1c2c66affSColin Finck /* 2c2c66affSColin Finck * Win 3.1 Style File Dialogs 3c2c66affSColin Finck * 4c2c66affSColin Finck * Copyright 1994 Martin Ayotte 5c2c66affSColin Finck * Copyright 1996 Albrecht Kleine 6c2c66affSColin Finck * 7c2c66affSColin Finck * This library is free software; you can redistribute it and/or 8c2c66affSColin Finck * modify it under the terms of the GNU Lesser General Public 9c2c66affSColin Finck * License as published by the Free Software Foundation; either 10c2c66affSColin Finck * version 2.1 of the License, or (at your option) any later version. 11c2c66affSColin Finck * 12c2c66affSColin Finck * This library is distributed in the hope that it will be useful, 13c2c66affSColin Finck * but WITHOUT ANY WARRANTY; without even the implied warranty of 14c2c66affSColin Finck * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15c2c66affSColin Finck * Lesser General Public License for more details. 16c2c66affSColin Finck * 17c2c66affSColin Finck * You should have received a copy of the GNU Lesser General Public 18c2c66affSColin Finck * License along with this library; if not, write to the Free Software 19c2c66affSColin Finck * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20c2c66affSColin Finck */ 2145ed51c1SAmine Khaldi #include <ctype.h> 2245ed51c1SAmine Khaldi #include <stdlib.h> 2345ed51c1SAmine Khaldi #include <stdarg.h> 2445ed51c1SAmine Khaldi #include <stdio.h> 2545ed51c1SAmine Khaldi #include <string.h> 2645ed51c1SAmine Khaldi #include "windef.h" 2745ed51c1SAmine Khaldi #include "winbase.h" 2845ed51c1SAmine Khaldi #include "winnls.h" 2945ed51c1SAmine Khaldi #include "wingdi.h" 3045ed51c1SAmine Khaldi #include "winuser.h" 3145ed51c1SAmine Khaldi #include "wine/unicode.h" 3245ed51c1SAmine Khaldi #include "wine/debug.h" 33*f68b0c51SAmine Khaldi #include "wine/heap.h" 3445ed51c1SAmine Khaldi #include "winreg.h" 3545ed51c1SAmine Khaldi #include "winternl.h" 3645ed51c1SAmine Khaldi #include "commdlg.h" 3745ed51c1SAmine Khaldi #include "shlwapi.h" 3845ed51c1SAmine Khaldi #include "cderr.h" 3945ed51c1SAmine Khaldi 4045ed51c1SAmine Khaldi WINE_DEFAULT_DEBUG_CHANNEL(commdlg); 41c2c66affSColin Finck 42c2c66affSColin Finck #include "cdlg.h" 43c2c66affSColin Finck 44c2c66affSColin Finck #define BUFFILE 512 45c2c66affSColin Finck #define BUFFILEALLOC 512 * sizeof(WCHAR) 46c2c66affSColin Finck 47c2c66affSColin Finck static const WCHAR FILE_star[] = {'*','.','*', 0}; 48c2c66affSColin Finck static const WCHAR FILE_bslash[] = {'\\', 0}; 49c2c66affSColin Finck static const WCHAR FILE_specc[] = {'%','c',':', 0}; 50c2c66affSColin Finck static const int fldrHeight = 16; 51c2c66affSColin Finck static const int fldrWidth = 20; 52c2c66affSColin Finck 53c2c66affSColin Finck static HICON hFolder = 0; 54c2c66affSColin Finck static HICON hFolder2 = 0; 55c2c66affSColin Finck static HICON hFloppy = 0; 56c2c66affSColin Finck static HICON hHDisk = 0; 57c2c66affSColin Finck static HICON hCDRom = 0; 58c2c66affSColin Finck static HICON hNet = 0; 59c2c66affSColin Finck 60c2c66affSColin Finck #define FD31_OFN_PROP "FILEDLG_OFN" 61c2c66affSColin Finck 62c2c66affSColin Finck typedef struct tagFD31_DATA 63c2c66affSColin Finck { 64c2c66affSColin Finck HWND hwnd; /* file dialog window handle */ 65c2c66affSColin Finck BOOL hook; /* TRUE if the dialog is hooked */ 66c2c66affSColin Finck UINT lbselchstring; /* registered message id */ 67c2c66affSColin Finck UINT fileokstring; /* registered message id */ 68c2c66affSColin Finck LPARAM lParam; /* save original lparam */ 69c2c66affSColin Finck LPCVOID template; /* template for 32 bits resource */ 70c2c66affSColin Finck BOOL open; /* TRUE if open dialog, FALSE if save dialog */ 71c2c66affSColin Finck LPOPENFILENAMEW ofnW; /* pointer either to the original structure or 72c2c66affSColin Finck a W copy for A/16 API */ 73c2c66affSColin Finck LPOPENFILENAMEA ofnA; /* original structure if 32bits ansi dialog */ 74c2c66affSColin Finck } FD31_DATA, *PFD31_DATA; 75c2c66affSColin Finck 76c2c66affSColin Finck /*********************************************************************** 77c2c66affSColin Finck * FD31_Init [internal] 78c2c66affSColin Finck */ 79c2c66affSColin Finck static BOOL FD31_Init(void) 80c2c66affSColin Finck { 81c2c66affSColin Finck static BOOL initialized = FALSE; 82c2c66affSColin Finck 83c2c66affSColin Finck if (!initialized) { 84c2c66affSColin Finck hFolder = LoadImageA( COMDLG32_hInstance, "FOLDER", IMAGE_ICON, 16, 16, LR_SHARED ); 85c2c66affSColin Finck hFolder2 = LoadImageA( COMDLG32_hInstance, "FOLDER2", IMAGE_ICON, 16, 16, LR_SHARED ); 86c2c66affSColin Finck hFloppy = LoadImageA( COMDLG32_hInstance, "FLOPPY", IMAGE_ICON, 16, 16, LR_SHARED ); 87c2c66affSColin Finck hHDisk = LoadImageA( COMDLG32_hInstance, "HDISK", IMAGE_ICON, 16, 16, LR_SHARED ); 88c2c66affSColin Finck hCDRom = LoadImageA( COMDLG32_hInstance, "CDROM", IMAGE_ICON, 16, 16, LR_SHARED ); 89c2c66affSColin Finck hNet = LoadImageA( COMDLG32_hInstance, "NETWORK", IMAGE_ICON, 16, 16, LR_SHARED ); 90c2c66affSColin Finck if (hFolder == 0 || hFolder2 == 0 || hFloppy == 0 || 91c2c66affSColin Finck hHDisk == 0 || hCDRom == 0 || hNet == 0) 92c2c66affSColin Finck { 93c2c66affSColin Finck ERR("Error loading icons!\n"); 94c2c66affSColin Finck return FALSE; 95c2c66affSColin Finck } 96c2c66affSColin Finck initialized = TRUE; 97c2c66affSColin Finck } 98c2c66affSColin Finck return TRUE; 99c2c66affSColin Finck } 100c2c66affSColin Finck 101c2c66affSColin Finck /*********************************************************************** 102c2c66affSColin Finck * FD31_StripEditControl [internal] 103c2c66affSColin Finck * Strip pathnames off the contents of the edit control. 104c2c66affSColin Finck */ 105c2c66affSColin Finck static void FD31_StripEditControl(HWND hwnd) 106c2c66affSColin Finck { 107c2c66affSColin Finck WCHAR temp[BUFFILE], *cp; 108c2c66affSColin Finck 109*f68b0c51SAmine Khaldi GetDlgItemTextW( hwnd, edt1, temp, ARRAY_SIZE(temp)); 110c2c66affSColin Finck cp = strrchrW(temp, '\\'); 111c2c66affSColin Finck if (cp != NULL) { 112c2c66affSColin Finck strcpyW(temp, cp+1); 113c2c66affSColin Finck } 114c2c66affSColin Finck cp = strrchrW(temp, ':'); 115c2c66affSColin Finck if (cp != NULL) { 116c2c66affSColin Finck strcpyW(temp, cp+1); 117c2c66affSColin Finck } 118c2c66affSColin Finck /* FIXME: shouldn't we do something with the result here? ;-) */ 119c2c66affSColin Finck } 120c2c66affSColin Finck 121c2c66affSColin Finck /*********************************************************************** 122c2c66affSColin Finck * FD31_CallWindowProc [internal] 123c2c66affSColin Finck * 124c2c66affSColin Finck * Call the appropriate hook 125c2c66affSColin Finck */ 126c2c66affSColin Finck static BOOL FD31_CallWindowProc(const FD31_DATA *lfs, UINT wMsg, WPARAM wParam, LPARAM lParam) 127c2c66affSColin Finck { 128c2c66affSColin Finck BOOL ret; 129c2c66affSColin Finck 130c2c66affSColin Finck if (lfs->ofnA) 131c2c66affSColin Finck { 132c2c66affSColin Finck TRACE("Call hookA %p (%p, %04x, %08lx, %08lx)\n", 133c2c66affSColin Finck lfs->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); 134c2c66affSColin Finck ret = lfs->ofnA->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); 135c2c66affSColin Finck TRACE("ret hookA %p (%p, %04x, %08lx, %08lx)\n", 136c2c66affSColin Finck lfs->ofnA->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); 137c2c66affSColin Finck return ret; 138c2c66affSColin Finck } 139c2c66affSColin Finck 140c2c66affSColin Finck TRACE("Call hookW %p (%p, %04x, %08lx, %08lx)\n", 141c2c66affSColin Finck lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); 142c2c66affSColin Finck ret = lfs->ofnW->lpfnHook(lfs->hwnd, wMsg, wParam, lParam); 143c2c66affSColin Finck TRACE("Ret hookW %p (%p, %04x, %08lx, %08lx)\n", 144c2c66affSColin Finck lfs->ofnW->lpfnHook, lfs->hwnd, wMsg, wParam, lParam); 145c2c66affSColin Finck return ret; 146c2c66affSColin Finck } 147c2c66affSColin Finck 148c2c66affSColin Finck /*********************************************************************** 149c2c66affSColin Finck * FD31_GetFileType [internal] 150c2c66affSColin Finck */ 151c2c66affSColin Finck static LPCWSTR FD31_GetFileType(LPCWSTR cfptr, LPCWSTR fptr, const WORD index) 152c2c66affSColin Finck { 153c2c66affSColin Finck int n, i; 154c2c66affSColin Finck i = 0; 155c2c66affSColin Finck if (cfptr) 156c2c66affSColin Finck for ( ;(n = lstrlenW(cfptr)) != 0; i++) 157c2c66affSColin Finck { 158c2c66affSColin Finck cfptr += n + 1; 159c2c66affSColin Finck if (i == index) 160c2c66affSColin Finck return cfptr; 161c2c66affSColin Finck cfptr += lstrlenW(cfptr) + 1; 162c2c66affSColin Finck } 163c2c66affSColin Finck if (fptr) 164c2c66affSColin Finck for ( ;(n = lstrlenW(fptr)) != 0; i++) 165c2c66affSColin Finck { 166c2c66affSColin Finck fptr += n + 1; 167c2c66affSColin Finck if (i == index) 168c2c66affSColin Finck return fptr; 169c2c66affSColin Finck fptr += lstrlenW(fptr) + 1; 170c2c66affSColin Finck } 171c2c66affSColin Finck return FILE_star; /* FIXME */ 172c2c66affSColin Finck } 173c2c66affSColin Finck 174c2c66affSColin Finck /*********************************************************************** 175c2c66affSColin Finck * FD31_ScanDir [internal] 176c2c66affSColin Finck */ 177c2c66affSColin Finck static BOOL FD31_ScanDir(const OPENFILENAMEW *ofn, HWND hWnd, LPCWSTR newPath) 178c2c66affSColin Finck { 179c2c66affSColin Finck WCHAR buffer[BUFFILE]; 180c2c66affSColin Finck HWND hdlg; 181c2c66affSColin Finck LRESULT lRet = TRUE; 182c2c66affSColin Finck HCURSOR hCursorWait, oldCursor; 183c2c66affSColin Finck 184c2c66affSColin Finck TRACE("Trying to change to %s\n", debugstr_w(newPath)); 185c2c66affSColin Finck if ( newPath[0] && !SetCurrentDirectoryW( newPath )) 186c2c66affSColin Finck return FALSE; 187c2c66affSColin Finck 188c2c66affSColin Finck /* get the list of spec files */ 189c2c66affSColin Finck lstrcpynW(buffer, FD31_GetFileType(ofn->lpstrCustomFilter, 190c2c66affSColin Finck ofn->lpstrFilter, ofn->nFilterIndex - 1), BUFFILE); 191c2c66affSColin Finck 192c2c66affSColin Finck hCursorWait = LoadCursorA(0, (LPSTR)IDC_WAIT); 193c2c66affSColin Finck oldCursor = SetCursor(hCursorWait); 194c2c66affSColin Finck 195c2c66affSColin Finck /* list of files */ 196c2c66affSColin Finck if ((hdlg = GetDlgItem(hWnd, lst1)) != 0) { 197c2c66affSColin Finck WCHAR* scptr; /* ptr on semi-colon */ 198c2c66affSColin Finck WCHAR* filter = buffer; 199c2c66affSColin Finck 200c2c66affSColin Finck TRACE("Using filter %s\n", debugstr_w(filter)); 201c2c66affSColin Finck SendMessageW(hdlg, LB_RESETCONTENT, 0, 0); 202c2c66affSColin Finck while (filter) { 203c2c66affSColin Finck scptr = strchrW(filter, ';'); 204c2c66affSColin Finck if (scptr) *scptr = 0; 205c2c66affSColin Finck while (*filter == ' ') filter++; 206c2c66affSColin Finck TRACE("Using file spec %s\n", debugstr_w(filter)); 207c2c66affSColin Finck SendMessageW(hdlg, LB_DIR, 0, (LPARAM)filter); 208c2c66affSColin Finck if (scptr) *scptr = ';'; 209c2c66affSColin Finck filter = (scptr) ? (scptr + 1) : 0; 210c2c66affSColin Finck } 211c2c66affSColin Finck } 212c2c66affSColin Finck 213c2c66affSColin Finck /* list of directories */ 214c2c66affSColin Finck strcpyW(buffer, FILE_star); 215c2c66affSColin Finck 216c2c66affSColin Finck if (GetDlgItem(hWnd, lst2) != 0) { 217c2c66affSColin Finck lRet = DlgDirListW(hWnd, buffer, lst2, stc1, DDL_EXCLUSIVE | DDL_DIRECTORY); 218c2c66affSColin Finck } 219c2c66affSColin Finck SetCursor(oldCursor); 220c2c66affSColin Finck return lRet; 221c2c66affSColin Finck } 222c2c66affSColin Finck 223c2c66affSColin Finck /*********************************************************************** 224c2c66affSColin Finck * FD31_WMDrawItem [internal] 225c2c66affSColin Finck */ 226c2c66affSColin Finck static LONG FD31_WMDrawItem(HWND hWnd, WPARAM wParam, LPARAM lParam, 227c2c66affSColin Finck int savedlg, const DRAWITEMSTRUCT *lpdis) 228c2c66affSColin Finck { 229c2c66affSColin Finck WCHAR *str; 230c2c66affSColin Finck HICON hIcon; 231c2c66affSColin Finck COLORREF oldText = 0, oldBk = 0; 232c2c66affSColin Finck 233c2c66affSColin Finck if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst1) 234c2c66affSColin Finck { 235*f68b0c51SAmine Khaldi if (!(str = heap_alloc(BUFFILEALLOC))) return FALSE; 236c2c66affSColin Finck SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 237c2c66affSColin Finck (LPARAM)str); 238c2c66affSColin Finck 239c2c66affSColin Finck if ((lpdis->itemState & ODS_SELECTED) && !savedlg) 240c2c66affSColin Finck { 241c2c66affSColin Finck oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); 242c2c66affSColin Finck oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 243c2c66affSColin Finck } 244c2c66affSColin Finck if (savedlg) 245c2c66affSColin Finck SetTextColor(lpdis->hDC,GetSysColor(COLOR_GRAYTEXT) ); 246c2c66affSColin Finck 247c2c66affSColin Finck ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + 1, 248c2c66affSColin Finck lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, 249c2c66affSColin Finck &(lpdis->rcItem), str, lstrlenW(str), NULL); 250c2c66affSColin Finck 251c2c66affSColin Finck if (lpdis->itemState & ODS_SELECTED) 252c2c66affSColin Finck DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) ); 253c2c66affSColin Finck 254c2c66affSColin Finck if ((lpdis->itemState & ODS_SELECTED) && !savedlg) 255c2c66affSColin Finck { 256c2c66affSColin Finck SetBkColor( lpdis->hDC, oldBk ); 257c2c66affSColin Finck SetTextColor( lpdis->hDC, oldText ); 258c2c66affSColin Finck } 259*f68b0c51SAmine Khaldi heap_free(str); 260c2c66affSColin Finck return TRUE; 261c2c66affSColin Finck } 262c2c66affSColin Finck 263c2c66affSColin Finck if (lpdis->CtlType == ODT_LISTBOX && lpdis->CtlID == lst2) 264c2c66affSColin Finck { 265*f68b0c51SAmine Khaldi if (!(str = heap_alloc(BUFFILEALLOC))) 266c2c66affSColin Finck return FALSE; 267c2c66affSColin Finck SendMessageW(lpdis->hwndItem, LB_GETTEXT, lpdis->itemID, 268c2c66affSColin Finck (LPARAM)str); 269c2c66affSColin Finck 270c2c66affSColin Finck if (lpdis->itemState & ODS_SELECTED) 271c2c66affSColin Finck { 272c2c66affSColin Finck oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); 273c2c66affSColin Finck oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 274c2c66affSColin Finck } 275c2c66affSColin Finck ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth, 276c2c66affSColin Finck lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, 277c2c66affSColin Finck &(lpdis->rcItem), str, lstrlenW(str), NULL); 278c2c66affSColin Finck 279c2c66affSColin Finck if (lpdis->itemState & ODS_SELECTED) 280c2c66affSColin Finck DrawFocusRect( lpdis->hDC, &(lpdis->rcItem) ); 281c2c66affSColin Finck 282c2c66affSColin Finck if (lpdis->itemState & ODS_SELECTED) 283c2c66affSColin Finck { 284c2c66affSColin Finck SetBkColor( lpdis->hDC, oldBk ); 285c2c66affSColin Finck SetTextColor( lpdis->hDC, oldText ); 286c2c66affSColin Finck } 287c2c66affSColin Finck DrawIconEx( lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hFolder, 16, 16, 0, 0, DI_NORMAL ); 288*f68b0c51SAmine Khaldi heap_free(str); 289c2c66affSColin Finck return TRUE; 290c2c66affSColin Finck } 291c2c66affSColin Finck if (lpdis->CtlType == ODT_COMBOBOX && lpdis->CtlID == cmb2) 292c2c66affSColin Finck { 293c2c66affSColin Finck char root[] = "a:"; 294*f68b0c51SAmine Khaldi if (!(str = heap_alloc(BUFFILEALLOC))) 295c2c66affSColin Finck return FALSE; 296c2c66affSColin Finck SendMessageW(lpdis->hwndItem, CB_GETLBTEXT, lpdis->itemID, 297c2c66affSColin Finck (LPARAM)str); 298c2c66affSColin Finck root[0] += str[2] - 'a'; 299c2c66affSColin Finck switch(GetDriveTypeA(root)) 300c2c66affSColin Finck { 301c2c66affSColin Finck case DRIVE_REMOVABLE: hIcon = hFloppy; break; 302c2c66affSColin Finck case DRIVE_CDROM: hIcon = hCDRom; break; 303c2c66affSColin Finck case DRIVE_REMOTE: hIcon = hNet; break; 304c2c66affSColin Finck case DRIVE_FIXED: 305c2c66affSColin Finck default: hIcon = hHDisk; break; 306c2c66affSColin Finck } 307c2c66affSColin Finck if (lpdis->itemState & ODS_SELECTED) 308c2c66affSColin Finck { 309c2c66affSColin Finck oldBk = SetBkColor( lpdis->hDC, GetSysColor( COLOR_HIGHLIGHT ) ); 310c2c66affSColin Finck oldText = SetTextColor( lpdis->hDC, GetSysColor(COLOR_HIGHLIGHTTEXT)); 311c2c66affSColin Finck } 312c2c66affSColin Finck ExtTextOutW(lpdis->hDC, lpdis->rcItem.left + fldrWidth, 313c2c66affSColin Finck lpdis->rcItem.top + 1, ETO_OPAQUE | ETO_CLIPPED, 314c2c66affSColin Finck &(lpdis->rcItem), str, lstrlenW(str), NULL); 315c2c66affSColin Finck 316c2c66affSColin Finck if (lpdis->itemState & ODS_SELECTED) 317c2c66affSColin Finck { 318c2c66affSColin Finck SetBkColor( lpdis->hDC, oldBk ); 319c2c66affSColin Finck SetTextColor( lpdis->hDC, oldText ); 320c2c66affSColin Finck } 321c2c66affSColin Finck DrawIconEx( lpdis->hDC, lpdis->rcItem.left, lpdis->rcItem.top, hIcon, 16, 16, 0, 0, DI_NORMAL ); 322*f68b0c51SAmine Khaldi heap_free(str); 323c2c66affSColin Finck return TRUE; 324c2c66affSColin Finck } 325c2c66affSColin Finck return FALSE; 326c2c66affSColin Finck } 327c2c66affSColin Finck 328c2c66affSColin Finck /*********************************************************************** 329c2c66affSColin Finck * FD31_UpdateResult [internal] 330c2c66affSColin Finck * update the displayed file name (with path) 331c2c66affSColin Finck */ 332c2c66affSColin Finck static void FD31_UpdateResult(const FD31_DATA *lfs, const WCHAR *tmpstr) 333c2c66affSColin Finck { 334c2c66affSColin Finck int lenstr2; 335c2c66affSColin Finck LPOPENFILENAMEW ofnW = lfs->ofnW; 336c2c66affSColin Finck LPOPENFILENAMEA ofnA = lfs->ofnA; 337c2c66affSColin Finck WCHAR tmpstr2[BUFFILE]; 338c2c66affSColin Finck WCHAR *p; 339c2c66affSColin Finck 340c2c66affSColin Finck TRACE("%s\n", debugstr_w(tmpstr)); 341c2c66affSColin Finck if(ofnW->Flags & OFN_NOVALIDATE) 342c2c66affSColin Finck tmpstr2[0] = '\0'; 343c2c66affSColin Finck else 344c2c66affSColin Finck GetCurrentDirectoryW(BUFFILE, tmpstr2); 345c2c66affSColin Finck lenstr2 = strlenW(tmpstr2); 346c2c66affSColin Finck if (lenstr2 > 3) 347c2c66affSColin Finck tmpstr2[lenstr2++]='\\'; 348c2c66affSColin Finck lstrcpynW(tmpstr2+lenstr2, tmpstr, BUFFILE-lenstr2); 349c2c66affSColin Finck if (!ofnW->lpstrFile) 350c2c66affSColin Finck return; 351c2c66affSColin Finck 352c2c66affSColin Finck lstrcpynW(ofnW->lpstrFile, tmpstr2, ofnW->nMaxFile); 353c2c66affSColin Finck 354c2c66affSColin Finck /* set filename offset */ 355c2c66affSColin Finck p = PathFindFileNameW(ofnW->lpstrFile); 356c2c66affSColin Finck ofnW->nFileOffset = (p - ofnW->lpstrFile); 357c2c66affSColin Finck 358c2c66affSColin Finck /* set extension offset */ 359c2c66affSColin Finck p = PathFindExtensionW(ofnW->lpstrFile); 360c2c66affSColin Finck ofnW->nFileExtension = (*p) ? (p - ofnW->lpstrFile) + 1 : 0; 361c2c66affSColin Finck 362c2c66affSColin Finck TRACE("file %s, file offset %d, ext offset %d\n", 363c2c66affSColin Finck debugstr_w(ofnW->lpstrFile), ofnW->nFileOffset, ofnW->nFileExtension); 364c2c66affSColin Finck 365c2c66affSColin Finck /* update the real client structures if any */ 366c2c66affSColin Finck if (ofnA) 367c2c66affSColin Finck { 368c2c66affSColin Finck LPSTR lpszTemp; 369c2c66affSColin Finck if (ofnW->nMaxFile && 370c2c66affSColin Finck !WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFile, -1, 371c2c66affSColin Finck ofnA->lpstrFile, ofnA->nMaxFile, NULL, NULL )) 372c2c66affSColin Finck ofnA->lpstrFile[ofnA->nMaxFile-1] = 0; 373c2c66affSColin Finck 374c2c66affSColin Finck /* offsets are not guaranteed to be the same in WCHAR to MULTIBYTE conversion */ 375c2c66affSColin Finck /* set filename offset */ 376c2c66affSColin Finck lpszTemp = PathFindFileNameA(ofnA->lpstrFile); 377c2c66affSColin Finck ofnA->nFileOffset = (lpszTemp - ofnA->lpstrFile); 378c2c66affSColin Finck 379c2c66affSColin Finck /* set extension offset */ 380c2c66affSColin Finck lpszTemp = PathFindExtensionA(ofnA->lpstrFile); 381c2c66affSColin Finck ofnA->nFileExtension = (*lpszTemp) ? (lpszTemp - ofnA->lpstrFile) + 1 : 0; 382c2c66affSColin Finck } 383c2c66affSColin Finck } 384c2c66affSColin Finck 385c2c66affSColin Finck /*********************************************************************** 386c2c66affSColin Finck * FD31_UpdateFileTitle [internal] 387c2c66affSColin Finck * update the displayed file name (without path) 388c2c66affSColin Finck */ 389c2c66affSColin Finck static void FD31_UpdateFileTitle(const FD31_DATA *lfs) 390c2c66affSColin Finck { 391c2c66affSColin Finck LONG lRet; 392c2c66affSColin Finck LPOPENFILENAMEW ofnW = lfs->ofnW; 393c2c66affSColin Finck LPOPENFILENAMEA ofnA = lfs->ofnA; 394c2c66affSColin Finck 395c2c66affSColin Finck if (ofnW->lpstrFileTitle != NULL) 396c2c66affSColin Finck { 397c2c66affSColin Finck lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0); 398c2c66affSColin Finck SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETTEXT, lRet, 399c2c66affSColin Finck (LPARAM)ofnW->lpstrFileTitle ); 400c2c66affSColin Finck if (ofnA) 401c2c66affSColin Finck { 402c2c66affSColin Finck if (!WideCharToMultiByte( CP_ACP, 0, ofnW->lpstrFileTitle, -1, 403c2c66affSColin Finck ofnA->lpstrFileTitle, ofnA->nMaxFileTitle, NULL, NULL )) 404c2c66affSColin Finck ofnA->lpstrFileTitle[ofnA->nMaxFileTitle-1] = 0; 405c2c66affSColin Finck } 406c2c66affSColin Finck } 407c2c66affSColin Finck } 408c2c66affSColin Finck 409c2c66affSColin Finck /*********************************************************************** 410c2c66affSColin Finck * FD31_DirListDblClick [internal] 411c2c66affSColin Finck */ 412c2c66affSColin Finck static LRESULT FD31_DirListDblClick( const FD31_DATA *lfs ) 413c2c66affSColin Finck { 414c2c66affSColin Finck LONG lRet; 415c2c66affSColin Finck HWND hWnd = lfs->hwnd; 416c2c66affSColin Finck LPWSTR pstr; 417c2c66affSColin Finck WCHAR tmpstr[BUFFILE]; 418c2c66affSColin Finck 419c2c66affSColin Finck /* get the raw string (with brackets) */ 420c2c66affSColin Finck lRet = SendDlgItemMessageW(hWnd, lst2, LB_GETCURSEL, 0, 0); 421c2c66affSColin Finck if (lRet == LB_ERR) return TRUE; 422*f68b0c51SAmine Khaldi pstr = heap_alloc(BUFFILEALLOC); 423c2c66affSColin Finck SendDlgItemMessageW(hWnd, lst2, LB_GETTEXT, lRet, 424c2c66affSColin Finck (LPARAM)pstr); 425c2c66affSColin Finck strcpyW( tmpstr, pstr ); 426*f68b0c51SAmine Khaldi heap_free(pstr); 427c2c66affSColin Finck /* get the selected directory in tmpstr */ 428c2c66affSColin Finck if (tmpstr[0] == '[') 429c2c66affSColin Finck { 430c2c66affSColin Finck tmpstr[lstrlenW(tmpstr) - 1] = 0; 431c2c66affSColin Finck strcpyW(tmpstr,tmpstr+1); 432c2c66affSColin Finck } 433c2c66affSColin Finck strcatW(tmpstr, FILE_bslash); 434c2c66affSColin Finck 435c2c66affSColin Finck FD31_ScanDir(lfs->ofnW, hWnd, tmpstr); 436c2c66affSColin Finck /* notify the app */ 437c2c66affSColin Finck if (lfs->hook) 438c2c66affSColin Finck { 439c2c66affSColin Finck if (FD31_CallWindowProc(lfs, lfs->lbselchstring, lst2, 440c2c66affSColin Finck MAKELONG(lRet,CD_LBSELCHANGE))) 441c2c66affSColin Finck return TRUE; 442c2c66affSColin Finck } 443c2c66affSColin Finck return TRUE; 444c2c66affSColin Finck } 445c2c66affSColin Finck 446c2c66affSColin Finck /*********************************************************************** 447c2c66affSColin Finck * FD31_FileListSelect [internal] 448c2c66affSColin Finck * called when a new item is picked in the file list 449c2c66affSColin Finck */ 450c2c66affSColin Finck static LRESULT FD31_FileListSelect( const FD31_DATA *lfs ) 451c2c66affSColin Finck { 452c2c66affSColin Finck LONG lRet; 453c2c66affSColin Finck HWND hWnd = lfs->hwnd; 454c2c66affSColin Finck LPWSTR pstr; 455c2c66affSColin Finck 456c2c66affSColin Finck lRet = SendDlgItemMessageW(lfs->hwnd, lst1, LB_GETCURSEL, 0, 0); 457c2c66affSColin Finck if (lRet == LB_ERR) 458c2c66affSColin Finck return TRUE; 459c2c66affSColin Finck 460c2c66affSColin Finck /* set the edit control to the chosen file */ 461*f68b0c51SAmine Khaldi if ((pstr = heap_alloc(BUFFILEALLOC))) 462c2c66affSColin Finck { 463c2c66affSColin Finck SendDlgItemMessageW(hWnd, lst1, LB_GETTEXT, lRet, 464c2c66affSColin Finck (LPARAM)pstr); 465c2c66affSColin Finck SetDlgItemTextW( hWnd, edt1, pstr ); 466*f68b0c51SAmine Khaldi heap_free(pstr); 467c2c66affSColin Finck } 468c2c66affSColin Finck if (lfs->hook) 469c2c66affSColin Finck { 470c2c66affSColin Finck FD31_CallWindowProc(lfs, lfs->lbselchstring, lst1, 471c2c66affSColin Finck MAKELONG(lRet,CD_LBSELCHANGE)); 472c2c66affSColin Finck } 473c2c66affSColin Finck /* FIXME: for OFN_ALLOWMULTISELECT we need CD_LBSELSUB, CD_SELADD, 474c2c66affSColin Finck CD_LBSELNOITEMS */ 475c2c66affSColin Finck return TRUE; 476c2c66affSColin Finck } 477c2c66affSColin Finck 478c2c66affSColin Finck /*********************************************************************** 479c2c66affSColin Finck * FD31_TestPath [internal] 480c2c66affSColin Finck * before accepting the file name, test if it includes wild cards 481c2c66affSColin Finck * tries to scan the directory and returns TRUE if no error. 482c2c66affSColin Finck */ 483c2c66affSColin Finck static LRESULT FD31_TestPath( const FD31_DATA *lfs, LPWSTR path ) 484c2c66affSColin Finck { 485c2c66affSColin Finck HWND hWnd = lfs->hwnd; 486c2c66affSColin Finck LPWSTR pBeginFileName, pstr2; 487c2c66affSColin Finck WCHAR tmpstr2[BUFFILE]; 488c2c66affSColin Finck 489c2c66affSColin Finck pBeginFileName = strrchrW(path, '\\'); 490c2c66affSColin Finck if (pBeginFileName == NULL) 491c2c66affSColin Finck pBeginFileName = strrchrW(path, ':'); 492c2c66affSColin Finck 493c2c66affSColin Finck if (strchrW(path,'*') != NULL || strchrW(path,'?') != NULL) 494c2c66affSColin Finck { 495c2c66affSColin Finck /* edit control contains wildcards */ 496c2c66affSColin Finck if (pBeginFileName != NULL) 497c2c66affSColin Finck { 498c2c66affSColin Finck lstrcpynW(tmpstr2, pBeginFileName + 1, BUFFILE); 499c2c66affSColin Finck *(pBeginFileName + 1) = 0; 500c2c66affSColin Finck } 501c2c66affSColin Finck else 502c2c66affSColin Finck { 503c2c66affSColin Finck strcpyW(tmpstr2, path); 504c2c66affSColin Finck if(!(lfs->ofnW->Flags & OFN_NOVALIDATE)) 505c2c66affSColin Finck *path = 0; 506c2c66affSColin Finck } 507c2c66affSColin Finck 508c2c66affSColin Finck TRACE("path=%s, tmpstr2=%s\n", debugstr_w(path), debugstr_w(tmpstr2)); 509c2c66affSColin Finck SetDlgItemTextW( hWnd, edt1, tmpstr2 ); 510c2c66affSColin Finck FD31_ScanDir(lfs->ofnW, hWnd, path); 511c2c66affSColin Finck return (lfs->ofnW->Flags & OFN_NOVALIDATE) != 0; 512c2c66affSColin Finck } 513c2c66affSColin Finck 514c2c66affSColin Finck /* no wildcards, we might have a directory or a filename */ 515c2c66affSColin Finck /* try appending a wildcard and reading the directory */ 516c2c66affSColin Finck 517c2c66affSColin Finck pstr2 = path + lstrlenW(path); 518c2c66affSColin Finck if (pBeginFileName == NULL || *(pBeginFileName + 1) != 0) 519c2c66affSColin Finck strcatW(path, FILE_bslash); 520c2c66affSColin Finck 521c2c66affSColin Finck /* if ScanDir succeeds, we have changed the directory */ 522c2c66affSColin Finck if (FD31_ScanDir(lfs->ofnW, hWnd, path)) 523c2c66affSColin Finck return FALSE; /* and path is not a valid file name */ 524c2c66affSColin Finck 525c2c66affSColin Finck /* if not, this must be a filename */ 526c2c66affSColin Finck 527c2c66affSColin Finck *pstr2 = 0; /* remove the wildcard added before */ 528c2c66affSColin Finck 529c2c66affSColin Finck if (pBeginFileName != NULL) 530c2c66affSColin Finck { 531c2c66affSColin Finck /* strip off the pathname */ 532c2c66affSColin Finck *pBeginFileName = 0; 533c2c66affSColin Finck SetDlgItemTextW( hWnd, edt1, pBeginFileName + 1 ); 534c2c66affSColin Finck 535*f68b0c51SAmine Khaldi lstrcpynW(tmpstr2, pBeginFileName + 1, ARRAY_SIZE(tmpstr2)); 536c2c66affSColin Finck /* Should we MessageBox() if this fails? */ 537c2c66affSColin Finck if (!FD31_ScanDir(lfs->ofnW, hWnd, path)) 538c2c66affSColin Finck { 539c2c66affSColin Finck return FALSE; 540c2c66affSColin Finck } 541c2c66affSColin Finck strcpyW(path, tmpstr2); 542c2c66affSColin Finck } 543c2c66affSColin Finck else 544c2c66affSColin Finck SetDlgItemTextW( hWnd, edt1, path ); 545c2c66affSColin Finck return TRUE; 546c2c66affSColin Finck } 547c2c66affSColin Finck 548c2c66affSColin Finck /*********************************************************************** 549c2c66affSColin Finck * FD31_Validate [internal] 550c2c66affSColin Finck * called on: click Ok button, Enter in edit, DoubleClick in file list 551c2c66affSColin Finck */ 552c2c66affSColin Finck static LRESULT FD31_Validate( const FD31_DATA *lfs, LPCWSTR path, UINT control, INT itemIndex, 553c2c66affSColin Finck BOOL internalUse ) 554c2c66affSColin Finck { 555c2c66affSColin Finck LONG lRet; 556c2c66affSColin Finck HWND hWnd = lfs->hwnd; 557c2c66affSColin Finck OPENFILENAMEW ofnsav; 558c2c66affSColin Finck LPOPENFILENAMEW ofnW = lfs->ofnW; 559c2c66affSColin Finck WCHAR filename[BUFFILE]; 560c2c66affSColin Finck int copied_size = min( ofnW->lStructSize, sizeof(ofnsav) ); 561c2c66affSColin Finck 562c2c66affSColin Finck memcpy( &ofnsav, ofnW, copied_size ); /* for later restoring */ 563c2c66affSColin Finck 564c2c66affSColin Finck /* get current file name */ 565c2c66affSColin Finck if (path) 566*f68b0c51SAmine Khaldi lstrcpynW(filename, path, ARRAY_SIZE(filename)); 567c2c66affSColin Finck else 568*f68b0c51SAmine Khaldi GetDlgItemTextW( hWnd, edt1, filename, ARRAY_SIZE(filename)); 569c2c66affSColin Finck 570c2c66affSColin Finck TRACE("got filename = %s\n", debugstr_w(filename)); 571c2c66affSColin Finck /* if we did not click in file list to get there */ 572c2c66affSColin Finck if (control != lst1) 573c2c66affSColin Finck { 574c2c66affSColin Finck if (!FD31_TestPath( lfs, filename) ) 575c2c66affSColin Finck return FALSE; 576c2c66affSColin Finck } 577c2c66affSColin Finck FD31_UpdateResult(lfs, filename); 578c2c66affSColin Finck 579c2c66affSColin Finck if (internalUse) 580c2c66affSColin Finck { /* called internally after a change in a combo */ 581c2c66affSColin Finck if (lfs->hook) 582c2c66affSColin Finck { 583c2c66affSColin Finck FD31_CallWindowProc(lfs, lfs->lbselchstring, control, 584c2c66affSColin Finck MAKELONG(itemIndex,CD_LBSELCHANGE)); 585c2c66affSColin Finck } 586c2c66affSColin Finck return TRUE; 587c2c66affSColin Finck } 588c2c66affSColin Finck 589c2c66affSColin Finck FD31_UpdateFileTitle(lfs); 590c2c66affSColin Finck if (lfs->hook) 591c2c66affSColin Finck { 592c2c66affSColin Finck lRet = FD31_CallWindowProc(lfs, lfs->fileokstring, 593c2c66affSColin Finck 0, lfs->lParam ); 594c2c66affSColin Finck if (lRet) 595c2c66affSColin Finck { 596c2c66affSColin Finck memcpy( ofnW, &ofnsav, copied_size ); /* restore old state */ 597c2c66affSColin Finck return FALSE; 598c2c66affSColin Finck } 599c2c66affSColin Finck } 600c2c66affSColin Finck if ((ofnW->Flags & OFN_ALLOWMULTISELECT) && (ofnW->Flags & OFN_EXPLORER)) 601c2c66affSColin Finck { 602c2c66affSColin Finck if (ofnW->lpstrFile) 603c2c66affSColin Finck { 604c2c66affSColin Finck LPWSTR str = ofnW->lpstrFile; 605c2c66affSColin Finck LPWSTR ptr = strrchrW(str, '\\'); 606c2c66affSColin Finck str[lstrlenW(str) + 1] = '\0'; 607c2c66affSColin Finck *ptr = 0; 608c2c66affSColin Finck } 609c2c66affSColin Finck } 610c2c66affSColin Finck return TRUE; 611c2c66affSColin Finck } 612c2c66affSColin Finck 613c2c66affSColin Finck /*********************************************************************** 614c2c66affSColin Finck * FD31_DiskChange [internal] 615c2c66affSColin Finck * called when a new item is picked in the disk selection combo 616c2c66affSColin Finck */ 617c2c66affSColin Finck static LRESULT FD31_DiskChange( const FD31_DATA *lfs ) 618c2c66affSColin Finck { 619c2c66affSColin Finck LONG lRet; 620c2c66affSColin Finck HWND hWnd = lfs->hwnd; 621c2c66affSColin Finck LPWSTR pstr; 622c2c66affSColin Finck WCHAR diskname[BUFFILE]; 623c2c66affSColin Finck 624c2c66affSColin Finck FD31_StripEditControl(hWnd); 625c2c66affSColin Finck lRet = SendDlgItemMessageW(hWnd, cmb2, CB_GETCURSEL, 0, 0L); 626c2c66affSColin Finck if (lRet == LB_ERR) 627c2c66affSColin Finck return 0; 628*f68b0c51SAmine Khaldi pstr = heap_alloc(BUFFILEALLOC); 629c2c66affSColin Finck SendDlgItemMessageW(hWnd, cmb2, CB_GETLBTEXT, lRet, 630c2c66affSColin Finck (LPARAM)pstr); 631c2c66affSColin Finck wsprintfW(diskname, FILE_specc, pstr[2]); 632*f68b0c51SAmine Khaldi heap_free(pstr); 633c2c66affSColin Finck 634c2c66affSColin Finck return FD31_Validate( lfs, diskname, cmb2, lRet, TRUE ); 635c2c66affSColin Finck } 636c2c66affSColin Finck 637c2c66affSColin Finck /*********************************************************************** 638c2c66affSColin Finck * FD31_FileTypeChange [internal] 639c2c66affSColin Finck * called when a new item is picked in the file type combo 640c2c66affSColin Finck */ 641c2c66affSColin Finck static LRESULT FD31_FileTypeChange( const FD31_DATA *lfs ) 642c2c66affSColin Finck { 643c2c66affSColin Finck LONG lRet; 644c2c66affSColin Finck LPWSTR pstr; 645c2c66affSColin Finck 646c2c66affSColin Finck lRet = SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETCURSEL, 0, 0); 647c2c66affSColin Finck if (lRet == LB_ERR) 648c2c66affSColin Finck return TRUE; 649c2c66affSColin Finck lfs->ofnW->nFilterIndex = lRet + 1; 650c2c66affSColin Finck if (lfs->ofnA) 651c2c66affSColin Finck lfs->ofnA->nFilterIndex = lRet + 1; 652c2c66affSColin Finck pstr = (LPWSTR)SendDlgItemMessageW(lfs->hwnd, cmb1, CB_GETITEMDATA, lRet, 0); 653c2c66affSColin Finck TRACE("Selected filter : %s\n", debugstr_w(pstr)); 654c2c66affSColin Finck 655c2c66affSColin Finck return FD31_Validate( lfs, pstr, cmb1, lRet, TRUE ); 656c2c66affSColin Finck } 657c2c66affSColin Finck 658c2c66affSColin Finck /*********************************************************************** 659c2c66affSColin Finck * FD31_WMCommand [internal] 660c2c66affSColin Finck */ 661c2c66affSColin Finck static LRESULT FD31_WMCommand( HWND hWnd, LPARAM lParam, UINT notification, 662c2c66affSColin Finck UINT control, const FD31_DATA *lfs ) 663c2c66affSColin Finck { 664c2c66affSColin Finck switch (control) 665c2c66affSColin Finck { 666c2c66affSColin Finck case lst1: /* file list */ 667c2c66affSColin Finck FD31_StripEditControl(hWnd); 668c2c66affSColin Finck if (notification == LBN_DBLCLK) 669c2c66affSColin Finck { 670c2c66affSColin Finck return SendMessageW(hWnd, WM_COMMAND, IDOK, 0); 671c2c66affSColin Finck } 672c2c66affSColin Finck else if (notification == LBN_SELCHANGE) 673c2c66affSColin Finck return FD31_FileListSelect( lfs ); 674c2c66affSColin Finck break; 675c2c66affSColin Finck 676c2c66affSColin Finck case lst2: /* directory list */ 677c2c66affSColin Finck FD31_StripEditControl(hWnd); 678c2c66affSColin Finck if (notification == LBN_DBLCLK) 679c2c66affSColin Finck return FD31_DirListDblClick( lfs ); 680c2c66affSColin Finck break; 681c2c66affSColin Finck 682c2c66affSColin Finck case cmb1: /* file type drop list */ 683c2c66affSColin Finck if (notification == CBN_SELCHANGE) 684c2c66affSColin Finck return FD31_FileTypeChange( lfs ); 685c2c66affSColin Finck break; 686c2c66affSColin Finck 687c2c66affSColin Finck case chx1: 688c2c66affSColin Finck break; 689c2c66affSColin Finck 690c2c66affSColin Finck case pshHelp: 691c2c66affSColin Finck break; 692c2c66affSColin Finck 693c2c66affSColin Finck case cmb2: /* disk dropdown combo */ 694c2c66affSColin Finck if (notification == CBN_SELCHANGE) 695c2c66affSColin Finck return FD31_DiskChange( lfs ); 696c2c66affSColin Finck break; 697c2c66affSColin Finck 698c2c66affSColin Finck case IDOK: 699c2c66affSColin Finck TRACE("OK pressed\n"); 700c2c66affSColin Finck if (FD31_Validate( lfs, NULL, control, 0, FALSE )) 701c2c66affSColin Finck EndDialog(hWnd, TRUE); 702c2c66affSColin Finck return TRUE; 703c2c66affSColin Finck 704c2c66affSColin Finck case IDCANCEL: 705c2c66affSColin Finck EndDialog(hWnd, FALSE); 706c2c66affSColin Finck return TRUE; 707c2c66affSColin Finck 708c2c66affSColin Finck case IDABORT: /* can be sent by the hook procedure */ 709c2c66affSColin Finck EndDialog(hWnd, TRUE); 710c2c66affSColin Finck return TRUE; 711c2c66affSColin Finck } 712c2c66affSColin Finck return FALSE; 713c2c66affSColin Finck } 714c2c66affSColin Finck 715c2c66affSColin Finck /************************************************************************ 716c2c66affSColin Finck * FD31_MapStringPairsToW [internal] 717c2c66affSColin Finck * map string pairs to Unicode 718c2c66affSColin Finck */ 719c2c66affSColin Finck static LPWSTR FD31_MapStringPairsToW(LPCSTR strA, UINT size) 720c2c66affSColin Finck { 721c2c66affSColin Finck LPCSTR s; 722c2c66affSColin Finck LPWSTR x; 723c2c66affSColin Finck unsigned int n, len; 724c2c66affSColin Finck 725c2c66affSColin Finck s = strA; 726c2c66affSColin Finck while (*s) 727c2c66affSColin Finck s = s+strlen(s)+1; 728c2c66affSColin Finck s++; 729c2c66affSColin Finck n = s + 1 - strA; /* Don't forget the other \0 */ 730c2c66affSColin Finck if (n < size) n = size; 731c2c66affSColin Finck 732c2c66affSColin Finck len = MultiByteToWideChar( CP_ACP, 0, strA, n, NULL, 0 ); 733*f68b0c51SAmine Khaldi x = heap_alloc(len * sizeof(WCHAR)); 734c2c66affSColin Finck MultiByteToWideChar( CP_ACP, 0, strA, n, x, len ); 735c2c66affSColin Finck return x; 736c2c66affSColin Finck } 737c2c66affSColin Finck 738c2c66affSColin Finck 739c2c66affSColin Finck /************************************************************************ 740c2c66affSColin Finck * FD31_DupToW [internal] 741c2c66affSColin Finck * duplicates an Ansi string to unicode, with a buffer size 742c2c66affSColin Finck */ 743c2c66affSColin Finck static LPWSTR FD31_DupToW(LPCSTR str, DWORD size) 744c2c66affSColin Finck { 745c2c66affSColin Finck LPWSTR strW = NULL; 746c2c66affSColin Finck if (str && (size > 0)) 747c2c66affSColin Finck { 748*f68b0c51SAmine Khaldi strW = heap_alloc(size * sizeof(WCHAR)); 749c2c66affSColin Finck if (strW) MultiByteToWideChar( CP_ACP, 0, str, -1, strW, size ); 750c2c66affSColin Finck } 751c2c66affSColin Finck return strW; 752c2c66affSColin Finck } 753c2c66affSColin Finck 754c2c66affSColin Finck /************************************************************************ 755c2c66affSColin Finck * FD31_MapOfnStructA [internal] 756c2c66affSColin Finck * map a 32 bits Ansi structure to a Unicode one 757c2c66affSColin Finck */ 758c2c66affSColin Finck static void FD31_MapOfnStructA(const OPENFILENAMEA *ofnA, LPOPENFILENAMEW ofnW, BOOL open) 759c2c66affSColin Finck { 760c2c66affSColin Finck UNICODE_STRING usBuffer; 761c2c66affSColin Finck 762c2c66affSColin Finck ofnW->hwndOwner = ofnA->hwndOwner; 763c2c66affSColin Finck ofnW->hInstance = ofnA->hInstance; 764c2c66affSColin Finck if (ofnA->lpstrFilter) 765c2c66affSColin Finck ofnW->lpstrFilter = FD31_MapStringPairsToW(ofnA->lpstrFilter, 0); 766c2c66affSColin Finck 767c2c66affSColin Finck if ((ofnA->lpstrCustomFilter) && (*(ofnA->lpstrCustomFilter))) 768c2c66affSColin Finck ofnW->lpstrCustomFilter = FD31_MapStringPairsToW(ofnA->lpstrCustomFilter, ofnA->nMaxCustFilter); 769c2c66affSColin Finck ofnW->nMaxCustFilter = ofnA->nMaxCustFilter; 770c2c66affSColin Finck ofnW->nFilterIndex = ofnA->nFilterIndex; 771c2c66affSColin Finck ofnW->nMaxFile = ofnA->nMaxFile; 772c2c66affSColin Finck ofnW->lpstrFile = FD31_DupToW(ofnA->lpstrFile, ofnW->nMaxFile); 773c2c66affSColin Finck ofnW->nMaxFileTitle = ofnA->nMaxFileTitle; 774c2c66affSColin Finck ofnW->lpstrFileTitle = FD31_DupToW(ofnA->lpstrFileTitle, ofnW->nMaxFileTitle); 775c2c66affSColin Finck if (ofnA->lpstrInitialDir) 776c2c66affSColin Finck { 777c2c66affSColin Finck RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpstrInitialDir); 778c2c66affSColin Finck ofnW->lpstrInitialDir = usBuffer.Buffer; 779c2c66affSColin Finck } 780c2c66affSColin Finck if (ofnA->lpstrTitle) { 781c2c66affSColin Finck RtlCreateUnicodeStringFromAsciiz (&usBuffer, ofnA->lpstrTitle); 782c2c66affSColin Finck ofnW->lpstrTitle = usBuffer.Buffer; 783c2c66affSColin Finck } else { 784c2c66affSColin Finck WCHAR buf[16]; 785c2c66affSColin Finck LPWSTR title_tmp; 786c2c66affSColin Finck int len; 787*f68b0c51SAmine Khaldi LoadStringW(COMDLG32_hInstance, open ? IDS_OPEN_FILE : IDS_SAVE_AS, buf, ARRAY_SIZE(buf)); 788c2c66affSColin Finck len = lstrlenW(buf)+1; 789*f68b0c51SAmine Khaldi title_tmp = heap_alloc(len * sizeof(WCHAR)); 790c2c66affSColin Finck memcpy(title_tmp, buf, len * sizeof(WCHAR)); 791c2c66affSColin Finck ofnW->lpstrTitle = title_tmp; 792c2c66affSColin Finck } 793c2c66affSColin Finck ofnW->Flags = ofnA->Flags; 794c2c66affSColin Finck ofnW->nFileOffset = ofnA->nFileOffset; 795c2c66affSColin Finck ofnW->nFileExtension = ofnA->nFileExtension; 796c2c66affSColin Finck ofnW->lpstrDefExt = FD31_DupToW(ofnA->lpstrDefExt, 3); 797c2c66affSColin Finck if ((ofnA->Flags & OFN_ENABLETEMPLATE) && (ofnA->lpTemplateName)) 798c2c66affSColin Finck { 799c2c66affSColin Finck if (!IS_INTRESOURCE(ofnA->lpTemplateName)) 800c2c66affSColin Finck { 801c2c66affSColin Finck RtlCreateUnicodeStringFromAsciiz (&usBuffer,ofnA->lpTemplateName); 802c2c66affSColin Finck ofnW->lpTemplateName = usBuffer.Buffer; 803c2c66affSColin Finck } 804c2c66affSColin Finck else /* numbered resource */ 805c2c66affSColin Finck ofnW->lpTemplateName = (LPCWSTR) ofnA->lpTemplateName; 806c2c66affSColin Finck } 807c2c66affSColin Finck if (ofnW->lStructSize > OPENFILENAME_SIZE_VERSION_400W) 808c2c66affSColin Finck { 809c2c66affSColin Finck ofnW->pvReserved = ofnA->pvReserved; 810c2c66affSColin Finck ofnW->dwReserved = ofnA->dwReserved; 811c2c66affSColin Finck ofnW->FlagsEx = ofnA->FlagsEx; 812c2c66affSColin Finck } 813c2c66affSColin Finck } 814c2c66affSColin Finck 815c2c66affSColin Finck 816c2c66affSColin Finck /************************************************************************ 817c2c66affSColin Finck * FD31_FreeOfnW [internal] 818c2c66affSColin Finck * Undo all allocations done by FD31_MapOfnStructA 819c2c66affSColin Finck */ 820c2c66affSColin Finck static void FD31_FreeOfnW(OPENFILENAMEW *ofnW) 821c2c66affSColin Finck { 822*f68b0c51SAmine Khaldi heap_free((void *)ofnW->lpstrFilter); 823*f68b0c51SAmine Khaldi heap_free(ofnW->lpstrCustomFilter); 824*f68b0c51SAmine Khaldi heap_free(ofnW->lpstrFile); 825*f68b0c51SAmine Khaldi heap_free(ofnW->lpstrFileTitle); 826*f68b0c51SAmine Khaldi heap_free((void *)ofnW->lpstrInitialDir); 827*f68b0c51SAmine Khaldi heap_free((void *)ofnW->lpstrTitle); 828c2c66affSColin Finck if (!IS_INTRESOURCE(ofnW->lpTemplateName)) 829*f68b0c51SAmine Khaldi heap_free((void *)ofnW->lpTemplateName); 830c2c66affSColin Finck } 831c2c66affSColin Finck 832c2c66affSColin Finck /************************************************************************ 833c2c66affSColin Finck * FD31_DestroyPrivate [internal] 834c2c66affSColin Finck * destroys the private object 835c2c66affSColin Finck */ 836c2c66affSColin Finck static void FD31_DestroyPrivate(PFD31_DATA lfs) 837c2c66affSColin Finck { 838c2c66affSColin Finck HWND hwnd; 839c2c66affSColin Finck if (!lfs) return; 840c2c66affSColin Finck hwnd = lfs->hwnd; 841c2c66affSColin Finck TRACE("destroying private allocation %p\n", lfs); 842c2c66affSColin Finck 843c2c66affSColin Finck /* if ofnW has been allocated, have to free everything in it */ 844c2c66affSColin Finck if (lfs->ofnA) 845c2c66affSColin Finck { 846c2c66affSColin Finck FD31_FreeOfnW(lfs->ofnW); 847*f68b0c51SAmine Khaldi heap_free(lfs->ofnW); 848c2c66affSColin Finck } 849*f68b0c51SAmine Khaldi heap_free(lfs); 850c2c66affSColin Finck RemovePropA(hwnd, FD31_OFN_PROP); 851c2c66affSColin Finck } 852c2c66affSColin Finck 853c2c66affSColin Finck /*********************************************************************** 854c2c66affSColin Finck * FD31_GetTemplate [internal] 855c2c66affSColin Finck * 856c2c66affSColin Finck * Get a template (or FALSE if failure) when 16 bits dialogs are used 857c2c66affSColin Finck * by a 32 bits application 858c2c66affSColin Finck * 859c2c66affSColin Finck */ 860c2c66affSColin Finck static BOOL FD31_GetTemplate(PFD31_DATA lfs) 861c2c66affSColin Finck { 862c2c66affSColin Finck LPOPENFILENAMEW ofnW = lfs->ofnW; 863c2c66affSColin Finck LPOPENFILENAMEA ofnA = lfs->ofnA; 864c2c66affSColin Finck HANDLE hDlgTmpl; 865c2c66affSColin Finck 866c2c66affSColin Finck if (ofnW->Flags & OFN_ENABLETEMPLATEHANDLE) 867c2c66affSColin Finck { 868c2c66affSColin Finck if (!(lfs->template = LockResource( ofnW->hInstance ))) 869c2c66affSColin Finck { 870c2c66affSColin Finck COMDLG32_SetCommDlgExtendedError( CDERR_LOADRESFAILURE ); 871c2c66affSColin Finck return FALSE; 872c2c66affSColin Finck } 873c2c66affSColin Finck } 874c2c66affSColin Finck else if (ofnW->Flags & OFN_ENABLETEMPLATE) 875c2c66affSColin Finck { 876c2c66affSColin Finck HRSRC hResInfo; 877c2c66affSColin Finck if (ofnA) 878c2c66affSColin Finck hResInfo = FindResourceA( ofnA->hInstance, ofnA->lpTemplateName, (LPSTR)RT_DIALOG ); 879c2c66affSColin Finck else 880c2c66affSColin Finck hResInfo = FindResourceW( ofnW->hInstance, ofnW->lpTemplateName, (LPWSTR)RT_DIALOG ); 881c2c66affSColin Finck if (!hResInfo) 882c2c66affSColin Finck { 883c2c66affSColin Finck COMDLG32_SetCommDlgExtendedError( CDERR_FINDRESFAILURE ); 884c2c66affSColin Finck return FALSE; 885c2c66affSColin Finck } 886c2c66affSColin Finck if (!(hDlgTmpl = LoadResource( ofnW->hInstance, hResInfo )) || 887c2c66affSColin Finck !(lfs->template = LockResource( hDlgTmpl ))) 888c2c66affSColin Finck { 889c2c66affSColin Finck COMDLG32_SetCommDlgExtendedError( CDERR_LOADRESFAILURE ); 890c2c66affSColin Finck return FALSE; 891c2c66affSColin Finck } 892c2c66affSColin Finck } 893c2c66affSColin Finck else /* get it from internal Wine resource */ 894c2c66affSColin Finck { 895c2c66affSColin Finck HRSRC hResInfo; 896c2c66affSColin Finck if (!(hResInfo = FindResourceA( COMDLG32_hInstance, lfs->open ? "OPEN_FILE" : "SAVE_FILE", (LPSTR)RT_DIALOG ))) 897c2c66affSColin Finck { 898c2c66affSColin Finck COMDLG32_SetCommDlgExtendedError( CDERR_FINDRESFAILURE ); 899c2c66affSColin Finck return FALSE; 900c2c66affSColin Finck } 901c2c66affSColin Finck if (!(hDlgTmpl = LoadResource( COMDLG32_hInstance, hResInfo )) || 902c2c66affSColin Finck !(lfs->template = LockResource( hDlgTmpl ))) 903c2c66affSColin Finck { 904c2c66affSColin Finck COMDLG32_SetCommDlgExtendedError( CDERR_LOADRESFAILURE ); 905c2c66affSColin Finck return FALSE; 906c2c66affSColin Finck } 907c2c66affSColin Finck } 908c2c66affSColin Finck return TRUE; 909c2c66affSColin Finck } 910c2c66affSColin Finck 911c2c66affSColin Finck /************************************************************************ 912c2c66affSColin Finck * FD31_AllocPrivate [internal] 913c2c66affSColin Finck * allocate a private object to hold 32 bits Unicode 914c2c66affSColin Finck * structure that will be used throughout the calls, while 915c2c66affSColin Finck * keeping available the original structures and a few variables 916c2c66affSColin Finck * On entry : type = dialog procedure type (16,32A,32W) 917c2c66affSColin Finck * dlgType = dialog type (open or save) 918c2c66affSColin Finck */ 919c2c66affSColin Finck static PFD31_DATA FD31_AllocPrivate(LPARAM lParam, UINT dlgType, BOOL IsUnicode) 920c2c66affSColin Finck { 921*f68b0c51SAmine Khaldi FD31_DATA *lfs = heap_alloc_zero(sizeof(*lfs)); 922c2c66affSColin Finck 923c2c66affSColin Finck TRACE("alloc private buf %p\n", lfs); 924c2c66affSColin Finck if (!lfs) return NULL; 925c2c66affSColin Finck lfs->hook = FALSE; 926c2c66affSColin Finck lfs->lParam = lParam; 927c2c66affSColin Finck lfs->open = (dlgType == OPEN_DIALOG); 928c2c66affSColin Finck 929c2c66affSColin Finck if (IsUnicode) 930c2c66affSColin Finck { 931c2c66affSColin Finck lfs->ofnA = NULL; 932c2c66affSColin Finck lfs->ofnW = (LPOPENFILENAMEW) lParam; 933c2c66affSColin Finck if (lfs->ofnW->Flags & OFN_ENABLEHOOK) 934c2c66affSColin Finck if (lfs->ofnW->lpfnHook) 935c2c66affSColin Finck lfs->hook = TRUE; 936c2c66affSColin Finck } 937c2c66affSColin Finck else 938c2c66affSColin Finck { 939c2c66affSColin Finck lfs->ofnA = (LPOPENFILENAMEA) lParam; 940c2c66affSColin Finck if (lfs->ofnA->Flags & OFN_ENABLEHOOK) 941c2c66affSColin Finck if (lfs->ofnA->lpfnHook) 942c2c66affSColin Finck lfs->hook = TRUE; 943*f68b0c51SAmine Khaldi lfs->ofnW = heap_alloc_zero(lfs->ofnA->lStructSize); 944c2c66affSColin Finck lfs->ofnW->lStructSize = lfs->ofnA->lStructSize; 945c2c66affSColin Finck FD31_MapOfnStructA(lfs->ofnA, lfs->ofnW, lfs->open); 946c2c66affSColin Finck } 947c2c66affSColin Finck 948c2c66affSColin Finck if (! FD31_GetTemplate(lfs)) 949c2c66affSColin Finck { 950c2c66affSColin Finck FD31_DestroyPrivate(lfs); 951c2c66affSColin Finck return NULL; 952c2c66affSColin Finck } 953c2c66affSColin Finck lfs->lbselchstring = RegisterWindowMessageA(LBSELCHSTRINGA); 954c2c66affSColin Finck lfs->fileokstring = RegisterWindowMessageA(FILEOKSTRINGA); 955c2c66affSColin Finck 956c2c66affSColin Finck return lfs; 957c2c66affSColin Finck } 958c2c66affSColin Finck 959c2c66affSColin Finck /*********************************************************************** 960c2c66affSColin Finck * FD31_WMInitDialog [internal] 961c2c66affSColin Finck */ 962c2c66affSColin Finck static LONG FD31_WMInitDialog(HWND hWnd, WPARAM wParam, LPARAM lParam) 963c2c66affSColin Finck { 964c2c66affSColin Finck int i, n; 965c2c66affSColin Finck WCHAR tmpstr[BUFFILE]; 966c2c66affSColin Finck LPWSTR pstr, old_pstr; 967c2c66affSColin Finck LPOPENFILENAMEW ofn; 968c2c66affSColin Finck PFD31_DATA lfs = (PFD31_DATA) lParam; 969c2c66affSColin Finck 970c2c66affSColin Finck if (!lfs) return FALSE; 971c2c66affSColin Finck SetPropA(hWnd, FD31_OFN_PROP, lfs); 972c2c66affSColin Finck lfs->hwnd = hWnd; 973c2c66affSColin Finck ofn = lfs->ofnW; 974c2c66affSColin Finck 975c2c66affSColin Finck TRACE("flags=%x initialdir=%s\n", ofn->Flags, debugstr_w(ofn->lpstrInitialDir)); 976c2c66affSColin Finck 977c2c66affSColin Finck SetWindowTextW( hWnd, ofn->lpstrTitle ); 978c2c66affSColin Finck /* read custom filter information */ 979c2c66affSColin Finck if (ofn->lpstrCustomFilter) 980c2c66affSColin Finck { 981c2c66affSColin Finck pstr = ofn->lpstrCustomFilter; 982c2c66affSColin Finck n = 0; 983c2c66affSColin Finck TRACE("lpstrCustomFilter = %p\n", pstr); 984c2c66affSColin Finck while(*pstr) 985c2c66affSColin Finck { 986c2c66affSColin Finck old_pstr = pstr; 987c2c66affSColin Finck i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0, 988c2c66affSColin Finck (LPARAM)(ofn->lpstrCustomFilter) + n ); 989c2c66affSColin Finck n += lstrlenW(pstr) + 1; 990c2c66affSColin Finck pstr += lstrlenW(pstr) + 1; 991c2c66affSColin Finck TRACE("add str=%s associated to %s\n", 992c2c66affSColin Finck debugstr_w(old_pstr), debugstr_w(pstr)); 993c2c66affSColin Finck SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr); 994c2c66affSColin Finck n += lstrlenW(pstr) + 1; 995c2c66affSColin Finck pstr += lstrlenW(pstr) + 1; 996c2c66affSColin Finck } 997c2c66affSColin Finck } 998c2c66affSColin Finck /* read filter information */ 999c2c66affSColin Finck if (ofn->lpstrFilter) { 1000c2c66affSColin Finck pstr = (LPWSTR) ofn->lpstrFilter; 1001c2c66affSColin Finck n = 0; 1002c2c66affSColin Finck while(*pstr) { 1003c2c66affSColin Finck old_pstr = pstr; 1004c2c66affSColin Finck i = SendDlgItemMessageW(hWnd, cmb1, CB_ADDSTRING, 0, 1005c2c66affSColin Finck (LPARAM)(ofn->lpstrFilter + n) ); 1006c2c66affSColin Finck n += lstrlenW(pstr) + 1; 1007c2c66affSColin Finck pstr += lstrlenW(pstr) + 1; 1008c2c66affSColin Finck TRACE("add str=%s associated to %s\n", 1009c2c66affSColin Finck debugstr_w(old_pstr), debugstr_w(pstr)); 1010c2c66affSColin Finck SendDlgItemMessageW(hWnd, cmb1, CB_SETITEMDATA, i, (LPARAM)pstr); 1011c2c66affSColin Finck n += lstrlenW(pstr) + 1; 1012c2c66affSColin Finck pstr += lstrlenW(pstr) + 1; 1013c2c66affSColin Finck } 1014c2c66affSColin Finck } 1015c2c66affSColin Finck /* set default filter */ 1016c2c66affSColin Finck if (ofn->nFilterIndex == 0 && ofn->lpstrCustomFilter == NULL) 1017c2c66affSColin Finck ofn->nFilterIndex = 1; 1018c2c66affSColin Finck SendDlgItemMessageW(hWnd, cmb1, CB_SETCURSEL, ofn->nFilterIndex - 1, 0); 1019c2c66affSColin Finck if (ofn->lpstrFile && ofn->lpstrFile[0]) 1020c2c66affSColin Finck { 1021c2c66affSColin Finck TRACE( "SetText of edt1 to %s\n", debugstr_w(ofn->lpstrFile) ); 1022c2c66affSColin Finck SetDlgItemTextW( hWnd, edt1, ofn->lpstrFile ); 1023c2c66affSColin Finck } 1024c2c66affSColin Finck else 1025c2c66affSColin Finck { 1026c2c66affSColin Finck lstrcpynW(tmpstr, FD31_GetFileType(ofn->lpstrCustomFilter, 1027c2c66affSColin Finck ofn->lpstrFilter, ofn->nFilterIndex - 1),BUFFILE); 1028c2c66affSColin Finck TRACE("nFilterIndex = %d, SetText of edt1 to %s\n", 1029c2c66affSColin Finck ofn->nFilterIndex, debugstr_w(tmpstr)); 1030c2c66affSColin Finck SetDlgItemTextW( hWnd, edt1, tmpstr ); 1031c2c66affSColin Finck } 1032c2c66affSColin Finck /* get drive list */ 1033c2c66affSColin Finck *tmpstr = 0; 1034c2c66affSColin Finck DlgDirListComboBoxW(hWnd, tmpstr, cmb2, 0, DDL_DRIVES | DDL_EXCLUSIVE); 1035c2c66affSColin Finck /* read initial directory */ 1036c2c66affSColin Finck /* FIXME: Note that this is now very version-specific (See MSDN description of 1037c2c66affSColin Finck * the OPENFILENAME structure). For example under 2000/XP any path in the 1038c2c66affSColin Finck * lpstrFile overrides the lpstrInitialDir, but not under 95/98/ME 1039c2c66affSColin Finck */ 1040c2c66affSColin Finck if (ofn->lpstrInitialDir != NULL) 1041c2c66affSColin Finck { 1042c2c66affSColin Finck int len; 1043c2c66affSColin Finck lstrcpynW(tmpstr, ofn->lpstrInitialDir, 511); 1044c2c66affSColin Finck len = lstrlenW(tmpstr); 1045c2c66affSColin Finck if (len > 0 && tmpstr[len-1] != '\\' && tmpstr[len-1] != ':') { 1046c2c66affSColin Finck tmpstr[len]='\\'; 1047c2c66affSColin Finck tmpstr[len+1]='\0'; 1048c2c66affSColin Finck } 1049c2c66affSColin Finck } 1050c2c66affSColin Finck else 1051c2c66affSColin Finck *tmpstr = 0; 1052c2c66affSColin Finck if (!FD31_ScanDir(ofn, hWnd, tmpstr)) { 1053c2c66affSColin Finck *tmpstr = 0; 1054c2c66affSColin Finck if (!FD31_ScanDir(ofn, hWnd, tmpstr)) 1055c2c66affSColin Finck WARN("Couldn't read initial directory %s!\n", debugstr_w(tmpstr)); 1056c2c66affSColin Finck } 1057c2c66affSColin Finck /* select current drive in combo 2, omit missing drives */ 1058c2c66affSColin Finck { 1059c2c66affSColin Finck char dir[MAX_PATH]; 1060c2c66affSColin Finck char str[4] = "a:\\"; 1061c2c66affSColin Finck GetCurrentDirectoryA( sizeof(dir), dir ); 1062c2c66affSColin Finck for(i = 0, n = -1; i < 26; i++) 1063c2c66affSColin Finck { 1064c2c66affSColin Finck str[0] = 'a' + i; 1065c2c66affSColin Finck if (GetDriveTypeA(str) > DRIVE_NO_ROOT_DIR) n++; 1066c2c66affSColin Finck if (toupper(str[0]) == toupper(dir[0])) break; 1067c2c66affSColin Finck } 1068c2c66affSColin Finck } 1069c2c66affSColin Finck SendDlgItemMessageW(hWnd, cmb2, CB_SETCURSEL, n, 0); 1070c2c66affSColin Finck if (!(ofn->Flags & OFN_SHOWHELP)) 1071c2c66affSColin Finck ShowWindow(GetDlgItem(hWnd, pshHelp), SW_HIDE); 1072c2c66affSColin Finck if (ofn->Flags & OFN_HIDEREADONLY) 1073c2c66affSColin Finck ShowWindow(GetDlgItem(hWnd, chx1), SW_HIDE); 1074c2c66affSColin Finck if (lfs->hook) 1075c2c66affSColin Finck return FD31_CallWindowProc(lfs, WM_INITDIALOG, wParam, lfs->lParam); 1076c2c66affSColin Finck return TRUE; 1077c2c66affSColin Finck } 1078c2c66affSColin Finck 1079c2c66affSColin Finck static int FD31_GetFldrHeight(void) 1080c2c66affSColin Finck { 1081c2c66affSColin Finck return fldrHeight; 1082c2c66affSColin Finck } 1083c2c66affSColin Finck 1084c2c66affSColin Finck /*********************************************************************** 1085c2c66affSColin Finck * FD31_WMMeasureItem [internal] 1086c2c66affSColin Finck */ 1087c2c66affSColin Finck static LONG FD31_WMMeasureItem(LPARAM lParam) 1088c2c66affSColin Finck { 1089c2c66affSColin Finck LPMEASUREITEMSTRUCT lpmeasure; 1090c2c66affSColin Finck 1091c2c66affSColin Finck lpmeasure = (LPMEASUREITEMSTRUCT)lParam; 1092c2c66affSColin Finck lpmeasure->itemHeight = FD31_GetFldrHeight(); 1093c2c66affSColin Finck return TRUE; 1094c2c66affSColin Finck } 1095c2c66affSColin Finck 1096c2c66affSColin Finck 1097c2c66affSColin Finck /*********************************************************************** 1098c2c66affSColin Finck * FileOpenDlgProc [internal] 1099c2c66affSColin Finck * Used for open and save, in fact. 1100c2c66affSColin Finck */ 1101c2c66affSColin Finck static INT_PTR CALLBACK FD31_FileOpenDlgProc(HWND hWnd, UINT wMsg, 1102c2c66affSColin Finck WPARAM wParam, LPARAM lParam) 1103c2c66affSColin Finck { 1104c2c66affSColin Finck PFD31_DATA lfs = (PFD31_DATA)GetPropA( hWnd, FD31_OFN_PROP ); 1105c2c66affSColin Finck 1106c2c66affSColin Finck TRACE("msg=%x wparam=%lx lParam=%lx\n", wMsg, wParam, lParam); 1107c2c66affSColin Finck if ((wMsg != WM_INITDIALOG) && lfs && lfs->hook) 1108c2c66affSColin Finck { 1109c2c66affSColin Finck INT_PTR lRet; 1110c2c66affSColin Finck lRet = (INT_PTR)FD31_CallWindowProc( lfs, wMsg, wParam, lParam ); 1111c2c66affSColin Finck if (lRet) return lRet; /* else continue message processing */ 1112c2c66affSColin Finck } 1113c2c66affSColin Finck switch (wMsg) 1114c2c66affSColin Finck { 1115c2c66affSColin Finck case WM_INITDIALOG: 1116c2c66affSColin Finck return FD31_WMInitDialog( hWnd, wParam, lParam ); 1117c2c66affSColin Finck 1118c2c66affSColin Finck case WM_MEASUREITEM: 1119c2c66affSColin Finck return FD31_WMMeasureItem( lParam ); 1120c2c66affSColin Finck 1121c2c66affSColin Finck case WM_DRAWITEM: 1122c2c66affSColin Finck return FD31_WMDrawItem( hWnd, wParam, lParam, !lfs->open, (DRAWITEMSTRUCT *)lParam ); 1123c2c66affSColin Finck 1124c2c66affSColin Finck case WM_COMMAND: 1125c2c66affSColin Finck return FD31_WMCommand( hWnd, lParam, HIWORD(wParam), LOWORD(wParam), lfs ); 1126c2c66affSColin Finck #if 0 1127c2c66affSColin Finck case WM_CTLCOLOR: 1128c2c66affSColin Finck SetBkColor( (HDC16)wParam, 0x00C0C0C0 ); 1129c2c66affSColin Finck switch (HIWORD(lParam)) 1130c2c66affSColin Finck { 1131c2c66affSColin Finck case CTLCOLOR_BTN: 1132c2c66affSColin Finck SetTextColor( (HDC16)wParam, 0x00000000 ); 1133c2c66affSColin Finck return hGRAYBrush; 1134c2c66affSColin Finck case CTLCOLOR_STATIC: 1135c2c66affSColin Finck SetTextColor( (HDC16)wParam, 0x00000000 ); 1136c2c66affSColin Finck return hGRAYBrush; 1137c2c66affSColin Finck } 1138c2c66affSColin Finck break; 1139c2c66affSColin Finck #endif 1140c2c66affSColin Finck } 1141c2c66affSColin Finck return FALSE; 1142c2c66affSColin Finck } 1143c2c66affSColin Finck 1144c2c66affSColin Finck /*********************************************************************** 1145c2c66affSColin Finck * GetFileName31A [internal] 1146c2c66affSColin Finck * 1147c2c66affSColin Finck * Creates a win31 style dialog box for the user to select a file to open/save. 1148c2c66affSColin Finck */ 1149c2c66affSColin Finck BOOL GetFileName31A( OPENFILENAMEA *lpofn, UINT dlgType ) 1150c2c66affSColin Finck { 1151c2c66affSColin Finck BOOL bRet = FALSE; 1152c2c66affSColin Finck PFD31_DATA lfs; 1153c2c66affSColin Finck 1154c2c66affSColin Finck if (!lpofn || !FD31_Init()) return FALSE; 1155c2c66affSColin Finck 1156c2c66affSColin Finck TRACE("ofn flags %08x\n", lpofn->Flags); 1157c2c66affSColin Finck lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, FALSE); 1158c2c66affSColin Finck if (lfs) 1159c2c66affSColin Finck { 1160c2c66affSColin Finck bRet = DialogBoxIndirectParamA( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner, 1161c2c66affSColin Finck FD31_FileOpenDlgProc, (LPARAM)lfs); 1162c2c66affSColin Finck FD31_DestroyPrivate(lfs); 1163c2c66affSColin Finck } 1164c2c66affSColin Finck 1165c2c66affSColin Finck TRACE("return lpstrFile='%s' !\n", lpofn->lpstrFile); 1166c2c66affSColin Finck return bRet; 1167c2c66affSColin Finck } 1168c2c66affSColin Finck 1169c2c66affSColin Finck /*********************************************************************** 1170c2c66affSColin Finck * GetFileName31W [internal] 1171c2c66affSColin Finck * 1172c2c66affSColin Finck * Creates a win31 style dialog box for the user to select a file to open/save 1173c2c66affSColin Finck */ 1174c2c66affSColin Finck BOOL GetFileName31W( OPENFILENAMEW *lpofn, UINT dlgType ) 1175c2c66affSColin Finck { 1176c2c66affSColin Finck BOOL bRet = FALSE; 1177c2c66affSColin Finck PFD31_DATA lfs; 1178c2c66affSColin Finck 1179c2c66affSColin Finck if (!lpofn || !FD31_Init()) return FALSE; 1180c2c66affSColin Finck 1181c2c66affSColin Finck lfs = FD31_AllocPrivate((LPARAM) lpofn, dlgType, TRUE); 1182c2c66affSColin Finck if (lfs) 1183c2c66affSColin Finck { 1184c2c66affSColin Finck bRet = DialogBoxIndirectParamW( COMDLG32_hInstance, lfs->template, lpofn->hwndOwner, 1185c2c66affSColin Finck FD31_FileOpenDlgProc, (LPARAM)lfs); 1186c2c66affSColin Finck FD31_DestroyPrivate(lfs); 1187c2c66affSColin Finck } 1188c2c66affSColin Finck 1189c2c66affSColin Finck TRACE("file %s, file offset %d, ext offset %d\n", 1190c2c66affSColin Finck debugstr_w(lpofn->lpstrFile), lpofn->nFileOffset, lpofn->nFileExtension); 1191c2c66affSColin Finck return bRet; 1192c2c66affSColin Finck } 1193