| 1 | /*
 | 
|---|
| 2 |  * COMMDLG - File Open Dialogs Win95 look and feel
 | 
|---|
| 3 |  *
 | 
|---|
| 4 |  * FIXME: lpstrCustomFilter not handled
 | 
|---|
| 5 |  *
 | 
|---|
| 6 |  * FIXME: if the size of lpstrFile (nMaxFile) is to small the first
 | 
|---|
| 7 |  * two bytes of lpstrFile should contain the needed size
 | 
|---|
| 8 |  *
 | 
|---|
| 9 |  * FIXME: algorithm for selecting the initial directory is too simple
 | 
|---|
| 10 |  *
 | 
|---|
| 11 |  * FIXME: add to recent docs
 | 
|---|
| 12 |  *
 | 
|---|
| 13 |  * FIXME: flags not implemented: OFN_CREATEPROMPT, OFN_DONTADDTORECENT,
 | 
|---|
| 14 |  * OFN_ENABLEINCLUDENOTIFY, OFN_ENABLESIZING, OFN_EXTENSIONDIFFERENT,
 | 
|---|
| 15 |  * OFN_NOCHANGEDIR, OFN_NODEREFERENCELINKS, OFN_READONLYRETURN,
 | 
|---|
| 16 |  * OFN_NOTESTFILECREATE, OFN_OVERWRITEPROMPT, OFN_USEMONIKERS
 | 
|---|
| 17 |  *
 | 
|---|
| 18 |  * FIXME: lCustData for lpfnHook (WM_INITDIALOG)
 | 
|---|
| 19 |  *
 | 
|---|
| 20 |  *
 | 
|---|
| 21 |  */
 | 
|---|
| 22 | #ifdef __WIN32OS2__
 | 
|---|
| 23 | #include <windef.h>
 | 
|---|
| 24 | #include <winbase.h>
 | 
|---|
| 25 | #include <wingdi.h>
 | 
|---|
| 26 | #include <winuser.h>
 | 
|---|
| 27 | #include <heapstring.h>
 | 
|---|
| 28 | #include <misc.h>
 | 
|---|
| 29 | #include <win\shlwapi.h>
 | 
|---|
| 30 | 
 | 
|---|
| 31 | #define MapHModuleSL(a) a
 | 
|---|
| 32 | #define MapHModuleLS(a) a
 | 
|---|
| 33 | 
 | 
|---|
| 34 | #endif
 | 
|---|
| 35 | 
 | 
|---|
| 36 | #include <ctype.h>
 | 
|---|
| 37 | #include <stdlib.h>
 | 
|---|
| 38 | #include <stdio.h>
 | 
|---|
| 39 | #include <string.h>
 | 
|---|
| 40 | 
 | 
|---|
| 41 | #include "winbase.h"
 | 
|---|
| 42 | #include "ntddk.h"
 | 
|---|
| 43 | #include "wine/winestring.h"
 | 
|---|
| 44 | #include "ldt.h"
 | 
|---|
| 45 | #include "heap.h"
 | 
|---|
| 46 | #include "commdlg.h"
 | 
|---|
| 47 | #include "dlgs.h"
 | 
|---|
| 48 | #include "cdlg.h"
 | 
|---|
| 49 | #include "debugtools.h"
 | 
|---|
| 50 | #include "cderr.h"
 | 
|---|
| 51 | #include "tweak.h"
 | 
|---|
| 52 | #include "winnls.h"
 | 
|---|
| 53 | #include "shellapi.h"
 | 
|---|
| 54 | #include "shlguid.h"
 | 
|---|
| 55 | #include "filedlgbrowser.h"
 | 
|---|
| 56 | #include "shlwapi.h"
 | 
|---|
| 57 | #include "wine/obj_contextmenu.h"
 | 
|---|
| 58 | 
 | 
|---|
| 59 | DEFAULT_DEBUG_CHANNEL(commdlg);
 | 
|---|
| 60 | 
 | 
|---|
| 61 | /***********************************************************************
 | 
|---|
| 62 |  * Data structure and global variables
 | 
|---|
| 63 |  */
 | 
|---|
| 64 | typedef struct SFolder
 | 
|---|
| 65 | {
 | 
|---|
| 66 |   int m_iImageIndex;    /* Index of picture in image list */
 | 
|---|
| 67 |   HIMAGELIST hImgList;
 | 
|---|
| 68 |   int m_iIndent;      /* Indentation index */
 | 
|---|
| 69 |   LPITEMIDLIST pidlItem;  /* absolute pidl of the item */ 
 | 
|---|
| 70 | 
 | 
|---|
| 71 | } SFOLDER,*LPSFOLDER;
 | 
|---|
| 72 | 
 | 
|---|
| 73 | typedef struct tagLookInInfo
 | 
|---|
| 74 | {
 | 
|---|
| 75 |   int iMaxIndentation;
 | 
|---|
| 76 |   UINT uSelectedItem;
 | 
|---|
| 77 | } LookInInfos;
 | 
|---|
| 78 | 
 | 
|---|
| 79 | 
 | 
|---|
| 80 | /***********************************************************************
 | 
|---|
| 81 |  * Defines and global variables
 | 
|---|
| 82 |  */
 | 
|---|
| 83 | 
 | 
|---|
| 84 | /* Draw item constant */
 | 
|---|
| 85 | #define ICONWIDTH 18
 | 
|---|
| 86 | #define YTEXTOFFSET 2
 | 
|---|
| 87 | #define XTEXTOFFSET 3
 | 
|---|
| 88 | 
 | 
|---|
| 89 | /* AddItem flags*/
 | 
|---|
| 90 | #define LISTEND -1
 | 
|---|
| 91 | 
 | 
|---|
| 92 | /* SearchItem methods */
 | 
|---|
| 93 | #define SEARCH_PIDL 1
 | 
|---|
| 94 | #define SEARCH_EXP  2
 | 
|---|
| 95 | #define ITEM_NOTFOUND -1
 | 
|---|
| 96 | 
 | 
|---|
| 97 | /* Undefined windows message sent by CreateViewObject*/
 | 
|---|
| 98 | #define WM_GETISHELLBROWSER  WM_USER+7
 | 
|---|
| 99 | 
 | 
|---|
| 100 | /* NOTE
 | 
|---|
| 101 |  * Those macros exist in windowsx.h. However, you can't really use them since
 | 
|---|
| 102 |  * they rely on the UNICODE defines and can't be use inside Wine itself.
 | 
|---|
| 103 |  */
 | 
|---|
| 104 | 
 | 
|---|
| 105 | /* Combo box macros */
 | 
|---|
| 106 | #define CBAddString(hwnd,str) \
 | 
|---|
| 107 |   SendMessageA(hwnd,CB_ADDSTRING,0,(LPARAM)str);
 | 
|---|
| 108 | 
 | 
|---|
| 109 | #define CBInsertString(hwnd,str,pos) \
 | 
|---|
| 110 |   SendMessageA(hwnd,CB_INSERTSTRING,(WPARAM)pos,(LPARAM)str);
 | 
|---|
| 111 | 
 | 
|---|
| 112 | #define CBDeleteString(hwnd,pos) \
 | 
|---|
| 113 |   SendMessageA(hwnd,CB_DELETESTRING,(WPARAM)pos,0);
 | 
|---|
| 114 | 
 | 
|---|
| 115 | #define CBSetItemDataPtr(hwnd,iItemId,dataPtr) \
 | 
|---|
| 116 |   SendMessageA(hwnd,CB_SETITEMDATA,(WPARAM)iItemId,(LPARAM)dataPtr);
 | 
|---|
| 117 | 
 | 
|---|
| 118 | #define CBGetItemDataPtr(hwnd,iItemId) \
 | 
|---|
| 119 |   SendMessageA(hwnd,CB_GETITEMDATA,(WPARAM)iItemId,0)
 | 
|---|
| 120 | 
 | 
|---|
| 121 | #define CBGetLBText(hwnd,iItemId,str) \
 | 
|---|
| 122 |   SendMessageA(hwnd,CB_GETLBTEXT,(WPARAM)iItemId,(LPARAM)str);
 | 
|---|
| 123 | 
 | 
|---|
| 124 | #define CBGetCurSel(hwnd) \
 | 
|---|
| 125 |   SendMessageA(hwnd,CB_GETCURSEL,0,0);
 | 
|---|
| 126 | 
 | 
|---|
| 127 | #define CBSetCurSel(hwnd,pos) \
 | 
|---|
| 128 |   SendMessageA(hwnd,CB_SETCURSEL,(WPARAM)pos,0);
 | 
|---|
| 129 | 
 | 
|---|
| 130 | #define CBGetCount(hwnd) \
 | 
|---|
| 131 |     SendMessageA(hwnd,CB_GETCOUNT,0,0);
 | 
|---|
| 132 | #define CBShowDropDown(hwnd,show) \
 | 
|---|
| 133 |   SendMessageA(hwnd,CB_SHOWDROPDOWN,(WPARAM)show,0);
 | 
|---|
| 134 | #define CBSetItemHeight(hwnd,index,height) \
 | 
|---|
| 135 |   SendMessageA(hwnd,CB_SETITEMHEIGHT,(WPARAM)index,(LPARAM)height);
 | 
|---|
| 136 | 
 | 
|---|
| 137 | 
 | 
|---|
| 138 | const char *FileOpenDlgInfosStr = "FileOpenDlgInfos"; /* windows property description string */
 | 
|---|
| 139 | const char *LookInInfosStr = "LookInInfos"; /* LOOKIN combo box property */
 | 
|---|
| 140 | 
 | 
|---|
| 141 | static const char defaultFilter[] = "*.*";
 | 
|---|
| 142 | 
 | 
|---|
| 143 | /***********************************************************************
 | 
|---|
| 144 |  * Prototypes
 | 
|---|
| 145 |  */
 | 
|---|
| 146 | 
 | 
|---|
| 147 | /* Internal functions used by the dialog */
 | 
|---|
| 148 | static LRESULT FILEDLG95_OnWMInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam);
 | 
|---|
| 149 | static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam);
 | 
|---|
| 150 | static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd);
 | 
|---|
| 151 |        BOOL    FILEDLG95_OnOpen(HWND hwnd);
 | 
|---|
| 152 | static LRESULT FILEDLG95_InitUI(HWND hwnd);
 | 
|---|
| 153 | static void    FILEDLG95_Clean(HWND hwnd);
 | 
|---|
| 154 | 
 | 
|---|
| 155 | /* Functions used by the shell navigation */
 | 
|---|
| 156 | static LRESULT FILEDLG95_SHELL_Init(HWND hwnd);
 | 
|---|
| 157 | static BOOL    FILEDLG95_SHELL_UpFolder(HWND hwnd);
 | 
|---|
| 158 | static BOOL    FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb);
 | 
|---|
| 159 | static void    FILEDLG95_SHELL_Clean(HWND hwnd);
 | 
|---|
| 160 | static BOOL    FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd);
 | 
|---|
| 161 | 
 | 
|---|
| 162 | /* Functions used by the filetype combo box */
 | 
|---|
| 163 | static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd);
 | 
|---|
| 164 | static BOOL    FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode);
 | 
|---|
| 165 | static int     FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCSTR lpstrExt);
 | 
|---|
| 166 | static void    FILEDLG95_FILETYPE_Clean(HWND hwnd);
 | 
|---|
| 167 | 
 | 
|---|
| 168 | /* Functions used by the Look In combo box */
 | 
|---|
| 169 | static HRESULT FILEDLG95_LOOKIN_Init(HWND hwndCombo);
 | 
|---|
| 170 | static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct);
 | 
|---|
| 171 | static BOOL    FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode);
 | 
|---|
| 172 | static int     FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId);
 | 
|---|
| 173 | static int     FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod);
 | 
|---|
| 174 | static int     FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl);
 | 
|---|
| 175 | static int     FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd);
 | 
|---|
| 176 |        int     FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl);
 | 
|---|
| 177 | static void    FILEDLG95_LOOKIN_Clean(HWND hwnd);
 | 
|---|
| 178 | 
 | 
|---|
| 179 | /* Miscellaneous tool functions */
 | 
|---|
| 180 | HRESULT       GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName);
 | 
|---|
| 181 | HRESULT       GetFileName(HWND hwnd, LPITEMIDLIST pidl, LPSTR lpstrFileName);
 | 
|---|
| 182 | IShellFolder* GetShellFolderFromPidl(LPITEMIDLIST pidlAbs);
 | 
|---|
| 183 | LPITEMIDLIST  GetParentPidl(LPITEMIDLIST pidl);
 | 
|---|
| 184 | LPITEMIDLIST  GetPidlFromName(IShellFolder *psf,LPCSTR lpcstrFileName);
 | 
|---|
| 185 | 
 | 
|---|
| 186 | /* Shell memory allocation */
 | 
|---|
| 187 | static void *MemAlloc(UINT size);
 | 
|---|
| 188 | static void MemFree(void *mem);
 | 
|---|
| 189 | 
 | 
|---|
| 190 | BOOL WINAPI GetFileName95(FileOpenDlgInfos *fodInfos);
 | 
|---|
| 191 | HRESULT WINAPI FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 | 
|---|
| 192 | HRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode);
 | 
|---|
| 193 | HRESULT FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
 | 
|---|
| 194 | BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPSTR lpstrFileList, UINT nFileCount, UINT sizeUsed);
 | 
|---|
| 195 | static BOOL BrowseSelectedFolder(HWND hwnd);
 | 
|---|
| 196 | 
 | 
|---|
| 197 | /***********************************************************************
 | 
|---|
| 198 |  *      GetFileName95
 | 
|---|
| 199 |  *
 | 
|---|
| 200 |  * Creates an Open common dialog box that lets the user select 
 | 
|---|
| 201 |  * the drive, directory, and the name of a file or set of files to open.
 | 
|---|
| 202 |  *
 | 
|---|
| 203 |  * IN  : The FileOpenDlgInfos structure associated with the dialog
 | 
|---|
| 204 |  * OUT : TRUE on success
 | 
|---|
| 205 |  *       FALSE on cancel, error, close or filename-does-not-fit-in-buffer.
 | 
|---|
| 206 |  */
 | 
|---|
| 207 | BOOL WINAPI GetFileName95(FileOpenDlgInfos *fodInfos)
 | 
|---|
| 208 | {
 | 
|---|
| 209 | 
 | 
|---|
| 210 |     LRESULT lRes;
 | 
|---|
| 211 |     LPCVOID template;
 | 
|---|
| 212 |     HRSRC hRes;
 | 
|---|
| 213 |     HANDLE hDlgTmpl = 0;
 | 
|---|
| 214 | 
 | 
|---|
| 215 |     /* Create the dialog from a template */
 | 
|---|
| 216 | 
 | 
|---|
| 217 |     if(!(hRes = FindResourceA(COMMDLG_hInstance32,MAKEINTRESOURCEA(NEWFILEOPENORD),RT_DIALOGA)))
 | 
|---|
| 218 |     {
 | 
|---|
| 219 |         COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
 | 
|---|
| 220 |         return FALSE;
 | 
|---|
| 221 |     }
 | 
|---|
| 222 |     if (!(hDlgTmpl = LoadResource(COMMDLG_hInstance32, hRes )) ||
 | 
|---|
| 223 |         !(template = LockResource( hDlgTmpl )))
 | 
|---|
| 224 |     {
 | 
|---|
| 225 |         COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
 | 
|---|
| 226 |         return FALSE;
 | 
|---|
| 227 |     }
 | 
|---|
| 228 |     lRes = DialogBoxIndirectParamA(COMMDLG_hInstance32,
 | 
|---|
| 229 |                                   (LPDLGTEMPLATEA) template,
 | 
|---|
| 230 |                                   fodInfos->ofnInfos->hwndOwner,
 | 
|---|
| 231 |                                   (DLGPROC) FileOpenDlgProc95,
 | 
|---|
| 232 |                                   (LPARAM) fodInfos);
 | 
|---|
| 233 | 
 | 
|---|
| 234 |     /* Unable to create the dialog*/
 | 
|---|
| 235 |     if( lRes == -1)
 | 
|---|
| 236 |         return FALSE;
 | 
|---|
| 237 |     
 | 
|---|
| 238 |     return lRes;
 | 
|---|
| 239 | }
 | 
|---|
| 240 | 
 | 
|---|
| 241 | /***********************************************************************
 | 
|---|
| 242 |  *      GetFileDialog95A
 | 
|---|
| 243 |  *
 | 
|---|
| 244 |  * Call GetFileName95 with this structure and clean the memory.
 | 
|---|
| 245 |  *
 | 
|---|
| 246 |  * IN  : The OPENFILENAMEA initialisation structure passed to
 | 
|---|
| 247 |  *       GetOpenFileNameA win api function (see filedlg.c)
 | 
|---|
| 248 |  */
 | 
|---|
| 249 | BOOL  WINAPI GetFileDialog95A(LPOPENFILENAMEA ofn,UINT iDlgType)
 | 
|---|
| 250 | {
 | 
|---|
| 251 | 
 | 
|---|
| 252 |   BOOL ret;
 | 
|---|
| 253 |   FileOpenDlgInfos *fodInfos;
 | 
|---|
| 254 |   HINSTANCE hInstance;
 | 
|---|
| 255 |   LPCSTR lpstrInitialDir = (LPCSTR)-1;
 | 
|---|
| 256 |   DWORD dwFlags = 0;
 | 
|---|
| 257 |   
 | 
|---|
| 258 |   /* Initialise FileOpenDlgInfos structure*/  
 | 
|---|
| 259 |   fodInfos = (FileOpenDlgInfos*)MemAlloc(sizeof(FileOpenDlgInfos));
 | 
|---|
| 260 |   ZeroMemory(fodInfos, sizeof(FileOpenDlgInfos));
 | 
|---|
| 261 |   
 | 
|---|
| 262 |   /* Pass in the original ofn */
 | 
|---|
| 263 |   fodInfos->ofnInfos = ofn;
 | 
|---|
| 264 |   
 | 
|---|
| 265 |   /* Save original hInstance value */
 | 
|---|
| 266 |   hInstance = ofn->hInstance;
 | 
|---|
| 267 |   fodInfos->ofnInfos->hInstance = MapHModuleLS(ofn->hInstance);
 | 
|---|
| 268 | 
 | 
|---|
| 269 |   dwFlags = ofn->Flags;
 | 
|---|
| 270 |   ofn->Flags = ofn->Flags|OFN_WINE;
 | 
|---|
| 271 | 
 | 
|---|
| 272 |   /* Replace the NULL lpstrInitialDir by the current folder */
 | 
|---|
| 273 |   if(!ofn->lpstrInitialDir)
 | 
|---|
| 274 |   {
 | 
|---|
| 275 |     lpstrInitialDir = ofn->lpstrInitialDir;
 | 
|---|
| 276 |     ofn->lpstrInitialDir = MemAlloc(MAX_PATH);
 | 
|---|
| 277 |     GetCurrentDirectoryA(MAX_PATH,(LPSTR)ofn->lpstrInitialDir);
 | 
|---|
| 278 |   }
 | 
|---|
| 279 | 
 | 
|---|
| 280 |   /* Initialise the dialog property */
 | 
|---|
| 281 |   fodInfos->DlgInfos.dwDlgProp = 0;
 | 
|---|
| 282 |   fodInfos->DlgInfos.hwndCustomDlg = (HWND)NULL;
 | 
|---|
| 283 |   
 | 
|---|
| 284 |   switch(iDlgType)
 | 
|---|
| 285 |   {
 | 
|---|
| 286 |     case OPEN_DIALOG :
 | 
|---|
| 287 |       ret = GetFileName95(fodInfos);
 | 
|---|
| 288 |       break;
 | 
|---|
| 289 |     case SAVE_DIALOG :
 | 
|---|
| 290 |       fodInfos->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
 | 
|---|
| 291 |       ret = GetFileName95(fodInfos);
 | 
|---|
| 292 |       break;
 | 
|---|
| 293 |     default :
 | 
|---|
| 294 |       ret = 0;
 | 
|---|
| 295 |   }
 | 
|---|
| 296 | 
 | 
|---|
| 297 |   if (lpstrInitialDir != (LPCSTR)-1)
 | 
|---|
| 298 |   {
 | 
|---|
| 299 |     MemFree((LPVOID)(ofn->lpstrInitialDir));
 | 
|---|
| 300 |     ofn->lpstrInitialDir = lpstrInitialDir;
 | 
|---|
| 301 |   }
 | 
|---|
| 302 | 
 | 
|---|
| 303 |   ofn->Flags = dwFlags;
 | 
|---|
| 304 |   ofn->hInstance = hInstance;
 | 
|---|
| 305 |   MemFree((LPVOID)(fodInfos));
 | 
|---|
| 306 |   return ret;
 | 
|---|
| 307 | }
 | 
|---|
| 308 | 
 | 
|---|
| 309 | /***********************************************************************
 | 
|---|
| 310 |  *      GetFileDialog95W
 | 
|---|
| 311 |  *
 | 
|---|
| 312 |  * Copy the OPENFILENAMEW structure in a FileOpenDlgInfos structure.
 | 
|---|
| 313 |  * Call GetFileName95 with this structure and clean the memory.
 | 
|---|
| 314 |  *
 | 
|---|
| 315 |  * IN  : The OPENFILENAMEW initialisation structure passed to
 | 
|---|
| 316 |  *       GetOpenFileNameW win api function (see filedlg.c)
 | 
|---|
| 317 |  *
 | 
|---|
| 318 |  * FIXME:
 | 
|---|
| 319 |  *   some more strings are needing to be convertet AtoW
 | 
|---|
| 320 |  */
 | 
|---|
| 321 | BOOL  WINAPI GetFileDialog95W(LPOPENFILENAMEW ofn,UINT iDlgType)
 | 
|---|
| 322 | {
 | 
|---|
| 323 |   BOOL ret;
 | 
|---|
| 324 |   FileOpenDlgInfos *fodInfos;
 | 
|---|
| 325 |   HINSTANCE hInstance;
 | 
|---|
| 326 |   LPCSTR lpstrFilter = NULL;
 | 
|---|
| 327 |   LPSTR lpstrCustomFilter = NULL;
 | 
|---|
| 328 | #ifdef __WIN32OS2__
 | 
|---|
| 329 |   LPWSTR lpstrInitialDir = NULL; 
 | 
|---|
| 330 |   LPWSTR lpstrTitle = NULL;
 | 
|---|
| 331 | #endif
 | 
|---|
| 332 |   LPWSTR lpstrFile = NULL;
 | 
|---|
| 333 |   DWORD dwFlags;
 | 
|---|
| 334 | 
 | 
|---|
| 335 |   /* Initialise FileOpenDlgInfos structure*/
 | 
|---|
| 336 |   fodInfos = (FileOpenDlgInfos*)MemAlloc(sizeof(FileOpenDlgInfos));
 | 
|---|
| 337 |   ZeroMemory(fodInfos, sizeof(FileOpenDlgInfos));
 | 
|---|
| 338 | 
 | 
|---|
| 339 |   /*  Pass in the original ofn */
 | 
|---|
| 340 |   fodInfos->ofnInfos = (LPOPENFILENAMEA) ofn;
 | 
|---|
| 341 | 
 | 
|---|
| 342 |   /* Save hInstance */
 | 
|---|
| 343 |   hInstance = fodInfos->ofnInfos->hInstance;
 | 
|---|
| 344 |   fodInfos->ofnInfos->hInstance = MapHModuleLS(ofn->hInstance);
 | 
|---|
| 345 | 
 | 
|---|
| 346 |   /* Save lpstrFilter */
 | 
|---|
| 347 |   if (ofn->lpstrFilter)
 | 
|---|
| 348 |   {
 | 
|---|
| 349 |     LPWSTR  s;
 | 
|---|
| 350 |     LPSTR x,y;
 | 
|---|
| 351 |     int n;
 | 
|---|
| 352 | 
 | 
|---|
| 353 |     lpstrFilter = fodInfos->ofnInfos->lpstrFilter;
 | 
|---|
| 354 | 
 | 
|---|
| 355 |     /* filter is a list...  title\0ext\0......\0\0 */
 | 
|---|
| 356 |     s = (LPWSTR)ofn->lpstrFilter;
 | 
|---|
| 357 |     
 | 
|---|
| 358 |     while (*s)
 | 
|---|
| 359 |       s = s+lstrlenW(s)+1;
 | 
|---|
| 360 |     s++;
 | 
|---|
| 361 |     n = s - ofn->lpstrFilter; /* already divides by 2. ptr magic */
 | 
|---|
| 362 |     x = y = (LPSTR)MemAlloc(n);
 | 
|---|
| 363 |     s = (LPWSTR)ofn->lpstrFilter;
 | 
|---|
| 364 |     while (*s) {
 | 
|---|
| 365 |       lstrcpyWtoA(x,s);
 | 
|---|
| 366 |       x+=strlen(x)+1;
 | 
|---|
| 367 |       s+=lstrlenW(s)+1;
 | 
|---|
| 368 |     }
 | 
|---|
| 369 |     *x=0;
 | 
|---|
| 370 |     fodInfos->ofnInfos->lpstrFilter = (LPSTR)y;
 | 
|---|
| 371 |   }
 | 
|---|
| 372 |   /* Save lpstrCustomFilter */
 | 
|---|
| 373 |   if (ofn->lpstrCustomFilter)
 | 
|---|
| 374 |   {
 | 
|---|
| 375 |     LPWSTR  s;
 | 
|---|
| 376 |     LPSTR x,y;
 | 
|---|
| 377 |     int n;
 | 
|---|
| 378 | 
 | 
|---|
| 379 |     lpstrCustomFilter = fodInfos->ofnInfos->lpstrCustomFilter;
 | 
|---|
| 380 |     /* filter is a list...  title\0ext\0......\0\0 */
 | 
|---|
| 381 |     s = (LPWSTR)ofn->lpstrCustomFilter;
 | 
|---|
| 382 |     while (*s)
 | 
|---|
| 383 |       s = s+lstrlenW(s)+1;
 | 
|---|
| 384 |     s++;
 | 
|---|
| 385 |     n = s - ofn->lpstrCustomFilter;
 | 
|---|
| 386 |     x = y = (LPSTR)MemAlloc(n);
 | 
|---|
| 387 |     s = (LPWSTR)ofn->lpstrCustomFilter;
 | 
|---|
| 388 |     while (*s) {
 | 
|---|
| 389 |       lstrcpyWtoA(x,s);
 | 
|---|
| 390 |       x+=strlen(x)+1;
 | 
|---|
| 391 |       s+=lstrlenW(s)+1;
 | 
|---|
| 392 |     }
 | 
|---|
| 393 |     *x=0;
 | 
|---|
| 394 |     fodInfos->ofnInfos->lpstrCustomFilter = (LPSTR)y;
 | 
|---|
| 395 |   }
 | 
|---|
| 396 | 
 | 
|---|
| 397 |   /* Save Flags */
 | 
|---|
| 398 |   dwFlags = fodInfos->ofnInfos->Flags;
 | 
|---|
| 399 |   fodInfos->ofnInfos->Flags = ofn->Flags|OFN_WINE|OFN_UNICODE;
 | 
|---|
| 400 | 
 | 
|---|
| 401 |   /* Initialise the dialog property */
 | 
|---|
| 402 |   fodInfos->DlgInfos.dwDlgProp = 0;
 | 
|---|
| 403 |   
 | 
|---|
| 404 |   /* allocate ansi filename buffer */
 | 
|---|
| 405 |   lpstrFile = ofn->lpstrFile;  
 | 
|---|
| 406 |   ofn->lpstrFile = MemAlloc(ofn->nMaxFile);
 | 
|---|
| 407 | 
 | 
|---|
| 408 | #ifdef __WIN32OS2__
 | 
|---|
| 409 |   // convert initial dir & title (if necessary)
 | 
|---|
| 410 |   lpstrInitialDir = (LPWSTR)ofn->lpstrInitialDir;
 | 
|---|
| 411 |   if(lpstrInitialDir && *lpstrInitialDir != 0) {
 | 
|---|
| 412 |         ofn->lpstrInitialDir = MemAlloc(lstrlenW(ofn->lpstrInitialDir)+1);
 | 
|---|
| 413 |         lstrcpyWtoA((LPSTR)ofn->lpstrInitialDir, lpstrInitialDir);
 | 
|---|
| 414 |   }
 | 
|---|
| 415 |   else
 | 
|---|
| 416 |   /* Replace the NULL lpstrInitialDir by the current folder */
 | 
|---|
| 417 |   if(!lpstrInitialDir || *lpstrInitialDir == 0)
 | 
|---|
| 418 |   {
 | 
|---|
| 419 |         ofn->lpstrInitialDir = MemAlloc(MAX_PATH);
 | 
|---|
| 420 |         GetCurrentDirectoryA(MAX_PATH,(LPSTR)ofn->lpstrInitialDir);
 | 
|---|
| 421 |   }
 | 
|---|
| 422 | 
 | 
|---|
| 423 |   lpstrTitle = (LPWSTR)ofn->lpstrTitle;
 | 
|---|
| 424 |   if(lpstrTitle) {
 | 
|---|
| 425 |         ofn->lpstrTitle = MemAlloc(lstrlenW(ofn->lpstrTitle)+1);
 | 
|---|
| 426 |         lstrcpyWtoA((LPSTR)ofn->lpstrTitle, lpstrTitle);
 | 
|---|
| 427 |   }
 | 
|---|
| 428 | 
 | 
|---|
| 429 | #endif
 | 
|---|
| 430 |   
 | 
|---|
| 431 |   switch(iDlgType)
 | 
|---|
| 432 |   {
 | 
|---|
| 433 |   case OPEN_DIALOG :
 | 
|---|
| 434 |       ret = GetFileName95(fodInfos);
 | 
|---|
| 435 |       break;
 | 
|---|
| 436 |   case SAVE_DIALOG :
 | 
|---|
| 437 |       fodInfos->DlgInfos.dwDlgProp |= FODPROP_SAVEDLG;
 | 
|---|
| 438 |       ret = GetFileName95(fodInfos);
 | 
|---|
| 439 |       break;
 | 
|---|
| 440 |   default :
 | 
|---|
| 441 |       ret = 0;
 | 
|---|
| 442 |   }
 | 
|---|
| 443 |       
 | 
|---|
| 444 |   /* Cleaning */
 | 
|---|
| 445 |   /* Restore Flags */
 | 
|---|
| 446 |   fodInfos->ofnInfos->Flags = dwFlags;
 | 
|---|
| 447 | 
 | 
|---|
| 448 |   /* Restore lpstrFilter */
 | 
|---|
| 449 |   if (fodInfos->ofnInfos->lpstrFilter)
 | 
|---|
| 450 |   {
 | 
|---|
| 451 |     MemFree((LPVOID)(fodInfos->ofnInfos->lpstrFilter));
 | 
|---|
| 452 |     fodInfos->ofnInfos->lpstrFilter = lpstrFilter;
 | 
|---|
| 453 |   }
 | 
|---|
| 454 |   if (fodInfos->ofnInfos->lpstrCustomFilter)
 | 
|---|
| 455 |   {
 | 
|---|
| 456 |     MemFree((LPVOID)(fodInfos->ofnInfos->lpstrCustomFilter));
 | 
|---|
| 457 |     fodInfos->ofnInfos->lpstrCustomFilter = lpstrCustomFilter;
 | 
|---|
| 458 |   }
 | 
|---|
| 459 | 
 | 
|---|
| 460 |   /* Restore hInstance */
 | 
|---|
| 461 |   fodInfos->ofnInfos->hInstance = hInstance;
 | 
|---|
| 462 |   MemFree((LPVOID)(fodInfos));
 | 
|---|
| 463 | 
 | 
|---|
| 464 |   /* filename */
 | 
|---|
| 465 |   lstrcpynAtoW(lpstrFile, (LPCSTR)ofn->lpstrFile, ofn->nMaxFile);
 | 
|---|
| 466 |   MemFree(ofn->lpstrFile);
 | 
|---|
| 467 |   ofn->lpstrFile = lpstrFile;
 | 
|---|
| 468 | 
 | 
|---|
| 469 | #ifdef __WIN32OS2__
 | 
|---|
| 470 |   //free converted initial dir & title strings
 | 
|---|
| 471 |   if(lpstrInitialDir) {
 | 
|---|
| 472 |         MemFree((LPVOID)ofn->lpstrInitialDir);
 | 
|---|
| 473 |         ofn->lpstrInitialDir = (LPCWSTR)lpstrInitialDir;
 | 
|---|
| 474 |   }
 | 
|---|
| 475 |   if(lpstrTitle) {
 | 
|---|
| 476 |         MemFree((LPVOID)ofn->lpstrTitle);
 | 
|---|
| 477 |         ofn->lpstrTitle = (LPCWSTR)lpstrTitle;
 | 
|---|
| 478 |   }
 | 
|---|
| 479 | #endif
 | 
|---|
| 480 | 
 | 
|---|
| 481 |   return ret;
 | 
|---|
| 482 | }
 | 
|---|
| 483 | 
 | 
|---|
| 484 | void ArrangeCtrlPositions( HWND hwndChildDlg, HWND hwndParentDlg)
 | 
|---|
| 485 | {
 | 
|---|
| 486 | 
 | 
|---|
| 487 |         HWND hwndChild,hwndStc32;
 | 
|---|
| 488 |         RECT rectParent, rectChild, rectCtrl, rectStc32, rectTemp;
 | 
|---|
| 489 |         POINT ptMoveCtl;
 | 
|---|
| 490 |         POINT ptParentClient;
 | 
|---|
| 491 | 
 | 
|---|
| 492 |         ptMoveCtl.x = ptMoveCtl.y = 0;
 | 
|---|
| 493 |         hwndStc32=GetDlgItem(hwndChildDlg,stc32);
 | 
|---|
| 494 |         GetClientRect(hwndParentDlg,&rectParent);
 | 
|---|
| 495 |         GetClientRect(hwndChildDlg,&rectChild);
 | 
|---|
| 496 |         if(hwndStc32)
 | 
|---|
| 497 |         {
 | 
|---|
| 498 |                 GetWindowRect(hwndStc32,&rectStc32);
 | 
|---|
| 499 |                 MapWindowPoints(0, hwndChildDlg,(LPPOINT)&rectStc32,2);
 | 
|---|
| 500 |                 CopyRect(&rectTemp,&rectStc32);
 | 
|---|
| 501 | 
 | 
|---|
| 502 |                 SetRect(&rectStc32,rectStc32.left,rectStc32.top,rectStc32.left + (rectParent.right-rectParent.left),rectStc32.top+(rectParent.bottom-rectParent.top));
 | 
|---|
| 503 |                 SetWindowPos(hwndStc32,0,rectStc32.left,rectStc32.top,rectStc32.right-rectStc32.left,rectStc32.bottom-rectStc32.top,SWP_NOMOVE|SWP_NOZORDER | SWP_NOACTIVATE);
 | 
|---|
| 504 | 
 | 
|---|
| 505 |                 if(rectStc32.right < rectTemp.right)
 | 
|---|
| 506 |                 {
 | 
|---|
| 507 |                         ptParentClient.x = max((rectParent.right-rectParent.left),(rectChild.right-rectChild.left));
 | 
|---|
| 508 |                         ptMoveCtl.x = 0;
 | 
|---|
| 509 |                 }
 | 
|---|
| 510 |                 else
 | 
|---|
| 511 |                 {
 | 
|---|
| 512 |                         ptMoveCtl.x = (rectStc32.right - rectTemp.right);
 | 
|---|
| 513 |                         ptParentClient.x = max((rectParent.right-rectParent.left),((rectChild.right-rectChild.left)+rectStc32.right-rectTemp.right));
 | 
|---|
| 514 |                 }
 | 
|---|
| 515 |                 if(rectStc32.bottom < rectTemp.bottom)
 | 
|---|
| 516 |                 {
 | 
|---|
| 517 |                         ptParentClient.y = max((rectParent.bottom-rectParent.top),(rectChild.bottom-rectChild.top));
 | 
|---|
| 518 |                         ptMoveCtl.y = 0;
 | 
|---|
| 519 |                 }
 | 
|---|
| 520 |                 else
 | 
|---|
| 521 |                 {
 | 
|---|
| 522 |                         ptMoveCtl.y = (rectStc32.bottom - rectTemp.bottom);
 | 
|---|
| 523 |                         ptParentClient.y = max((rectParent.bottom-rectParent.top),((rectChild.bottom-rectChild.top)+rectStc32.bottom-rectTemp.bottom));
 | 
|---|
| 524 |                 }
 | 
|---|
| 525 |         }
 | 
|---|
| 526 |         else
 | 
|---|
| 527 |         {
 | 
|---|
| 528 |                 if( (GetWindow(hwndChildDlg,GW_CHILD)) == (HWND) NULL)
 | 
|---|
| 529 |                    return;
 | 
|---|
| 530 |                 SetRectEmpty(&rectTemp);
 | 
|---|
| 531 |                 ptParentClient.x = max((rectParent.right-rectParent.left),(rectChild.right-rectChild.left));
 | 
|---|
| 532 |                 ptParentClient.y = (rectParent.bottom-rectParent.top) + (rectChild.bottom-rectChild.top);
 | 
|---|
| 533 |                 ptMoveCtl.y = rectParent.bottom-rectParent.top;
 | 
|---|
| 534 |                 ptMoveCtl.x=0;
 | 
|---|
| 535 |         }
 | 
|---|
| 536 |         SetRect(&rectParent,rectParent.left,rectParent.top,rectParent.left+ptParentClient.x,rectParent.top+ptParentClient.y);
 | 
|---|
| 537 |         AdjustWindowRectEx( &rectParent,GetWindowLongA(hwndParentDlg,GWL_STYLE),FALSE,GetWindowLongA(hwndParentDlg,GWL_EXSTYLE));
 | 
|---|
| 538 | 
 | 
|---|
| 539 |         SetWindowPos(hwndChildDlg, 0, 0,0, ptParentClient.x,ptParentClient.y,
 | 
|---|
| 540 |                  SWP_NOZORDER );
 | 
|---|
| 541 |         SetWindowPos(hwndParentDlg, 0, rectParent.left,rectParent.top, (rectParent.right- rectParent.left),
 | 
|---|
| 542 |                 (rectParent.bottom-rectParent.top),SWP_NOMOVE | SWP_NOZORDER);
 | 
|---|
| 543 |         
 | 
|---|
| 544 |         hwndChild = GetWindow(hwndChildDlg,GW_CHILD);
 | 
|---|
| 545 |         if(hwndStc32)
 | 
|---|
| 546 |         {
 | 
|---|
| 547 |                 GetWindowRect(hwndStc32,&rectStc32);
 | 
|---|
| 548 |                 MapWindowPoints( 0, hwndChildDlg,(LPPOINT)&rectStc32,2);
 | 
|---|
| 549 |         }
 | 
|---|
| 550 |         else
 | 
|---|
| 551 |                 SetRect(&rectStc32,0,0,0,0);
 | 
|---|
| 552 | 
 | 
|---|
| 553 |         if (hwndChild )
 | 
|---|
| 554 |         {
 | 
|---|
| 555 |                 do
 | 
|---|
| 556 |                 {
 | 
|---|
| 557 |                         if(hwndChild != hwndStc32)
 | 
|---|
| 558 |                         {
 | 
|---|
| 559 |                         if (GetWindowLongA( hwndChild, GWL_STYLE ) & WS_MAXIMIZE)
 | 
|---|
| 560 |                                 continue;
 | 
|---|
| 561 |                         GetWindowRect(hwndChild,&rectCtrl);
 | 
|---|
| 562 |                         MapWindowPoints( 0, hwndParentDlg,(LPPOINT)&rectCtrl,2);
 | 
|---|
| 563 |                                   
 | 
|---|
| 564 |                                 /*
 | 
|---|
| 565 |                                    Check the initial position of the controls relative to the initial
 | 
|---|
| 566 |                                    position and size of stc32 (before it is expanded).
 | 
|---|
| 567 |                                 */
 | 
|---|
| 568 |                 if (rectCtrl.left >= rectTemp.right && rectCtrl.top >= rectTemp.bottom)
 | 
|---|
| 569 |                                 {
 | 
|---|
| 570 |                                         rectCtrl.left += ptMoveCtl.x;
 | 
|---|
| 571 |                                 rectCtrl.top  += ptMoveCtl.y;
 | 
|---|
| 572 |                                 }
 | 
|---|
| 573 |                                 else if (rectCtrl.left >= rectTemp.right)
 | 
|---|
| 574 |                                         rectCtrl.left += ptMoveCtl.x;
 | 
|---|
| 575 |                                 else if (rectCtrl.top >= rectTemp.bottom)
 | 
|---|
| 576 |                                         rectCtrl.top  += ptMoveCtl.y;
 | 
|---|
| 577 |                                         
 | 
|---|
| 578 |                                 SetWindowPos( hwndChild, 0, rectCtrl.left, rectCtrl.top, 
 | 
|---|
| 579 |                                 rectCtrl.right-rectCtrl.left,rectCtrl.bottom-rectCtrl.top,
 | 
|---|
| 580 |                                 SWP_NOSIZE | SWP_NOZORDER );
 | 
|---|
| 581 |                                 }
 | 
|---|
| 582 |                         }
 | 
|---|
| 583 |                 while ((hwndChild=GetWindow( hwndChild, GW_HWNDNEXT )) != (HWND)NULL);
 | 
|---|
| 584 |         }               
 | 
|---|
| 585 |         hwndChild = GetWindow(hwndParentDlg,GW_CHILD);
 | 
|---|
| 586 |         
 | 
|---|
| 587 |         if(hwndStc32)
 | 
|---|
| 588 |         {
 | 
|---|
| 589 |                 GetWindowRect(hwndStc32,&rectStc32);
 | 
|---|
| 590 |                 MapWindowPoints( 0, hwndChildDlg,(LPPOINT)&rectStc32,2);
 | 
|---|
| 591 |                 ptMoveCtl.x = rectStc32.left - 0;
 | 
|---|
| 592 |                 ptMoveCtl.y = rectStc32.top - 0;
 | 
|---|
| 593 |                 if (hwndChild )
 | 
|---|
| 594 |                 {
 | 
|---|
| 595 |                         do
 | 
|---|
| 596 |                         {
 | 
|---|
| 597 |                                 if(hwndChild != hwndChildDlg)
 | 
|---|
| 598 |                                 {
 | 
|---|
| 599 | 
 | 
|---|
| 600 |                                         if (GetWindowLongA( hwndChild, GWL_STYLE ) & WS_MAXIMIZE)
 | 
|---|
| 601 |                                                 continue;
 | 
|---|
| 602 |                                         GetWindowRect(hwndChild,&rectCtrl);
 | 
|---|
| 603 |                                         MapWindowPoints( 0, hwndParentDlg,(LPPOINT)&rectCtrl,2);
 | 
|---|
| 604 | 
 | 
|---|
| 605 |                                         rectCtrl.left += ptMoveCtl.x;
 | 
|---|
| 606 |                                         rectCtrl.top += ptMoveCtl.y;
 | 
|---|
| 607 | 
 | 
|---|
| 608 |                                         SetWindowPos( hwndChild, 0, rectCtrl.left, rectCtrl.top, 
 | 
|---|
| 609 |                                         rectCtrl.right-rectCtrl.left,rectCtrl.bottom-rectCtrl.top,
 | 
|---|
| 610 |                                         SWP_NOSIZE |SWP_NOZORDER );
 | 
|---|
| 611 |                                 }
 | 
|---|
| 612 |                         }
 | 
|---|
| 613 |                         while ((hwndChild=GetWindow( hwndChild, GW_HWNDNEXT )) != (HWND)NULL);
 | 
|---|
| 614 |                 }               
 | 
|---|
| 615 |         }
 | 
|---|
| 616 | 
 | 
|---|
| 617 | }
 | 
|---|
| 618 | 
 | 
|---|
| 619 | 
 | 
|---|
| 620 | HRESULT WINAPI FileOpenDlgProcUserTemplate(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 621 | {
 | 
|---|
| 622 |     FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(GetParent(hwnd),FileOpenDlgInfosStr);
 | 
|---|
| 623 |   switch(uMsg)
 | 
|---|
| 624 |   {
 | 
|---|
| 625 |         case WM_INITDIALOG:
 | 
|---|
| 626 |         {         
 | 
|---|
| 627 |             fodInfos = (FileOpenDlgInfos *)lParam;
 | 
|---|
| 628 |                 lParam = (LPARAM) fodInfos->ofnInfos;
 | 
|---|
| 629 |                 ArrangeCtrlPositions(hwnd,GetParent(hwnd));
 | 
|---|
| 630 |             if(fodInfos && (fodInfos->ofnInfos->Flags & OFN_ENABLEHOOK) && fodInfos->ofnInfos->lpfnHook)
 | 
|---|
| 631 |                  return CallWindowProcA((WNDPROC)fodInfos->ofnInfos->lpfnHook,hwnd,uMsg,wParam,lParam);
 | 
|---|
| 632 |                 return 0;       
 | 
|---|
| 633 |         } 
 | 
|---|
| 634 |     }
 | 
|---|
| 635 |     if(fodInfos && (fodInfos->ofnInfos->Flags & OFN_ENABLEHOOK) && fodInfos->ofnInfos->lpfnHook )
 | 
|---|
| 636 |         return CallWindowProcA((WNDPROC)fodInfos->ofnInfos->lpfnHook,hwnd,uMsg,wParam,lParam); 
 | 
|---|
| 637 |   return DefWindowProcA(hwnd,uMsg,wParam,lParam); 
 | 
|---|
| 638 | }
 | 
|---|
| 639 | 
 | 
|---|
| 640 | HWND CreateTemplateDialog(FileOpenDlgInfos *fodInfos,HWND hwnd)
 | 
|---|
| 641 | {
 | 
|---|
| 642 |     LPCVOID template;
 | 
|---|
| 643 |     HRSRC hRes;
 | 
|---|
| 644 |     HANDLE hDlgTmpl = 0;
 | 
|---|
| 645 |     HWND hChildDlg = 0;
 | 
|---|
| 646 |    if (fodInfos->ofnInfos->Flags & OFN_ENABLETEMPLATE || fodInfos->ofnInfos->Flags & OFN_ENABLETEMPLATEHANDLE)
 | 
|---|
| 647 |    {
 | 
|---|
| 648 |         if (fodInfos->ofnInfos->Flags  & OFN_ENABLETEMPLATEHANDLE)
 | 
|---|
| 649 |         {
 | 
|---|
| 650 |            if( !(template = LockResource( fodInfos->ofnInfos->hInstance)))
 | 
|---|
| 651 |                 {
 | 
|---|
| 652 |                 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
 | 
|---|
| 653 |                 return (HWND)NULL;
 | 
|---|
| 654 |                 }
 | 
|---|
| 655 |                 
 | 
|---|
| 656 |         }
 | 
|---|
| 657 |         else
 | 
|---|
| 658 |         {
 | 
|---|
| 659 |          if (!(hRes = FindResourceA(MapHModuleSL(fodInfos->ofnInfos->hInstance),
 | 
|---|
| 660 |             (fodInfos->ofnInfos->lpTemplateName), RT_DIALOGA)))
 | 
|---|
| 661 |         {
 | 
|---|
| 662 |                 COMDLG32_SetCommDlgExtendedError(CDERR_FINDRESFAILURE);
 | 
|---|
| 663 |                  return (HWND)NULL;
 | 
|---|
| 664 |         }
 | 
|---|
| 665 |         if (!(hDlgTmpl = LoadResource( MapHModuleSL(fodInfos->ofnInfos->hInstance),
 | 
|---|
| 666 |              hRes )) ||
 | 
|---|
| 667 |                  !(template = LockResource( hDlgTmpl )))
 | 
|---|
| 668 |         {
 | 
|---|
| 669 |                 COMDLG32_SetCommDlgExtendedError(CDERR_LOADRESFAILURE);
 | 
|---|
| 670 |                 return (HWND)NULL;
 | 
|---|
| 671 |         }
 | 
|---|
| 672 |         }
 | 
|---|
| 673 | 
 | 
|---|
| 674 |         hChildDlg= CreateDialogIndirectParamA(fodInfos->ofnInfos->hInstance,template,hwnd,(DLGPROC)FileOpenDlgProcUserTemplate,(LPARAM)fodInfos);
 | 
|---|
| 675 |         if(hChildDlg)
 | 
|---|
| 676 |         {
 | 
|---|
| 677 |                 ShowWindow(hChildDlg,SW_SHOW); 
 | 
|---|
| 678 |                 return hChildDlg;
 | 
|---|
| 679 |         }
 | 
|---|
| 680 |  }
 | 
|---|
| 681 |  else if(fodInfos->ofnInfos->Flags & OFN_ENABLEHOOK && fodInfos->ofnInfos->lpfnHook)
 | 
|---|
| 682 |  {
 | 
|---|
| 683 |         RECT rectHwnd;
 | 
|---|
| 684 |         DLGTEMPLATE tmplate;
 | 
|---|
| 685 |         GetClientRect(hwnd,&rectHwnd);
 | 
|---|
| 686 |         tmplate.style = WS_CHILD | WS_CLIPSIBLINGS;
 | 
|---|
| 687 |         tmplate.dwExtendedStyle = 0;
 | 
|---|
| 688 |         tmplate.cdit = 0;
 | 
|---|
| 689 |         tmplate.x = 0;
 | 
|---|
| 690 |         tmplate.y = 0;
 | 
|---|
| 691 |         tmplate.cx = rectHwnd.right-rectHwnd.left;
 | 
|---|
| 692 |         tmplate.cy = rectHwnd.bottom-rectHwnd.top;
 | 
|---|
| 693 |        
 | 
|---|
| 694 |         return CreateDialogIndirectParamA(fodInfos->ofnInfos->hInstance,&tmplate,hwnd,(DLGPROC)FileOpenDlgProcUserTemplate,(LPARAM)fodInfos);
 | 
|---|
| 695 |  }
 | 
|---|
| 696 | return (HWND)NULL;
 | 
|---|
| 697 | }
 | 
|---|
| 698 |  
 | 
|---|
| 699 | /***********************************************************************
 | 
|---|
| 700 | *          SendCustomDlgNotificationMessage
 | 
|---|
| 701 | *
 | 
|---|
| 702 | * Send CustomDialogNotification (CDN_FIRST -- CDN_LAST) message to the custom template dialog
 | 
|---|
| 703 | */
 | 
|---|
| 704 | 
 | 
|---|
| 705 | HRESULT SendCustomDlgNotificationMessage(HWND hwndParentDlg, UINT uCode)
 | 
|---|
| 706 | {
 | 
|---|
| 707 |     FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwndParentDlg,FileOpenDlgInfosStr);
 | 
|---|
| 708 |     if(!fodInfos)
 | 
|---|
| 709 |         return 0;
 | 
|---|
| 710 |     if(fodInfos->DlgInfos.hwndCustomDlg)
 | 
|---|
| 711 |     {
 | 
|---|
| 712 |         OFNOTIFYA ofnNotify;
 | 
|---|
| 713 |         ofnNotify.hdr.hwndFrom=hwndParentDlg;
 | 
|---|
| 714 |         ofnNotify.hdr.idFrom=0;
 | 
|---|
| 715 |         ofnNotify.hdr.code = uCode;
 | 
|---|
| 716 |         ofnNotify.lpOFN = fodInfos->ofnInfos;
 | 
|---|
| 717 |         return SendMessageA(fodInfos->DlgInfos.hwndCustomDlg,WM_NOTIFY,0,(LPARAM)&ofnNotify);
 | 
|---|
| 718 |     }
 | 
|---|
| 719 |     return TRUE;
 | 
|---|
| 720 | }
 | 
|---|
| 721 | 
 | 
|---|
| 722 | /***********************************************************************
 | 
|---|
| 723 | *         FILEDLG95_HandleCustomDialogMessages
 | 
|---|
| 724 | *
 | 
|---|
| 725 | * Handle Custom Dialog Messages (CDM_FIRST -- CDM_LAST) messages
 | 
|---|
| 726 | */
 | 
|---|
| 727 | HRESULT FILEDLG95_HandleCustomDialogMessages(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 728 | {
 | 
|---|
| 729 |     LPSTR lpstrFileSpec;
 | 
|---|
| 730 |     int reqSize;
 | 
|---|
| 731 |     char lpstrPath[MAX_PATH];
 | 
|---|
| 732 |     FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 733 |     if(!fodInfos) return -1;
 | 
|---|
| 734 | 
 | 
|---|
| 735 |     switch(uMsg)
 | 
|---|
| 736 |     {
 | 
|---|
| 737 |         case CDM_GETFILEPATH:
 | 
|---|
| 738 |             GetDlgItemTextA(hwnd,IDC_FILENAME,lpstrPath, sizeof(lpstrPath));
 | 
|---|
| 739 |             lpstrFileSpec = (LPSTR)COMDLG32_PathFindFileNameA(lpstrPath);
 | 
|---|
| 740 |             if (lpstrFileSpec==lpstrPath) 
 | 
|---|
| 741 |             {
 | 
|---|
| 742 |                 char lpstrCurrentDir[MAX_PATH];
 | 
|---|
| 743 |                 /* Prepend the current path */
 | 
|---|
| 744 |                 COMDLG32_SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent,lpstrCurrentDir);
 | 
|---|
| 745 |                 if ((LPSTR)lParam!=NULL)
 | 
|---|
| 746 |                     wsnprintfA((LPSTR)lParam,(int)wParam,"%s\\%s",lpstrCurrentDir,lpstrPath);
 | 
|---|
| 747 |                 reqSize=strlen(lpstrCurrentDir)+1+strlen(lpstrPath)+1;
 | 
|---|
| 748 |             } 
 | 
|---|
| 749 |             else 
 | 
|---|
| 750 |             {
 | 
|---|
| 751 |                 lstrcpynA((LPSTR)lParam,(LPSTR)lpstrPath,(int)wParam);
 | 
|---|
| 752 |                 reqSize=strlen(lpstrPath);
 | 
|---|
| 753 |             }
 | 
|---|
| 754 |             /* return the required buffer size */
 | 
|---|
| 755 |             return reqSize;
 | 
|---|
| 756 | 
 | 
|---|
| 757 |         case CDM_GETFOLDERPATH:
 | 
|---|
| 758 |             COMDLG32_SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent,lpstrPath);
 | 
|---|
| 759 |             if ((LPSTR)lParam!=NULL)
 | 
|---|
| 760 |                 lstrcpynA((LPSTR)lParam,lpstrPath,(int)wParam);
 | 
|---|
| 761 |             return strlen(lpstrPath);
 | 
|---|
| 762 | 
 | 
|---|
| 763 |         case CDM_GETSPEC:
 | 
|---|
| 764 |             reqSize=GetDlgItemTextA(hwnd,IDC_FILENAME,lpstrPath, sizeof(lpstrPath));
 | 
|---|
| 765 |             lpstrFileSpec = (LPSTR)COMDLG32_PathFindFileNameA(lpstrPath);
 | 
|---|
| 766 |             if ((LPSTR)lParam!=NULL)
 | 
|---|
| 767 |                 lstrcpynA((LPSTR)lParam, lpstrFileSpec, (int)wParam);
 | 
|---|
| 768 |             return strlen(lpstrFileSpec);
 | 
|---|
| 769 | 
 | 
|---|
| 770 |         case CDM_SETCONTROLTEXT:
 | 
|---|
| 771 |             if ( 0 != lParam )
 | 
|---|
| 772 |                 SetDlgItemTextA( hwnd, (UINT) wParam, (LPSTR) lParam );
 | 
|---|
| 773 |             return TRUE;
 | 
|---|
| 774 | 
 | 
|---|
| 775 |         case CDM_HIDECONTROL:
 | 
|---|
| 776 |         case CDM_SETDEFEXT:
 | 
|---|
| 777 |             FIXME("CDM_HIDECONTROL,CDM_SETCONTROLTEXT,CDM_SETDEFEXT not implemented\n");
 | 
|---|
| 778 |             return -1;
 | 
|---|
| 779 |     }
 | 
|---|
| 780 |     return TRUE;
 | 
|---|
| 781 | }
 | 
|---|
| 782 |  
 | 
|---|
| 783 | /***********************************************************************
 | 
|---|
| 784 |  *          FileOpenDlgProc95
 | 
|---|
| 785 |  *
 | 
|---|
| 786 |  * File open dialog procedure
 | 
|---|
| 787 |  */
 | 
|---|
| 788 | HRESULT WINAPI FileOpenDlgProc95(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 789 | {
 | 
|---|
| 790 |   switch(uMsg)
 | 
|---|
| 791 |   {
 | 
|---|
| 792 |     case WM_INITDIALOG:
 | 
|---|
| 793 |          /* Adds the FileOpenDlgInfos in the property list of the dialog 
 | 
|---|
| 794 |             so it will be easily accessible through a GetPropA(...) */
 | 
|---|
| 795 |          SetPropA(hwnd, FileOpenDlgInfosStr, (HANDLE) lParam);
 | 
|---|
| 796 | 
 | 
|---|
| 797 |          FILEDLG95_OnWMInitDialog(hwnd, wParam, lParam);
 | 
|---|
| 798 |          ((FileOpenDlgInfos *)lParam)->DlgInfos.hwndCustomDlg = 
 | 
|---|
| 799 |         CreateTemplateDialog((FileOpenDlgInfos *)lParam,hwnd);
 | 
|---|
| 800 |          SendCustomDlgNotificationMessage(hwnd,CDN_INITDONE);
 | 
|---|
| 801 |          return 0;
 | 
|---|
| 802 |     case WM_COMMAND:
 | 
|---|
| 803 |       return FILEDLG95_OnWMCommand(hwnd, wParam, lParam);
 | 
|---|
| 804 |     case WM_DRAWITEM:
 | 
|---|
| 805 |       {
 | 
|---|
| 806 |         switch(((LPDRAWITEMSTRUCT)lParam)->CtlID)
 | 
|---|
| 807 |         {
 | 
|---|
| 808 |         case IDC_LOOKIN:
 | 
|---|
| 809 |           FILEDLG95_LOOKIN_DrawItem((LPDRAWITEMSTRUCT) lParam);
 | 
|---|
| 810 |           return TRUE;
 | 
|---|
| 811 |         }
 | 
|---|
| 812 |       }
 | 
|---|
| 813 |       return FALSE;
 | 
|---|
| 814 |           
 | 
|---|
| 815 |     case WM_GETISHELLBROWSER:
 | 
|---|
| 816 |       return FILEDLG95_OnWMGetIShellBrowser(hwnd);
 | 
|---|
| 817 | 
 | 
|---|
| 818 |     case WM_DESTROY:
 | 
|---|
| 819 |       RemovePropA(hwnd, FileOpenDlgInfosStr);
 | 
|---|
| 820 |       return FALSE;
 | 
|---|
| 821 | 
 | 
|---|
| 822 |     case WM_NOTIFY:
 | 
|---|
| 823 |     {
 | 
|---|
| 824 |         LPNMHDR lpnmh = (LPNMHDR)lParam;
 | 
|---|
| 825 |         UINT stringId = -1;
 | 
|---|
| 826 | 
 | 
|---|
| 827 |         /* set up the button tooltips strings */
 | 
|---|
| 828 |         if(TTN_GETDISPINFOA == lpnmh->code )
 | 
|---|
| 829 |         {
 | 
|---|
| 830 |             LPNMTTDISPINFOA lpdi = (LPNMTTDISPINFOA)lParam; 
 | 
|---|
| 831 |             switch(lpnmh->idFrom )
 | 
|---|
| 832 |             {
 | 
|---|
| 833 |                 /* Up folder button */
 | 
|---|
| 834 |                 case FCIDM_TB_UPFOLDER:
 | 
|---|
| 835 |                     stringId = IDS_UPFOLDER;
 | 
|---|
| 836 |                     break;
 | 
|---|
| 837 |                 /* New folder button */
 | 
|---|
| 838 |                 case FCIDM_TB_NEWFOLDER:
 | 
|---|
| 839 |                     stringId = IDS_NEWFOLDER;
 | 
|---|
| 840 |                     break;
 | 
|---|
| 841 |                 /* List option button */
 | 
|---|
| 842 |                 case FCIDM_TB_SMALLICON:
 | 
|---|
| 843 |                     stringId = IDS_LISTVIEW;
 | 
|---|
| 844 |                     break;
 | 
|---|
| 845 |                 /* Details option button */
 | 
|---|
| 846 |                 case FCIDM_TB_REPORTVIEW:
 | 
|---|
| 847 |                     stringId = IDS_REPORTVIEW;
 | 
|---|
| 848 |                     break;
 | 
|---|
| 849 |                 /* Desktop button */
 | 
|---|
| 850 |                 case FCIDM_TB_DESKTOP:
 | 
|---|
| 851 |                     stringId = IDS_TODESKTOP;
 | 
|---|
| 852 |                     break;
 | 
|---|
| 853 |                 default:
 | 
|---|
| 854 |                     stringId = 0;
 | 
|---|
| 855 |             }
 | 
|---|
| 856 |             lpdi->hinst = COMMDLG_hInstance32; 
 | 
|---|
| 857 |             lpdi->lpszText =  (LPSTR) stringId;
 | 
|---|
| 858 |         }
 | 
|---|
| 859 |         return FALSE;
 | 
|---|
| 860 |     }
 | 
|---|
| 861 |     default :
 | 
|---|
| 862 |       if(uMsg >= CDM_FIRST && uMsg <= CDM_LAST)
 | 
|---|
| 863 |         return FILEDLG95_HandleCustomDialogMessages(hwnd, uMsg, wParam, lParam);
 | 
|---|
| 864 |       return FALSE;
 | 
|---|
| 865 |   }
 | 
|---|
| 866 | }
 | 
|---|
| 867 | 
 | 
|---|
| 868 | /***********************************************************************
 | 
|---|
| 869 |  *      FILEDLG95_OnWMInitDialog
 | 
|---|
| 870 |  *
 | 
|---|
| 871 |  * WM_INITDIALOG message handler
 | 
|---|
| 872 |  */
 | 
|---|
| 873 | static LRESULT FILEDLG95_OnWMInitDialog(HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 874 | {
 | 
|---|
| 875 |   LPITEMIDLIST pidlItemId;
 | 
|---|
| 876 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) lParam;
 | 
|---|
| 877 | 
 | 
|---|
| 878 |   TRACE("dir=%s file=%s\n", 
 | 
|---|
| 879 |   fodInfos->ofnInfos->lpstrInitialDir, fodInfos->ofnInfos->lpstrFile);
 | 
|---|
| 880 | 
 | 
|---|
| 881 |   /* Get the initial directory pidl */
 | 
|---|
| 882 | 
 | 
|---|
| 883 |   if(!(pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder,fodInfos->ofnInfos->lpstrInitialDir)))
 | 
|---|
| 884 |   {
 | 
|---|
| 885 |     char path[MAX_PATH];
 | 
|---|
| 886 | 
 | 
|---|
| 887 |     GetCurrentDirectoryA(MAX_PATH,path);
 | 
|---|
| 888 |     pidlItemId = GetPidlFromName(fodInfos->Shell.FOIShellFolder, path);
 | 
|---|
| 889 | 
 | 
|---|
| 890 |   }
 | 
|---|
| 891 | 
 | 
|---|
| 892 |   /* Initialise shell objects */
 | 
|---|
| 893 |   FILEDLG95_SHELL_Init(hwnd);
 | 
|---|
| 894 | 
 | 
|---|
| 895 |   /* Initialise dialog UI */
 | 
|---|
| 896 |   FILEDLG95_InitUI(hwnd);
 | 
|---|
| 897 | 
 | 
|---|
| 898 |   /* Initialize the Look In combo box*/
 | 
|---|
| 899 |   FILEDLG95_LOOKIN_Init(fodInfos->DlgInfos.hwndLookInCB);
 | 
|---|
| 900 | 
 | 
|---|
| 901 |   /* Initialize the filter combo box */
 | 
|---|
| 902 |   FILEDLG95_FILETYPE_Init(hwnd);
 | 
|---|
| 903 | 
 | 
|---|
| 904 |   /* Browse to the initial directory */
 | 
|---|
| 905 |   IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,pidlItemId, SBSP_ABSOLUTE);
 | 
|---|
| 906 | 
 | 
|---|
| 907 |   /* Free pidlItem memory */
 | 
|---|
| 908 |   COMDLG32_SHFree(pidlItemId);
 | 
|---|
| 909 | 
 | 
|---|
| 910 |   return TRUE;
 | 
|---|
| 911 | }
 | 
|---|
| 912 | /***********************************************************************
 | 
|---|
| 913 |  *      FILEDLG95_Clean
 | 
|---|
| 914 |  *
 | 
|---|
| 915 |  * Regroups all the cleaning functions of the filedlg
 | 
|---|
| 916 |  */
 | 
|---|
| 917 | void FILEDLG95_Clean(HWND hwnd)
 | 
|---|
| 918 | {
 | 
|---|
| 919 |       FILEDLG95_FILETYPE_Clean(hwnd);
 | 
|---|
| 920 |       FILEDLG95_LOOKIN_Clean(hwnd);
 | 
|---|
| 921 |       FILEDLG95_SHELL_Clean(hwnd);
 | 
|---|
| 922 | }
 | 
|---|
| 923 | /***********************************************************************
 | 
|---|
| 924 |  *      FILEDLG95_OnWMCommand
 | 
|---|
| 925 |  *
 | 
|---|
| 926 |  * WM_COMMAND message handler
 | 
|---|
| 927 |  */
 | 
|---|
| 928 | static LRESULT FILEDLG95_OnWMCommand(HWND hwnd, WPARAM wParam, LPARAM lParam)
 | 
|---|
| 929 | {
 | 
|---|
| 930 |   WORD wNotifyCode = HIWORD(wParam); /* notification code */
 | 
|---|
| 931 |   WORD wID = LOWORD(wParam);         /* item, control, or accelerator identifier */
 | 
|---|
| 932 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 933 | 
 | 
|---|
| 934 |   switch(wID)
 | 
|---|
| 935 |   {
 | 
|---|
| 936 |     /* OK button */
 | 
|---|
| 937 |   case IDOK:
 | 
|---|
| 938 |       if(FILEDLG95_OnOpen(hwnd))
 | 
|---|
| 939 |         SendCustomDlgNotificationMessage(hwnd,CDN_FILEOK);
 | 
|---|
| 940 |     break;
 | 
|---|
| 941 |     /* Cancel button */
 | 
|---|
| 942 |   case IDCANCEL:
 | 
|---|
| 943 |       FILEDLG95_Clean(hwnd);
 | 
|---|
| 944 |       EndDialog(hwnd, FALSE);
 | 
|---|
| 945 |     break;
 | 
|---|
| 946 |     /* Filetype combo box */
 | 
|---|
| 947 |   case IDC_FILETYPE:
 | 
|---|
| 948 |     FILEDLG95_FILETYPE_OnCommand(hwnd,wNotifyCode);
 | 
|---|
| 949 |     break;
 | 
|---|
| 950 |     /* LookIn combo box */
 | 
|---|
| 951 |   case IDC_LOOKIN:
 | 
|---|
| 952 |     FILEDLG95_LOOKIN_OnCommand(hwnd,wNotifyCode);
 | 
|---|
| 953 |     break;
 | 
|---|
| 954 | 
 | 
|---|
| 955 |   /* --- toolbar --- */
 | 
|---|
| 956 |     /* Up folder button */
 | 
|---|
| 957 |   case FCIDM_TB_UPFOLDER:
 | 
|---|
| 958 |     FILEDLG95_SHELL_UpFolder(hwnd);
 | 
|---|
| 959 |     break;
 | 
|---|
| 960 |     /* New folder button */
 | 
|---|
| 961 |   case FCIDM_TB_NEWFOLDER:
 | 
|---|
| 962 |     FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_NEWFOLDER);
 | 
|---|
| 963 |     break;
 | 
|---|
| 964 |     /* List option button */
 | 
|---|
| 965 |   case FCIDM_TB_SMALLICON:
 | 
|---|
| 966 |     FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWLIST);
 | 
|---|
| 967 |     break;
 | 
|---|
| 968 |     /* Details option button */
 | 
|---|
| 969 |   case FCIDM_TB_REPORTVIEW:
 | 
|---|
| 970 |     FILEDLG95_SHELL_ExecuteCommand(hwnd,CMDSTR_VIEWDETAILS);
 | 
|---|
| 971 |     break;
 | 
|---|
| 972 |     /* Details option button */
 | 
|---|
| 973 |   case FCIDM_TB_DESKTOP:
 | 
|---|
| 974 |     FILEDLG95_SHELL_BrowseToDesktop(hwnd);
 | 
|---|
| 975 |     break;
 | 
|---|
| 976 | 
 | 
|---|
| 977 |   case IDC_FILENAME:
 | 
|---|
| 978 |     break;
 | 
|---|
| 979 | 
 | 
|---|
| 980 |   }
 | 
|---|
| 981 |   /* Do not use the listview selection anymore */
 | 
|---|
| 982 |   fodInfos->DlgInfos.dwDlgProp &= ~FODPROP_USEVIEW;
 | 
|---|
| 983 |   return 0; 
 | 
|---|
| 984 | }
 | 
|---|
| 985 | 
 | 
|---|
| 986 | /***********************************************************************
 | 
|---|
| 987 |  *      FILEDLG95_OnWMGetIShellBrowser
 | 
|---|
| 988 |  *
 | 
|---|
| 989 |  * WM_GETISHELLBROWSER message handler
 | 
|---|
| 990 |  */
 | 
|---|
| 991 | static LRESULT FILEDLG95_OnWMGetIShellBrowser(HWND hwnd)
 | 
|---|
| 992 | {
 | 
|---|
| 993 | 
 | 
|---|
| 994 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 995 | 
 | 
|---|
| 996 |   TRACE("\n");
 | 
|---|
| 997 | 
 | 
|---|
| 998 |   SetWindowLongA(hwnd,DWL_MSGRESULT,(LONG)fodInfos->Shell.FOIShellBrowser);
 | 
|---|
| 999 | 
 | 
|---|
| 1000 |   return TRUE; 
 | 
|---|
| 1001 | }
 | 
|---|
| 1002 | 
 | 
|---|
| 1003 | 
 | 
|---|
| 1004 | /***********************************************************************
 | 
|---|
| 1005 |  *      FILEDLG95_InitUI
 | 
|---|
| 1006 |  *
 | 
|---|
| 1007 |  */
 | 
|---|
| 1008 | static LRESULT FILEDLG95_InitUI(HWND hwnd)
 | 
|---|
| 1009 | {
 | 
|---|
| 1010 |   TBBUTTON tbb[] =
 | 
|---|
| 1011 |   {
 | 
|---|
| 1012 |    {0,                 0,                   TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0 },
 | 
|---|
| 1013 |    {VIEW_PARENTFOLDER, FCIDM_TB_UPFOLDER,   TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
 | 
|---|
| 1014 |    {0,                 0,                   TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0 },
 | 
|---|
| 1015 |    {VIEW_NEWFOLDER+1,  FCIDM_TB_DESKTOP,    TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
 | 
|---|
| 1016 |    {0,                 0,                   TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0 },
 | 
|---|
| 1017 |    {VIEW_NEWFOLDER,    FCIDM_TB_NEWFOLDER,  TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
 | 
|---|
| 1018 |    {0,                 0,                   TBSTATE_ENABLED, TBSTYLE_SEP, {0, 0}, 0, 0 },
 | 
|---|
| 1019 |    {VIEW_LIST,         FCIDM_TB_SMALLICON,  TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
 | 
|---|
| 1020 |    {VIEW_DETAILS,      FCIDM_TB_REPORTVIEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0, 0}, 0, 0 },
 | 
|---|
| 1021 |   };
 | 
|---|
| 1022 |   TBADDBITMAP tba[] =
 | 
|---|
| 1023 |   {
 | 
|---|
| 1024 |    { HINST_COMMCTRL, IDB_VIEW_SMALL_COLOR },
 | 
|---|
| 1025 |    { COMDLG32_hInstance, 800 }                  // desktop icon
 | 
|---|
| 1026 |   };
 | 
|---|
| 1027 |   
 | 
|---|
| 1028 |   RECT rectTB;
 | 
|---|
| 1029 |   
 | 
|---|
| 1030 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1031 | 
 | 
|---|
| 1032 |   TRACE("%p\n", fodInfos);
 | 
|---|
| 1033 | 
 | 
|---|
| 1034 |   /* Get the hwnd of the controls */
 | 
|---|
| 1035 |   fodInfos->DlgInfos.hwndFileName = GetDlgItem(hwnd,IDC_FILENAME);
 | 
|---|
| 1036 |   fodInfos->DlgInfos.hwndFileTypeCB = GetDlgItem(hwnd,IDC_FILETYPE);
 | 
|---|
| 1037 |   fodInfos->DlgInfos.hwndLookInCB = GetDlgItem(hwnd,IDC_LOOKIN);
 | 
|---|
| 1038 | 
 | 
|---|
| 1039 |   /* construct the toolbar */
 | 
|---|
| 1040 |   GetWindowRect(GetDlgItem(hwnd,IDC_TOOLBARSTATIC),&rectTB);
 | 
|---|
| 1041 |   MapWindowPoints( 0, hwnd,(LPPOINT)&rectTB,2);
 | 
|---|
| 1042 | 
 | 
|---|
| 1043 |   fodInfos->DlgInfos.hwndTB = CreateWindowExA(0, TOOLBARCLASSNAMEA, (LPSTR) NULL, 
 | 
|---|
| 1044 |         WS_CHILD | WS_GROUP | TBSTYLE_TOOLTIPS | CCS_NODIVIDER | CCS_NORESIZE,
 | 
|---|
| 1045 |         0, 0, 150, 26,
 | 
|---|
| 1046 |         hwnd, (HMENU) IDC_TOOLBAR, COMMDLG_hInstance32, NULL); 
 | 
|---|
| 1047 |  
 | 
|---|
| 1048 |   SetWindowPos(fodInfos->DlgInfos.hwndTB, 0, 
 | 
|---|
| 1049 |         rectTB.left,rectTB.top, rectTB.right-rectTB.left, rectTB.bottom-rectTB.top,
 | 
|---|
| 1050 |         SWP_SHOWWINDOW | SWP_NOACTIVATE | SWP_NOZORDER );
 | 
|---|
| 1051 | 
 | 
|---|
| 1052 |   SendMessageA(fodInfos->DlgInfos.hwndTB, TB_BUTTONSTRUCTSIZE, (WPARAM) sizeof(TBBUTTON), 0);
 | 
|---|
| 1053 | 
 | 
|---|
| 1054 | /* fixme: use TB_LOADIMAGES when implemented */
 | 
|---|
| 1055 | /*  SendMessageA(fodInfos->DlgInfos.hwndTB, TB_LOADIMAGES, (WPARAM) IDB_VIEW_SMALL_COLOR, HINST_COMMCTRL);*/
 | 
|---|
| 1056 |   SendMessageA(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, (WPARAM) 12, (LPARAM) &tba[0]);
 | 
|---|
| 1057 |   SendMessageA(fodInfos->DlgInfos.hwndTB, TB_ADDBITMAP, (WPARAM) 1, (LPARAM) &tba[1]);
 | 
|---|
| 1058 | 
 | 
|---|
| 1059 |   SendMessageA(fodInfos->DlgInfos.hwndTB, TB_ADDBUTTONSA, (WPARAM) 9,(LPARAM) &tbb);
 | 
|---|
| 1060 |   SendMessageA(fodInfos->DlgInfos.hwndTB, TB_AUTOSIZE, 0, 0); 
 | 
|---|
| 1061 | 
 | 
|---|
| 1062 |   /* Set the window text with the text specified in the OPENFILENAME structure */
 | 
|---|
| 1063 |   if(fodInfos->ofnInfos->lpstrTitle)
 | 
|---|
| 1064 |   {
 | 
|---|
| 1065 |       SetWindowTextA(hwnd,fodInfos->ofnInfos->lpstrTitle);
 | 
|---|
| 1066 |   }
 | 
|---|
| 1067 |   else if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
 | 
|---|
| 1068 |   {
 | 
|---|
| 1069 |       SetWindowTextA(hwnd,"Save");
 | 
|---|
| 1070 |   }
 | 
|---|
| 1071 | 
 | 
|---|
| 1072 |   /* Initialise the file name edit control */
 | 
|---|
| 1073 |   if(fodInfos->ofnInfos->lpstrFile)
 | 
|---|
| 1074 |   {
 | 
|---|
| 1075 |       LPSTR lpstrFile = COMDLG32_PathFindFileNameA(fodInfos->ofnInfos->lpstrFile);
 | 
|---|
| 1076 |       SetDlgItemTextA(hwnd, IDC_FILENAME, lpstrFile);
 | 
|---|
| 1077 |   }
 | 
|---|
| 1078 | 
 | 
|---|
| 1079 |   /* Must the open as read only check box be checked ?*/
 | 
|---|
| 1080 |   if(fodInfos->ofnInfos->Flags & OFN_READONLY)
 | 
|---|
| 1081 |   {
 | 
|---|
| 1082 |     SendDlgItemMessageA(hwnd,IDC_OPENREADONLY,BM_SETCHECK,(WPARAM)TRUE,0);
 | 
|---|
| 1083 |   }
 | 
|---|
| 1084 | 
 | 
|---|
| 1085 |   /* Must the open as read only check box be hid ?*/
 | 
|---|
| 1086 |   if(fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY)
 | 
|---|
| 1087 |   {
 | 
|---|
| 1088 |     ShowWindow(GetDlgItem(hwnd,IDC_OPENREADONLY),SW_HIDE);
 | 
|---|
| 1089 |   }
 | 
|---|
| 1090 | 
 | 
|---|
| 1091 |   /* Must the help button be hid ?*/
 | 
|---|
| 1092 |   if (!(fodInfos->ofnInfos->Flags & OFN_SHOWHELP))
 | 
|---|
| 1093 |   {
 | 
|---|
| 1094 |     ShowWindow(GetDlgItem(hwnd, pshHelp), SW_HIDE);
 | 
|---|
| 1095 |   }
 | 
|---|
| 1096 | 
 | 
|---|
| 1097 |   /* Resize the height, if open as read only checkbox ad help button
 | 
|---|
| 1098 |      are hidden */
 | 
|---|
| 1099 |   if ( (fodInfos->ofnInfos->Flags & OFN_HIDEREADONLY) &&
 | 
|---|
| 1100 |        (!(fodInfos->ofnInfos->Flags & OFN_SHOWHELP)) )
 | 
|---|
| 1101 |   {
 | 
|---|
| 1102 |     RECT rectDlg, rectHelp, rectCancel;
 | 
|---|
| 1103 |     GetWindowRect(hwnd, &rectDlg);
 | 
|---|
| 1104 |     GetWindowRect(GetDlgItem(hwnd, pshHelp), &rectHelp);
 | 
|---|
| 1105 |     GetWindowRect(GetDlgItem(hwnd, IDCANCEL), &rectCancel);
 | 
|---|
| 1106 |     /* subtract the height of the help button plus the space between
 | 
|---|
| 1107 |        the help button and the cancel button to the height of the dialog */
 | 
|---|
| 1108 |     SetWindowPos(hwnd, 0, 0, 0, rectDlg.right-rectDlg.left, 
 | 
|---|
| 1109 |                  (rectDlg.bottom-rectDlg.top) - (rectHelp.bottom - rectCancel.bottom), 
 | 
|---|
| 1110 |                  SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOZORDER);
 | 
|---|
| 1111 |   }
 | 
|---|
| 1112 | 
 | 
|---|
| 1113 |   /* change Open to Save FIXME: use resources */
 | 
|---|
| 1114 |   if (fodInfos->DlgInfos.dwDlgProp & FODPROP_SAVEDLG)
 | 
|---|
| 1115 |   {
 | 
|---|
| 1116 |       SetDlgItemTextA(hwnd,IDOK,"&Save");
 | 
|---|
| 1117 |       SetDlgItemTextA(hwnd,IDC_LOOKINSTATIC,"Save &in");
 | 
|---|
| 1118 |   }
 | 
|---|
| 1119 |   return 0;
 | 
|---|
| 1120 | }
 | 
|---|
| 1121 | 
 | 
|---|
| 1122 | /***********************************************************************
 | 
|---|
| 1123 |  *      FILEDLG95_OnOpenMultipleFiles
 | 
|---|
| 1124 |  *      
 | 
|---|
| 1125 |  * Handles the opening of multiple files.
 | 
|---|
| 1126 |  *
 | 
|---|
| 1127 |  * FIXME
 | 
|---|
| 1128 |  *  check destination buffer size
 | 
|---|
| 1129 |  */
 | 
|---|
| 1130 | BOOL FILEDLG95_OnOpenMultipleFiles(HWND hwnd, LPSTR lpstrFileList, UINT nFileCount, UINT sizeUsed)
 | 
|---|
| 1131 | {
 | 
|---|
| 1132 |   CHAR   lpstrPathSpec[MAX_PATH] = "";
 | 
|---|
| 1133 |   LPSTR  lpstrFile;
 | 
|---|
| 1134 |   UINT   nCount, nSizePath;
 | 
|---|
| 1135 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1136 | 
 | 
|---|
| 1137 |   TRACE("\n");
 | 
|---|
| 1138 | 
 | 
|---|
| 1139 |   lpstrFile = fodInfos->ofnInfos->lpstrFile;
 | 
|---|
| 1140 |   lpstrFile[0] = '\0';
 | 
|---|
| 1141 |   
 | 
|---|
| 1142 |   COMDLG32_SHGetPathFromIDListA( fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathSpec );
 | 
|---|
| 1143 | 
 | 
|---|
| 1144 |   if ( !(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE) &&
 | 
|---|
| 1145 |       ( fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST))
 | 
|---|
| 1146 |   {
 | 
|---|
| 1147 |     LPSTR lpstrTemp = lpstrFileList; 
 | 
|---|
| 1148 | 
 | 
|---|
| 1149 |     for ( nCount = 0; nCount < nFileCount; nCount++ )
 | 
|---|
| 1150 |     {
 | 
|---|
| 1151 |       LPITEMIDLIST pidl;
 | 
|---|
| 1152 | 
 | 
|---|
| 1153 |       pidl = GetPidlFromName(fodInfos->Shell.FOIShellFolder, lpstrTemp);
 | 
|---|
| 1154 |       if (!pidl)
 | 
|---|
| 1155 |       {
 | 
|---|
| 1156 |         CHAR lpstrNotFound[100];
 | 
|---|
| 1157 |         CHAR lpstrMsg[100];
 | 
|---|
| 1158 |         CHAR tmp[400];
 | 
|---|
| 1159 | 
 | 
|---|
| 1160 |         LoadStringA(COMMDLG_hInstance32, IDS_FILENOTFOUND, lpstrNotFound, 100);
 | 
|---|
| 1161 |         LoadStringA(COMMDLG_hInstance32, IDS_VERIFYFILE, lpstrMsg, 100);
 | 
|---|
| 1162 | 
 | 
|---|
| 1163 |         strcpy(tmp, lpstrTemp);
 | 
|---|
| 1164 |         strcat(tmp, "\n");
 | 
|---|
| 1165 |         strcat(tmp, lpstrNotFound);
 | 
|---|
| 1166 |         strcat(tmp, "\n");
 | 
|---|
| 1167 |         strcat(tmp, lpstrMsg);
 | 
|---|
| 1168 | 
 | 
|---|
| 1169 |         MessageBoxA(hwnd, tmp, fodInfos->ofnInfos->lpstrTitle, MB_OK | MB_ICONEXCLAMATION);
 | 
|---|
| 1170 |         return FALSE;
 | 
|---|
| 1171 |       }
 | 
|---|
| 1172 |   
 | 
|---|
| 1173 |       lpstrTemp += strlen(lpstrFileList) + 1;
 | 
|---|
| 1174 |       COMDLG32_SHFree(pidl);
 | 
|---|
| 1175 |     }
 | 
|---|
| 1176 |   }
 | 
|---|
| 1177 | 
 | 
|---|
| 1178 |   nSizePath = strlen(lpstrPathSpec);
 | 
|---|
| 1179 |   strcpy( lpstrFile, lpstrPathSpec);
 | 
|---|
| 1180 |   memcpy( lpstrFile + nSizePath + 1, lpstrFileList, sizeUsed );
 | 
|---|
| 1181 | 
 | 
|---|
| 1182 |   fodInfos->ofnInfos->nFileOffset = nSizePath + 1;
 | 
|---|
| 1183 |   fodInfos->ofnInfos->nFileExtension = 0;
 | 
|---|
| 1184 | 
 | 
|---|
| 1185 |   /* clean and exit */
 | 
|---|
| 1186 |   FILEDLG95_Clean(hwnd);
 | 
|---|
| 1187 |   return EndDialog(hwnd,TRUE);
 | 
|---|
| 1188 | }
 | 
|---|
| 1189 | 
 | 
|---|
| 1190 | /***********************************************************************
 | 
|---|
| 1191 |  *      FILEDLG95_OnOpen
 | 
|---|
| 1192 |  *
 | 
|---|
| 1193 |  * Ok button WM_COMMAND message handler
 | 
|---|
| 1194 |  * 
 | 
|---|
| 1195 |  * If the function succeeds, the return value is nonzero.
 | 
|---|
| 1196 |  */
 | 
|---|
| 1197 | #define ONOPEN_BROWSE 1
 | 
|---|
| 1198 | #define ONOPEN_OPEN   2
 | 
|---|
| 1199 | #define ONOPEN_SEARCH 3
 | 
|---|
| 1200 | static void FILEDLG95_OnOpenMessage(HWND hwnd, int idCaption, int idText)
 | 
|---|
| 1201 | {
 | 
|---|
| 1202 |   char strMsgTitle[MAX_PATH];
 | 
|---|
| 1203 |   char strMsgText [MAX_PATH];
 | 
|---|
| 1204 |   if (idCaption)
 | 
|---|
| 1205 |     LoadStringA(COMDLG32_hInstance, idCaption, strMsgTitle, sizeof(strMsgTitle));
 | 
|---|
| 1206 |   else
 | 
|---|
| 1207 |     strMsgTitle[0] = '\0';
 | 
|---|
| 1208 |   LoadStringA(COMDLG32_hInstance, idText, strMsgText, sizeof(strMsgText));
 | 
|---|
| 1209 |   MessageBoxA(hwnd,strMsgText, strMsgTitle, MB_OK | MB_ICONHAND);
 | 
|---|
| 1210 | }
 | 
|---|
| 1211 | 
 | 
|---|
| 1212 | BOOL FILEDLG95_OnOpen(HWND hwnd)
 | 
|---|
| 1213 | {
 | 
|---|
| 1214 |   char * lpstrFileList;
 | 
|---|
| 1215 |   UINT nFileCount = 0;
 | 
|---|
| 1216 |   UINT sizeUsed = 0;
 | 
|---|
| 1217 |   BOOL ret = TRUE;
 | 
|---|
| 1218 |   char lpstrPathAndFile[MAX_PATH];
 | 
|---|
| 1219 |   char lpstrTemp[MAX_PATH];
 | 
|---|
| 1220 |   LPSHELLFOLDER lpsf = NULL;
 | 
|---|
| 1221 |   int nOpenAction;
 | 
|---|
| 1222 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1223 | 
 | 
|---|
| 1224 |   TRACE("hwnd=0x%04x\n", hwnd);
 | 
|---|
| 1225 | 
 | 
|---|
| 1226 |   /* get the files from the edit control */
 | 
|---|
| 1227 |   nFileCount = FILEDLG95_FILENAME_GetFileNames(hwnd, &lpstrFileList, &sizeUsed);
 | 
|---|
| 1228 | 
 | 
|---|
| 1229 |   /* try if the user selected a folder in the shellview */
 | 
|---|
| 1230 |   if(nFileCount == 0)
 | 
|---|
| 1231 |   {
 | 
|---|
| 1232 |       BrowseSelectedFolder(hwnd);
 | 
|---|
| 1233 |       return FALSE;
 | 
|---|
| 1234 |   }
 | 
|---|
| 1235 |  
 | 
|---|
| 1236 |   if(nFileCount > 1)
 | 
|---|
| 1237 |   {
 | 
|---|
| 1238 |       ret = FILEDLG95_OnOpenMultipleFiles(hwnd, lpstrFileList, nFileCount, sizeUsed);
 | 
|---|
| 1239 |       goto ret;
 | 
|---|
| 1240 |   }
 | 
|---|
| 1241 | 
 | 
|---|
| 1242 |   TRACE("count=%u len=%u file=%s\n", nFileCount, sizeUsed, lpstrFileList);
 | 
|---|
| 1243 | 
 | 
|---|
| 1244 | /*
 | 
|---|
| 1245 |   Step 1:  Build a complete path name from the current folder and
 | 
|---|
| 1246 |   the filename or path in the edit box.
 | 
|---|
| 1247 |   Special cases:
 | 
|---|
| 1248 |   - the path in the edit box is a root path
 | 
|---|
| 1249 |     (with or without drive letter)
 | 
|---|
| 1250 |   - the edit box contains ".." (or a path with ".." in it)
 | 
|---|
| 1251 | */
 | 
|---|
| 1252 | 
 | 
|---|
| 1253 |   /* Get the current directory name */
 | 
|---|
| 1254 |   if (!COMDLG32_SHGetPathFromIDListA(fodInfos->ShellInfos.pidlAbsCurrent, lpstrPathAndFile))
 | 
|---|
| 1255 |   {
 | 
|---|
| 1256 |     /* we are in a special folder, default to desktop */
 | 
|---|
| 1257 |     if(FAILED(COMDLG32_SHGetFolderPathA(hwnd, CSIDL_DESKTOPDIRECTORY|CSIDL_FLAG_CREATE, NULL, 0, lpstrPathAndFile)))
 | 
|---|
| 1258 |     {
 | 
|---|
| 1259 |       /* last fallback */
 | 
|---|
| 1260 |       GetCurrentDirectoryA(MAX_PATH, lpstrPathAndFile);
 | 
|---|
| 1261 |     }
 | 
|---|
| 1262 |   }
 | 
|---|
| 1263 |   COMDLG32_PathAddBackslashA(lpstrPathAndFile);
 | 
|---|
| 1264 | 
 | 
|---|
| 1265 |   TRACE("current directory=%s\n", lpstrPathAndFile);
 | 
|---|
| 1266 | 
 | 
|---|
| 1267 |   /* if the user specifyed a fully qualified path use it */
 | 
|---|
| 1268 |   if(COMDLG32_PathIsRelativeA(lpstrFileList))
 | 
|---|
| 1269 |   {
 | 
|---|
| 1270 |     strcat(lpstrPathAndFile, lpstrFileList);
 | 
|---|
| 1271 |   }
 | 
|---|
| 1272 |   else
 | 
|---|
| 1273 |   {
 | 
|---|
| 1274 |     /* does the path have a drive letter? */
 | 
|---|
| 1275 |     if (COMDLG32_PathGetDriveNumberA(lpstrFileList) == -1)
 | 
|---|
| 1276 |       strcpy(lpstrPathAndFile+2, lpstrFileList);
 | 
|---|
| 1277 |     else
 | 
|---|
| 1278 |       strcpy(lpstrPathAndFile, lpstrFileList);
 | 
|---|
| 1279 |   }
 | 
|---|
| 1280 | 
 | 
|---|
| 1281 |   /* resolve "." and ".." */
 | 
|---|
| 1282 |   COMDLG32_PathCanonicalizeA(lpstrTemp, lpstrPathAndFile );
 | 
|---|
| 1283 |   strcpy(lpstrPathAndFile, lpstrTemp);
 | 
|---|
| 1284 |   TRACE("canon=%s\n", lpstrPathAndFile);
 | 
|---|
| 1285 | 
 | 
|---|
| 1286 |   MemFree(lpstrFileList);
 | 
|---|
| 1287 | 
 | 
|---|
| 1288 | /*
 | 
|---|
| 1289 |   Step 2: here we have a cleaned up path
 | 
|---|
| 1290 | 
 | 
|---|
| 1291 |   We have to parse the path step by step to see if we have to browse
 | 
|---|
| 1292 |   to a folder if the path points to a directory or the last
 | 
|---|
| 1293 |   valid element is a directory.
 | 
|---|
| 1294 |   
 | 
|---|
| 1295 |   valid variables:
 | 
|---|
| 1296 |     lpstrPathAndFile: cleaned up path
 | 
|---|
| 1297 |  */
 | 
|---|
| 1298 | 
 | 
|---|
| 1299 |   nOpenAction = ONOPEN_BROWSE;
 | 
|---|
| 1300 | 
 | 
|---|
| 1301 |   /* dont apply any checks with OFN_NOVALIDATE */
 | 
|---|
| 1302 |   if(!(fodInfos->ofnInfos->Flags & OFN_NOVALIDATE))
 | 
|---|
| 1303 |   {
 | 
|---|
| 1304 |     LPSTR lpszTemp, lpszTemp1;
 | 
|---|
| 1305 |     LPITEMIDLIST pidl = NULL;
 | 
|---|
| 1306 | 
 | 
|---|
| 1307 |     /* check for invalid chars */
 | 
|---|
| 1308 |     if(strpbrk(lpstrPathAndFile+3, "/:<>|") != NULL)
 | 
|---|
| 1309 |     {
 | 
|---|
| 1310 |       FILEDLG95_OnOpenMessage(hwnd, IDS_INVALID_FILENAME_TITLE, IDS_INVALID_FILENAME);
 | 
|---|
| 1311 |       ret = FALSE;
 | 
|---|
| 1312 |       goto ret;
 | 
|---|
| 1313 |     }
 | 
|---|
| 1314 | 
 | 
|---|
| 1315 |     if (FAILED (COMDLG32_SHGetDesktopFolder(&lpsf))) return FALSE;
 | 
|---|
| 1316 |   
 | 
|---|
| 1317 |     lpszTemp1 = lpszTemp = lpstrPathAndFile;
 | 
|---|
| 1318 |     while (lpszTemp1)
 | 
|---|
| 1319 |     {
 | 
|---|
| 1320 |       LPSHELLFOLDER lpsfChild;
 | 
|---|
| 1321 |       WCHAR lpwstrTemp[MAX_PATH];
 | 
|---|
| 1322 |       DWORD dwEaten, dwAttributes;
 | 
|---|
| 1323 | 
 | 
|---|
| 1324 |       lpszTemp = COMDLG32_PathFindNextComponentA(lpszTemp);
 | 
|---|
| 1325 |       if (*lpszTemp)
 | 
|---|
| 1326 |         lstrcpynAtoW(lpwstrTemp, lpszTemp1, lpszTemp - lpszTemp1);
 | 
|---|
| 1327 |       else
 | 
|---|
| 1328 |       {
 | 
|---|
| 1329 |         lstrcpyAtoW(lpwstrTemp, lpszTemp1);     /* last element */
 | 
|---|
| 1330 |         if(strpbrk(lpszTemp1, "*?") != NULL)
 | 
|---|
| 1331 |         {
 | 
|---|
| 1332 |           nOpenAction = ONOPEN_SEARCH;
 | 
|---|
| 1333 |           break;
 | 
|---|
| 1334 |         }
 | 
|---|
| 1335 |       }
 | 
|---|
| 1336 |       lpszTemp1 = lpszTemp;
 | 
|---|
| 1337 | 
 | 
|---|
| 1338 |       TRACE("parse now=%s next=%s sf=%p\n",debugstr_w(lpwstrTemp), debugstr_a(lpszTemp), lpsf);
 | 
|---|
| 1339 | 
 | 
|---|
| 1340 |       if(lstrlenW(lpwstrTemp)==2) COMDLG32_PathAddBackslashW(lpwstrTemp);
 | 
|---|
| 1341 | 
 | 
|---|
| 1342 |       dwAttributes = SFGAO_FOLDER;
 | 
|---|
| 1343 |       if(FAILED(IShellFolder_ParseDisplayName(lpsf, hwnd, NULL, lpwstrTemp, &dwEaten, &pidl, &dwAttributes)))
 | 
|---|
| 1344 |       {
 | 
|---|
| 1345 |         if(*lpszTemp)   /* points to trailing null for last path element */
 | 
|---|
| 1346 |         {
 | 
|---|
| 1347 |           if(fodInfos->ofnInfos->Flags & OFN_PATHMUSTEXIST)
 | 
|---|
| 1348 |           {
 | 
|---|
| 1349 |             FILEDLG95_OnOpenMessage(hwnd, 0, IDS_PATHNOTEXISTING);
 | 
|---|
| 1350 |             break;
 | 
|---|
| 1351 |           }
 | 
|---|
| 1352 |         }
 | 
|---|
| 1353 |         else
 | 
|---|
| 1354 |         {
 | 
|---|
| 1355 |           if(fodInfos->ofnInfos->Flags & OFN_FILEMUSTEXIST)
 | 
|---|
| 1356 |           {
 | 
|---|
| 1357 |             FILEDLG95_OnOpenMessage(hwnd, 0, IDS_FILENOTEXISTING);
 | 
|---|
| 1358 |             break;
 | 
|---|
| 1359 |           }
 | 
|---|
| 1360 |         }
 | 
|---|
| 1361 |         /* change to the current folder */
 | 
|---|
| 1362 |         nOpenAction = ONOPEN_OPEN;
 | 
|---|
| 1363 |         break;
 | 
|---|
| 1364 |       }
 | 
|---|
| 1365 |       else
 | 
|---|
| 1366 |       {
 | 
|---|
| 1367 |         /* the path component is valid */
 | 
|---|
| 1368 |         TRACE("parse OK attr=0x%08lx pidl=%p\n", dwAttributes, pidl);
 | 
|---|
| 1369 |         if(dwAttributes & SFGAO_FOLDER)
 | 
|---|
| 1370 |         {
 | 
|---|
| 1371 |           if(FAILED(IShellFolder_BindToObject(lpsf, pidl, 0, &IID_IShellFolder, (LPVOID*)&lpsfChild)))
 | 
|---|
| 1372 |           {
 | 
|---|
| 1373 |             ERR("bind to failed\n"); /* should not fail */
 | 
|---|
| 1374 |             break;
 | 
|---|
| 1375 |           }
 | 
|---|
| 1376 |           IShellFolder_Release(lpsf);
 | 
|---|
| 1377 |           lpsf = lpsfChild;
 | 
|---|
| 1378 |           lpsfChild = NULL;
 | 
|---|
| 1379 |         }
 | 
|---|
| 1380 |         else
 | 
|---|
| 1381 |         {
 | 
|---|
| 1382 |           TRACE("value\n");
 | 
|---|
| 1383 | 
 | 
|---|
| 1384 |           /* end dialog, return value */
 | 
|---|
| 1385 |           nOpenAction = ONOPEN_OPEN;
 | 
|---|
| 1386 |           break;
 | 
|---|
| 1387 |         }
 | 
|---|
| 1388 |         COMDLG32_SHFree(pidl);
 | 
|---|
| 1389 |         pidl = NULL;
 | 
|---|
| 1390 |       }
 | 
|---|
| 1391 |     }
 | 
|---|
| 1392 |     if(pidl) COMDLG32_SHFree(pidl);
 | 
|---|
| 1393 |   }
 | 
|---|
| 1394 | 
 | 
|---|
| 1395 |   /* path is valid, clean the edit box */
 | 
|---|
| 1396 |   SetDlgItemTextA(hwnd,IDC_FILENAME,"");
 | 
|---|
| 1397 | 
 | 
|---|
| 1398 | /*
 | 
|---|
| 1399 |   Step 3: here we have a cleaned up and validated path
 | 
|---|
| 1400 | 
 | 
|---|
| 1401 |   valid variables:
 | 
|---|
| 1402 |    lpsf:             ShellFolder bound to the rightmost valid path component
 | 
|---|
| 1403 |    lpstrPathAndFile: cleaned up path
 | 
|---|
| 1404 |    nOpenAction:      action to do
 | 
|---|
| 1405 | */
 | 
|---|
| 1406 |   TRACE("end validate sf=%p\n", lpsf);
 | 
|---|
| 1407 | 
 | 
|---|
| 1408 |   switch(nOpenAction)
 | 
|---|
| 1409 |   {
 | 
|---|
| 1410 |     case ONOPEN_SEARCH:   /* set the current filter to the file mask and refresh */
 | 
|---|
| 1411 |       TRACE("ONOPEN_SEARCH %s\n", lpstrPathAndFile);
 | 
|---|
| 1412 |       {
 | 
|---|
| 1413 |         int iPos;
 | 
|---|
| 1414 |         LPSTR lpszTemp = COMDLG32_PathFindFileNameA(lpstrPathAndFile);
 | 
|---|
| 1415 | 
 | 
|---|
| 1416 |         /* replace the current filter */
 | 
|---|
| 1417 |         if(fodInfos->ShellInfos.lpstrCurrentFilter)
 | 
|---|
| 1418 |           MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
 | 
|---|
| 1419 |         fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc((strlen(lpszTemp)+1)*sizeof(WCHAR));
 | 
|---|
| 1420 |         lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter, lpszTemp);
 | 
|---|
| 1421 | 
 | 
|---|
| 1422 |         /* set the filter cb to the extension when possible */
 | 
|---|
| 1423 |         if(-1 < (iPos = FILEDLG95_FILETYPE_SearchExt(fodInfos->DlgInfos.hwndFileTypeCB, lpszTemp)))
 | 
|---|
| 1424 |         CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB, iPos);
 | 
|---|
| 1425 |       }
 | 
|---|
| 1426 |       /* fall through */
 | 
|---|
| 1427 |     case ONOPEN_BROWSE:   /* browse to the highest folder we could bind to */
 | 
|---|
| 1428 |       TRACE("ONOPEN_BROWSE\n");
 | 
|---|
| 1429 |       {
 | 
|---|
| 1430 |         IPersistFolder2 * ppf2;
 | 
|---|
| 1431 |         if(SUCCEEDED(IShellFolder_QueryInterface( lpsf, &IID_IPersistFolder2, (LPVOID*)&ppf2)))
 | 
|---|
| 1432 |         {
 | 
|---|
| 1433 |           LPITEMIDLIST pidlCurrent;
 | 
|---|
| 1434 |           IPersistFolder2_GetCurFolder(ppf2, &pidlCurrent);
 | 
|---|
| 1435 |           IPersistFolder2_Release(ppf2);
 | 
|---|
| 1436 |           if( ! COMDLG32_PIDL_ILIsEqual(pidlCurrent, fodInfos->ShellInfos.pidlAbsCurrent))
 | 
|---|
| 1437 |           {
 | 
|---|
| 1438 |             IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidlCurrent, SBSP_ABSOLUTE);
 | 
|---|
| 1439 |           }
 | 
|---|
| 1440 |           else if( nOpenAction == ONOPEN_SEARCH )
 | 
|---|
| 1441 |           {
 | 
|---|
| 1442 |             IShellView_Refresh(fodInfos->Shell.FOIShellView);
 | 
|---|
| 1443 |           }
 | 
|---|
| 1444 |           COMDLG32_SHFree(pidlCurrent);
 | 
|---|
| 1445 |         }
 | 
|---|
| 1446 |       }
 | 
|---|
| 1447 |       ret = FALSE;
 | 
|---|
| 1448 |       break;
 | 
|---|
| 1449 |     case ONOPEN_OPEN:   /* fill in the return struct and close the dialog */
 | 
|---|
| 1450 |       TRACE("ONOPEN_OPEN %s\n", lpstrPathAndFile);
 | 
|---|
| 1451 |       {
 | 
|---|
| 1452 |         /* add default extension */
 | 
|---|
| 1453 |         if (fodInfos->ofnInfos->lpstrDefExt)
 | 
|---|
| 1454 |         {
 | 
|---|
| 1455 |           if (! *COMDLG32_PathFindExtensionA(lpstrPathAndFile))
 | 
|---|
| 1456 |           {
 | 
|---|
| 1457 |             strcat(lpstrPathAndFile, ".");
 | 
|---|
| 1458 |             strcat(lpstrPathAndFile, fodInfos->ofnInfos->lpstrDefExt);
 | 
|---|
| 1459 |           }
 | 
|---|
| 1460 |         }
 | 
|---|
| 1461 | 
 | 
|---|
| 1462 |         /* Check that size size of the file does not exceed buffer size */
 | 
|---|
| 1463 |         if(strlen(lpstrPathAndFile) < fodInfos->ofnInfos->nMaxFile)
 | 
|---|
| 1464 |         {
 | 
|---|
| 1465 |           LPSTR lpszTemp;
 | 
|---|
| 1466 |           
 | 
|---|
| 1467 |           /* fill destination buffer */
 | 
|---|
| 1468 |           strcpy(fodInfos->ofnInfos->lpstrFile, lpstrPathAndFile);
 | 
|---|
| 1469 | 
 | 
|---|
| 1470 |           /* set filename offset */
 | 
|---|
| 1471 |           lpszTemp = COMDLG32_PathFindFileNameA(lpstrPathAndFile);
 | 
|---|
| 1472 |           fodInfos->ofnInfos->nFileOffset = lpszTemp - lpstrPathAndFile;
 | 
|---|
| 1473 |  
 | 
|---|
| 1474 |           /* set extension offset */
 | 
|---|
| 1475 |           lpszTemp = COMDLG32_PathFindExtensionA(lpstrPathAndFile);
 | 
|---|
| 1476 |           fodInfos->ofnInfos->nFileExtension = (*lpszTemp) ? lpszTemp - lpstrPathAndFile + 1 : 0;
 | 
|---|
| 1477 |     
 | 
|---|
| 1478 |           /* set the lpstrFileTitle */
 | 
|---|
| 1479 |           if(fodInfos->ofnInfos->lpstrFileTitle)
 | 
|---|
| 1480 |           {
 | 
|---|
| 1481 |             LPSTR lpstrFileTitle = COMDLG32_PathFindFileNameA(lpstrPathAndFile);
 | 
|---|
| 1482 |             strncpy(fodInfos->ofnInfos->lpstrFileTitle, lpstrFileTitle, fodInfos->ofnInfos->nMaxFileTitle);
 | 
|---|
| 1483 |           }
 | 
|---|
| 1484 | 
 | 
|---|
| 1485 |           FILEDLG95_Clean(hwnd);
 | 
|---|
| 1486 |           ret = EndDialog(hwnd, TRUE);
 | 
|---|
| 1487 |         }
 | 
|---|
| 1488 |         else
 | 
|---|
| 1489 |         {
 | 
|---|
| 1490 |           /* FIXME set error FNERR_BUFFERTOSMALL */
 | 
|---|
| 1491 |           FILEDLG95_Clean(hwnd);
 | 
|---|
| 1492 |           ret = EndDialog(hwnd, FALSE);
 | 
|---|
| 1493 |         }
 | 
|---|
| 1494 |         goto ret;
 | 
|---|
| 1495 |       }
 | 
|---|
| 1496 |       break;
 | 
|---|
| 1497 |   }
 | 
|---|
| 1498 | 
 | 
|---|
| 1499 | ret:
 | 
|---|
| 1500 |   if(lpsf) IShellFolder_Release(lpsf);
 | 
|---|
| 1501 |   return ret;
 | 
|---|
| 1502 | }
 | 
|---|
| 1503 | 
 | 
|---|
| 1504 | /***********************************************************************
 | 
|---|
| 1505 |  *      FILEDLG95_SHELL_Init
 | 
|---|
| 1506 |  *
 | 
|---|
| 1507 |  * Initialisation of the shell objects
 | 
|---|
| 1508 |  */
 | 
|---|
| 1509 | static HRESULT FILEDLG95_SHELL_Init(HWND hwnd)
 | 
|---|
| 1510 | {
 | 
|---|
| 1511 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1512 | 
 | 
|---|
| 1513 |   TRACE("\n");
 | 
|---|
| 1514 | 
 | 
|---|
| 1515 |   /*
 | 
|---|
| 1516 |    * Initialisation of the FileOpenDialogInfos structure 
 | 
|---|
| 1517 |    */
 | 
|---|
| 1518 | 
 | 
|---|
| 1519 |   /* Shell */
 | 
|---|
| 1520 | 
 | 
|---|
| 1521 |   /*ShellInfos */
 | 
|---|
| 1522 |   fodInfos->ShellInfos.hwndOwner = hwnd;
 | 
|---|
| 1523 | 
 | 
|---|
| 1524 |   /* Disable multi-select if flag not set */
 | 
|---|
| 1525 |   if (!(fodInfos->ofnInfos->Flags & OFN_ALLOWMULTISELECT))
 | 
|---|
| 1526 |   {
 | 
|---|
| 1527 |      fodInfos->ShellInfos.folderSettings.fFlags |= FWF_SINGLESEL; 
 | 
|---|
| 1528 |   }
 | 
|---|
| 1529 |   fodInfos->ShellInfos.folderSettings.fFlags |= FWF_AUTOARRANGE | FWF_ALIGNLEFT;
 | 
|---|
| 1530 |   fodInfos->ShellInfos.folderSettings.ViewMode = FVM_LIST;
 | 
|---|
| 1531 | 
 | 
|---|
| 1532 |   GetWindowRect(GetDlgItem(hwnd,IDC_SHELLSTATIC),&fodInfos->ShellInfos.rectView);
 | 
|---|
| 1533 |   ScreenToClient(hwnd,(LPPOINT)&fodInfos->ShellInfos.rectView.left);
 | 
|---|
| 1534 |   ScreenToClient(hwnd,(LPPOINT)&fodInfos->ShellInfos.rectView.right);
 | 
|---|
| 1535 | 
 | 
|---|
| 1536 |   /* Construct the IShellBrowser interface */
 | 
|---|
| 1537 |   fodInfos->Shell.FOIShellBrowser = IShellBrowserImpl_Construct(hwnd);  
 | 
|---|
| 1538 |     
 | 
|---|
| 1539 |   return NOERROR;
 | 
|---|
| 1540 | }
 | 
|---|
| 1541 | 
 | 
|---|
| 1542 | /***********************************************************************
 | 
|---|
| 1543 |  *      FILEDLG95_SHELL_ExecuteCommand
 | 
|---|
| 1544 |  *
 | 
|---|
| 1545 |  * Change the folder option and refresh the view
 | 
|---|
| 1546 |  * If the function succeeds, the return value is nonzero.
 | 
|---|
| 1547 |  */
 | 
|---|
| 1548 | static BOOL FILEDLG95_SHELL_ExecuteCommand(HWND hwnd, LPCSTR lpVerb)
 | 
|---|
| 1549 | {
 | 
|---|
| 1550 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1551 | 
 | 
|---|
| 1552 |   IContextMenu * pcm;
 | 
|---|
| 1553 |   TRACE("(0x%08x,%p)\n", hwnd, lpVerb);
 | 
|---|
| 1554 | 
 | 
|---|
| 1555 |   if(SUCCEEDED(IShellView_GetItemObject(fodInfos->Shell.FOIShellView,
 | 
|---|
| 1556 |                                         SVGIO_BACKGROUND,
 | 
|---|
| 1557 |                                         &IID_IContextMenu,
 | 
|---|
| 1558 |                                         (LPVOID*)&pcm)))
 | 
|---|
| 1559 |   {
 | 
|---|
| 1560 |     CMINVOKECOMMANDINFO ci;
 | 
|---|
| 1561 |     ZeroMemory(&ci, sizeof(CMINVOKECOMMANDINFO));
 | 
|---|
| 1562 |     ci.cbSize = sizeof(CMINVOKECOMMANDINFO);
 | 
|---|
| 1563 |     ci.lpVerb = lpVerb;
 | 
|---|
| 1564 |     ci.hwnd = hwnd;
 | 
|---|
| 1565 | 
 | 
|---|
| 1566 |     IContextMenu_InvokeCommand(pcm, &ci);
 | 
|---|
| 1567 |     IContextMenu_Release(pcm);
 | 
|---|
| 1568 |   }
 | 
|---|
| 1569 | 
 | 
|---|
| 1570 |   return FALSE;
 | 
|---|
| 1571 | }
 | 
|---|
| 1572 | 
 | 
|---|
| 1573 | /***********************************************************************
 | 
|---|
| 1574 |  *      FILEDLG95_SHELL_UpFolder
 | 
|---|
| 1575 |  *
 | 
|---|
| 1576 |  * Browse to the specified object
 | 
|---|
| 1577 |  * If the function succeeds, the return value is nonzero.
 | 
|---|
| 1578 |  */
 | 
|---|
| 1579 | static BOOL FILEDLG95_SHELL_UpFolder(HWND hwnd)
 | 
|---|
| 1580 | {
 | 
|---|
| 1581 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1582 | 
 | 
|---|
| 1583 |   TRACE("\n");
 | 
|---|
| 1584 | 
 | 
|---|
| 1585 |   if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
 | 
|---|
| 1586 |                                           NULL,
 | 
|---|
| 1587 |                                           SBSP_PARENT)))
 | 
|---|
| 1588 |   {
 | 
|---|
| 1589 |     return TRUE;
 | 
|---|
| 1590 |   }
 | 
|---|
| 1591 |   return FALSE;
 | 
|---|
| 1592 | }
 | 
|---|
| 1593 | 
 | 
|---|
| 1594 | /***********************************************************************
 | 
|---|
| 1595 |  *      FILEDLG95_SHELL_BrowseToDesktop
 | 
|---|
| 1596 |  *
 | 
|---|
| 1597 |  * Browse to the Desktop
 | 
|---|
| 1598 |  * If the function succeeds, the return value is nonzero.
 | 
|---|
| 1599 |  */
 | 
|---|
| 1600 | static BOOL FILEDLG95_SHELL_BrowseToDesktop(HWND hwnd)
 | 
|---|
| 1601 | {
 | 
|---|
| 1602 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1603 |   LPITEMIDLIST pidl;
 | 
|---|
| 1604 |   HRESULT hres;
 | 
|---|
| 1605 |   
 | 
|---|
| 1606 |   TRACE("\n");
 | 
|---|
| 1607 | 
 | 
|---|
| 1608 |   COMDLG32_SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidl);
 | 
|---|
| 1609 |   hres = IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser, pidl, SBSP_ABSOLUTE);
 | 
|---|
| 1610 |   COMDLG32_SHFree(pidl);
 | 
|---|
| 1611 |   return SUCCEEDED(hres);
 | 
|---|
| 1612 | }
 | 
|---|
| 1613 | /***********************************************************************
 | 
|---|
| 1614 |  *      FILEDLG95_SHELL_Clean
 | 
|---|
| 1615 |  *
 | 
|---|
| 1616 |  * Cleans the memory used by shell objects
 | 
|---|
| 1617 |  */
 | 
|---|
| 1618 | static void FILEDLG95_SHELL_Clean(HWND hwnd)
 | 
|---|
| 1619 | {
 | 
|---|
| 1620 |     FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1621 | 
 | 
|---|
| 1622 |     TRACE("\n");
 | 
|---|
| 1623 | 
 | 
|---|
| 1624 |     COMDLG32_SHFree(fodInfos->ShellInfos.pidlAbsCurrent);
 | 
|---|
| 1625 | 
 | 
|---|
| 1626 |     /* clean Shell interfaces */
 | 
|---|
| 1627 |     IShellView_DestroyViewWindow(fodInfos->Shell.FOIShellView);
 | 
|---|
| 1628 |     IShellView_Release(fodInfos->Shell.FOIShellView);
 | 
|---|
| 1629 |     IShellFolder_Release(fodInfos->Shell.FOIShellFolder);
 | 
|---|
| 1630 |     IShellBrowser_Release(fodInfos->Shell.FOIShellBrowser);
 | 
|---|
| 1631 |     if (fodInfos->Shell.FOIDataObject)
 | 
|---|
| 1632 |       IDataObject_Release(fodInfos->Shell.FOIDataObject);
 | 
|---|
| 1633 | }
 | 
|---|
| 1634 | 
 | 
|---|
| 1635 | /***********************************************************************
 | 
|---|
| 1636 |  *      FILEDLG95_FILETYPE_Init
 | 
|---|
| 1637 |  *
 | 
|---|
| 1638 |  * Initialisation of the file type combo box 
 | 
|---|
| 1639 |  */
 | 
|---|
| 1640 | static HRESULT FILEDLG95_FILETYPE_Init(HWND hwnd)
 | 
|---|
| 1641 | {
 | 
|---|
| 1642 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1643 | 
 | 
|---|
| 1644 |   TRACE("\n");
 | 
|---|
| 1645 | 
 | 
|---|
| 1646 |   if(fodInfos->ofnInfos->lpstrFilter)
 | 
|---|
| 1647 |   {
 | 
|---|
| 1648 |     int nFilters = 0;   /* number of filters */
 | 
|---|
| 1649 |     LPSTR lpstrFilter;
 | 
|---|
| 1650 |     LPCSTR lpstrPos = fodInfos->ofnInfos->lpstrFilter;
 | 
|---|
| 1651 | 
 | 
|---|
| 1652 |     for(;;)
 | 
|---|
| 1653 |     {
 | 
|---|
| 1654 |       /* filter is a list...  title\0ext\0......\0\0 
 | 
|---|
| 1655 |        * Set the combo item text to the title and the item data
 | 
|---|
| 1656 |        *  to the ext
 | 
|---|
| 1657 |        */
 | 
|---|
| 1658 |       LPCSTR lpstrDisplay;
 | 
|---|
| 1659 |       LPSTR lpstrExt;
 | 
|---|
| 1660 | 
 | 
|---|
| 1661 |       /* Get the title */
 | 
|---|
| 1662 |       if(! *lpstrPos) break;    /* end */
 | 
|---|
| 1663 |       lpstrDisplay = lpstrPos;
 | 
|---|
| 1664 |       lpstrPos += strlen(lpstrPos) + 1;
 | 
|---|
| 1665 | 
 | 
|---|
| 1666 |       /* Copy the extensions */
 | 
|---|
| 1667 |       if (! *lpstrPos) return E_FAIL;   /* malformed filter */
 | 
|---|
| 1668 |       if (!(lpstrExt = (LPSTR) MemAlloc(strlen(lpstrPos)+1))) return E_FAIL;
 | 
|---|
| 1669 |       strcpy(lpstrExt,lpstrPos);
 | 
|---|
| 1670 |       lpstrPos += strlen(lpstrPos) + 1;
 | 
|---|
| 1671 |             
 | 
|---|
| 1672 |       /* Add the item at the end of the combo */
 | 
|---|
| 1673 |       CBAddString(fodInfos->DlgInfos.hwndFileTypeCB, lpstrDisplay);
 | 
|---|
| 1674 |       CBSetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB, nFilters, lpstrExt);
 | 
|---|
| 1675 |       nFilters++;
 | 
|---|
| 1676 |     }
 | 
|---|
| 1677 |     /*
 | 
|---|
| 1678 |      * Set the current filter to the one specified
 | 
|---|
| 1679 |      * in the initialisation structure
 | 
|---|
| 1680 |      * FIXME: lpstrCustomFilter not handled at all
 | 
|---|
| 1681 |      */
 | 
|---|
| 1682 |   
 | 
|---|
| 1683 |     /* set default filter index */
 | 
|---|
| 1684 |     if(fodInfos->ofnInfos->nFilterIndex == 0 && fodInfos->ofnInfos->lpstrCustomFilter == NULL)
 | 
|---|
| 1685 |       fodInfos->ofnInfos->nFilterIndex = 1;
 | 
|---|
| 1686 | 
 | 
|---|
| 1687 |     /* First, check to make sure our index isn't out of bounds. */
 | 
|---|
| 1688 |     if ( fodInfos->ofnInfos->nFilterIndex > nFilters )
 | 
|---|
| 1689 |       fodInfos->ofnInfos->nFilterIndex = nFilters;
 | 
|---|
| 1690 |  
 | 
|---|
| 1691 |     /* Set the current index selection. */
 | 
|---|
| 1692 |     CBSetCurSel(fodInfos->DlgInfos.hwndFileTypeCB, fodInfos->ofnInfos->nFilterIndex-1);
 | 
|---|
| 1693 |   
 | 
|---|
| 1694 |     /* Get the corresponding text string from the combo box. */
 | 
|---|
| 1695 |     lpstrFilter = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
 | 
|---|
| 1696 |                                              fodInfos->ofnInfos->nFilterIndex-1);
 | 
|---|
| 1697 | 
 | 
|---|
| 1698 |     if ((INT)lpstrFilter == CB_ERR)  /* control is empty */
 | 
|---|
| 1699 |       lpstrFilter = NULL;       
 | 
|---|
| 1700 | 
 | 
|---|
| 1701 |     if(lpstrFilter)
 | 
|---|
| 1702 |     {
 | 
|---|
| 1703 |       _strlwr(lpstrFilter);     /* lowercase */
 | 
|---|
| 1704 |       fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc((strlen(lpstrFilter)+1)*2);
 | 
|---|
| 1705 |       lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter, lpstrFilter);
 | 
|---|
| 1706 |     }
 | 
|---|
| 1707 |   }
 | 
|---|
| 1708 |   return NOERROR;
 | 
|---|
| 1709 | }
 | 
|---|
| 1710 | 
 | 
|---|
| 1711 | /***********************************************************************
 | 
|---|
| 1712 |  *      FILEDLG95_FILETYPE_OnCommand
 | 
|---|
| 1713 |  *
 | 
|---|
| 1714 |  * WM_COMMAND of the file type combo box
 | 
|---|
| 1715 |  * If the function succeeds, the return value is nonzero.
 | 
|---|
| 1716 |  */
 | 
|---|
| 1717 | static BOOL FILEDLG95_FILETYPE_OnCommand(HWND hwnd, WORD wNotifyCode)
 | 
|---|
| 1718 | {
 | 
|---|
| 1719 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1720 | 
 | 
|---|
| 1721 |   switch(wNotifyCode)
 | 
|---|
| 1722 |   {
 | 
|---|
| 1723 |     case CBN_SELENDOK:
 | 
|---|
| 1724 |     {
 | 
|---|
| 1725 |       LPSTR lpstrFilter;
 | 
|---|
| 1726 | 
 | 
|---|
| 1727 |       /* Get the current item of the filetype combo box */
 | 
|---|
| 1728 |       int iItem = CBGetCurSel(fodInfos->DlgInfos.hwndFileTypeCB);
 | 
|---|
| 1729 | 
 | 
|---|
| 1730 |       /* set the current filter index - indexed from 1 */
 | 
|---|
| 1731 |       fodInfos->ofnInfos->nFilterIndex = iItem + 1;
 | 
|---|
| 1732 | 
 | 
|---|
| 1733 |       /* Set the current filter with the current selection */
 | 
|---|
| 1734 |       if(fodInfos->ShellInfos.lpstrCurrentFilter)
 | 
|---|
| 1735 |          MemFree((LPVOID)fodInfos->ShellInfos.lpstrCurrentFilter);
 | 
|---|
| 1736 | 
 | 
|---|
| 1737 |       lpstrFilter = (LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,
 | 
|---|
| 1738 |                                              iItem);
 | 
|---|
| 1739 |       if((int)lpstrFilter != CB_ERR)
 | 
|---|
| 1740 |       {
 | 
|---|
| 1741 |         fodInfos->ShellInfos.lpstrCurrentFilter = MemAlloc((strlen(lpstrFilter)+1)*2);
 | 
|---|
| 1742 |         lstrcpyAtoW(fodInfos->ShellInfos.lpstrCurrentFilter,_strlwr(lpstrFilter));
 | 
|---|
| 1743 |         SendCustomDlgNotificationMessage(hwnd,CDN_TYPECHANGE);
 | 
|---|
| 1744 |       }
 | 
|---|
| 1745 | 
 | 
|---|
| 1746 |       /* Refresh the actual view to display the included items*/
 | 
|---|
| 1747 |       IShellView_Refresh(fodInfos->Shell.FOIShellView);
 | 
|---|
| 1748 |     }
 | 
|---|
| 1749 |   }
 | 
|---|
| 1750 |   return FALSE;
 | 
|---|
| 1751 | }
 | 
|---|
| 1752 | /***********************************************************************
 | 
|---|
| 1753 |  *      FILEDLG95_FILETYPE_SearchExt
 | 
|---|
| 1754 |  *
 | 
|---|
| 1755 |  * searches for a extension in the filetype box
 | 
|---|
| 1756 |  */
 | 
|---|
| 1757 | static int FILEDLG95_FILETYPE_SearchExt(HWND hwnd,LPCSTR lpstrExt)
 | 
|---|
| 1758 | {
 | 
|---|
| 1759 |   int i, iCount = CBGetCount(hwnd);
 | 
|---|
| 1760 | 
 | 
|---|
| 1761 |   TRACE("%s\n", lpstrExt);
 | 
|---|
| 1762 | 
 | 
|---|
| 1763 |   if(iCount != CB_ERR)
 | 
|---|
| 1764 |   {
 | 
|---|
| 1765 |     for(i=0;i<iCount;i++)
 | 
|---|
| 1766 |     {
 | 
|---|
| 1767 |       if(!strcasecmp(lpstrExt,(LPSTR)CBGetItemDataPtr(hwnd,i)))
 | 
|---|
| 1768 |           return i;
 | 
|---|
| 1769 |     }
 | 
|---|
| 1770 |   }
 | 
|---|
| 1771 |   return -1;
 | 
|---|
| 1772 | }
 | 
|---|
| 1773 | 
 | 
|---|
| 1774 | /***********************************************************************
 | 
|---|
| 1775 |  *      FILEDLG95_FILETYPE_Clean
 | 
|---|
| 1776 |  *
 | 
|---|
| 1777 |  * Clean the memory used by the filetype combo box
 | 
|---|
| 1778 |  */
 | 
|---|
| 1779 | static void FILEDLG95_FILETYPE_Clean(HWND hwnd)
 | 
|---|
| 1780 | {
 | 
|---|
| 1781 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1782 |   int iPos;
 | 
|---|
| 1783 |   int iCount = CBGetCount(fodInfos->DlgInfos.hwndFileTypeCB);
 | 
|---|
| 1784 | 
 | 
|---|
| 1785 |   TRACE("\n");
 | 
|---|
| 1786 | 
 | 
|---|
| 1787 |   /* Delete each string of the combo and their associated data */
 | 
|---|
| 1788 |   if(iCount != CB_ERR)
 | 
|---|
| 1789 |   {
 | 
|---|
| 1790 |     for(iPos = iCount-1;iPos>=0;iPos--)
 | 
|---|
| 1791 |     {
 | 
|---|
| 1792 |       MemFree((LPSTR) CBGetItemDataPtr(fodInfos->DlgInfos.hwndFileTypeCB,iPos));
 | 
|---|
| 1793 |       CBDeleteString(fodInfos->DlgInfos.hwndFileTypeCB,iPos);
 | 
|---|
| 1794 |     }
 | 
|---|
| 1795 |   }
 | 
|---|
| 1796 |   /* Current filter */
 | 
|---|
| 1797 |   if(fodInfos->ShellInfos.lpstrCurrentFilter)
 | 
|---|
| 1798 |      MemFree(fodInfos->ShellInfos.lpstrCurrentFilter);
 | 
|---|
| 1799 | 
 | 
|---|
| 1800 | }
 | 
|---|
| 1801 |     
 | 
|---|
| 1802 | /***********************************************************************
 | 
|---|
| 1803 |  *      FILEDLG95_LOOKIN_Init
 | 
|---|
| 1804 |  *
 | 
|---|
| 1805 |  * Initialisation of the look in combo box 
 | 
|---|
| 1806 |  */
 | 
|---|
| 1807 | static HRESULT FILEDLG95_LOOKIN_Init(HWND hwndCombo)
 | 
|---|
| 1808 | {
 | 
|---|
| 1809 |   IShellFolder  *psfRoot, *psfDrives;
 | 
|---|
| 1810 |   IEnumIDList   *lpeRoot, *lpeDrives;
 | 
|---|
| 1811 |   LPITEMIDLIST  pidlDrives, pidlTmp, pidlTmp1, pidlAbsTmp;
 | 
|---|
| 1812 | 
 | 
|---|
| 1813 |   LookInInfos *liInfos = MemAlloc(sizeof(LookInInfos));
 | 
|---|
| 1814 | 
 | 
|---|
| 1815 |   TRACE("\n");
 | 
|---|
| 1816 | 
 | 
|---|
| 1817 |   liInfos->iMaxIndentation = 0;
 | 
|---|
| 1818 | 
 | 
|---|
| 1819 |   SetPropA(hwndCombo, LookInInfosStr, (HANDLE) liInfos);
 | 
|---|
| 1820 |   CBSetItemHeight(hwndCombo,0,GetSystemMetrics(SM_CYSMICON));
 | 
|---|
| 1821 | 
 | 
|---|
| 1822 |   /* Initialise data of Desktop folder */
 | 
|---|
| 1823 |   COMDLG32_SHGetSpecialFolderLocation(0,CSIDL_DESKTOP,&pidlTmp);
 | 
|---|
| 1824 |   FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
 | 
|---|
| 1825 |   COMDLG32_SHFree(pidlTmp);
 | 
|---|
| 1826 | 
 | 
|---|
| 1827 |   COMDLG32_SHGetSpecialFolderLocation(0,CSIDL_DRIVES,&pidlDrives);
 | 
|---|
| 1828 | 
 | 
|---|
| 1829 |   COMDLG32_SHGetDesktopFolder(&psfRoot);
 | 
|---|
| 1830 | 
 | 
|---|
| 1831 |   if (psfRoot)
 | 
|---|
| 1832 |   {
 | 
|---|
| 1833 |     /* enumerate the contents of the desktop */
 | 
|---|
| 1834 |     if(SUCCEEDED(IShellFolder_EnumObjects(psfRoot, hwndCombo, SHCONTF_FOLDERS, &lpeRoot)))
 | 
|---|
| 1835 |     {
 | 
|---|
| 1836 |       while (S_OK == IEnumIDList_Next(lpeRoot, 1, &pidlTmp, NULL))
 | 
|---|
| 1837 |       {
 | 
|---|
| 1838 |         FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlTmp,LISTEND);
 | 
|---|
| 1839 | 
 | 
|---|
| 1840 |         /* special handling for CSIDL_DRIVES */
 | 
|---|
| 1841 |         if (COMDLG32_PIDL_ILIsEqual(pidlTmp, pidlDrives))
 | 
|---|
| 1842 |         {
 | 
|---|
| 1843 |           if(SUCCEEDED(IShellFolder_BindToObject(psfRoot, pidlTmp, NULL, &IID_IShellFolder, (LPVOID*)&psfDrives)))
 | 
|---|
| 1844 |           {
 | 
|---|
| 1845 |             /* enumerate the drives */
 | 
|---|
| 1846 |             if(SUCCEEDED(IShellFolder_EnumObjects(psfDrives, hwndCombo,SHCONTF_FOLDERS, &lpeDrives)))
 | 
|---|
| 1847 |             {
 | 
|---|
| 1848 |               while (S_OK == IEnumIDList_Next(lpeDrives, 1, &pidlTmp1, NULL))
 | 
|---|
| 1849 |               {
 | 
|---|
| 1850 |                 pidlAbsTmp = COMDLG32_PIDL_ILCombine(pidlTmp, pidlTmp1);
 | 
|---|
| 1851 |                 FILEDLG95_LOOKIN_AddItem(hwndCombo, pidlAbsTmp,LISTEND);
 | 
|---|
| 1852 |                 COMDLG32_SHFree(pidlAbsTmp);
 | 
|---|
| 1853 |                 COMDLG32_SHFree(pidlTmp1);
 | 
|---|
| 1854 |               }
 | 
|---|
| 1855 |               IEnumIDList_Release(lpeDrives);
 | 
|---|
| 1856 |             }
 | 
|---|
| 1857 |             IShellFolder_Release(psfDrives);
 | 
|---|
| 1858 |           }
 | 
|---|
| 1859 |         }
 | 
|---|
| 1860 |         COMDLG32_SHFree(pidlTmp);
 | 
|---|
| 1861 |       }
 | 
|---|
| 1862 |       IEnumIDList_Release(lpeRoot);
 | 
|---|
| 1863 |     }
 | 
|---|
| 1864 |   }
 | 
|---|
| 1865 | 
 | 
|---|
| 1866 |   IShellFolder_Release(psfRoot);
 | 
|---|
| 1867 |   COMDLG32_SHFree(pidlDrives);
 | 
|---|
| 1868 |   return NOERROR;
 | 
|---|
| 1869 | }
 | 
|---|
| 1870 | 
 | 
|---|
| 1871 | /***********************************************************************
 | 
|---|
| 1872 |  *      FILEDLG95_LOOKIN_DrawItem
 | 
|---|
| 1873 |  *
 | 
|---|
| 1874 |  * WM_DRAWITEM message handler
 | 
|---|
| 1875 |  */
 | 
|---|
| 1876 | static LRESULT FILEDLG95_LOOKIN_DrawItem(LPDRAWITEMSTRUCT pDIStruct)
 | 
|---|
| 1877 | {
 | 
|---|
| 1878 |   COLORREF crWin = GetSysColor(COLOR_WINDOW);
 | 
|---|
| 1879 |   COLORREF crHighLight = GetSysColor(COLOR_HIGHLIGHT);
 | 
|---|
| 1880 |   COLORREF crText = GetSysColor(COLOR_WINDOWTEXT);
 | 
|---|
| 1881 |   RECT rectText;
 | 
|---|
| 1882 |   RECT rectIcon;
 | 
|---|
| 1883 |   SHFILEINFOA sfi;
 | 
|---|
| 1884 |   HIMAGELIST ilItemImage;
 | 
|---|
| 1885 |   int iIndentation;
 | 
|---|
| 1886 |   LPSFOLDER tmpFolder;
 | 
|---|
| 1887 | 
 | 
|---|
| 1888 | 
 | 
|---|
| 1889 |   LookInInfos *liInfos = (LookInInfos *)GetPropA(pDIStruct->hwndItem,LookInInfosStr);
 | 
|---|
| 1890 | 
 | 
|---|
| 1891 |   TRACE("\n");
 | 
|---|
| 1892 | 
 | 
|---|
| 1893 |   if(pDIStruct->itemID == -1)
 | 
|---|
| 1894 |     return 0;
 | 
|---|
| 1895 | 
 | 
|---|
| 1896 |   if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(pDIStruct->hwndItem,
 | 
|---|
| 1897 |                             pDIStruct->itemID)))
 | 
|---|
| 1898 |     return 0;
 | 
|---|
| 1899 | 
 | 
|---|
| 1900 | 
 | 
|---|
| 1901 |   if(pDIStruct->itemID == liInfos->uSelectedItem)
 | 
|---|
| 1902 |   {
 | 
|---|
| 1903 |     ilItemImage = (HIMAGELIST) COMDLG32_SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
 | 
|---|
| 1904 |                                                0,    
 | 
|---|
| 1905 |                                                &sfi,    
 | 
|---|
| 1906 |                                                sizeof (SHFILEINFOA),   
 | 
|---|
| 1907 |                                                SHGFI_PIDL | SHGFI_SMALLICON |    
 | 
|---|
| 1908 |                                                SHGFI_OPENICON | SHGFI_SYSICONINDEX    | 
 | 
|---|
| 1909 |                                                SHGFI_DISPLAYNAME );   
 | 
|---|
| 1910 |   }
 | 
|---|
| 1911 |   else
 | 
|---|
| 1912 |   {
 | 
|---|
| 1913 |     ilItemImage = (HIMAGELIST) COMDLG32_SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
 | 
|---|
| 1914 |                                                   0, 
 | 
|---|
| 1915 |                                                   &sfi, 
 | 
|---|
| 1916 |                                                   sizeof (SHFILEINFOA),
 | 
|---|
| 1917 |                                                   SHGFI_PIDL | SHGFI_SMALLICON | 
 | 
|---|
| 1918 |                                                   SHGFI_SYSICONINDEX | 
 | 
|---|
| 1919 |                                                   SHGFI_DISPLAYNAME);
 | 
|---|
| 1920 |   }
 | 
|---|
| 1921 | 
 | 
|---|
| 1922 |   /* Is this item selected ?*/
 | 
|---|
| 1923 |   if(pDIStruct->itemState & ODS_SELECTED)
 | 
|---|
| 1924 |   {
 | 
|---|
| 1925 |     SetTextColor(pDIStruct->hDC,(0x00FFFFFF & ~(crText)));
 | 
|---|
| 1926 |     SetBkColor(pDIStruct->hDC,crHighLight);
 | 
|---|
| 1927 |     FillRect(pDIStruct->hDC,&pDIStruct->rcItem,(HBRUSH)crHighLight);
 | 
|---|
| 1928 |   }
 | 
|---|
| 1929 |   else
 | 
|---|
| 1930 |   {
 | 
|---|
| 1931 |     SetTextColor(pDIStruct->hDC,crText);
 | 
|---|
| 1932 |     SetBkColor(pDIStruct->hDC,crWin);
 | 
|---|
| 1933 |     FillRect(pDIStruct->hDC,&pDIStruct->rcItem,(HBRUSH)crWin);
 | 
|---|
| 1934 |   }
 | 
|---|
| 1935 | 
 | 
|---|
| 1936 |   /* Do not indent item  if drawing in the edit of the combo*/
 | 
|---|
| 1937 |   if(pDIStruct->itemState & ODS_COMBOBOXEDIT)
 | 
|---|
| 1938 |   {
 | 
|---|
| 1939 |     iIndentation = 0;
 | 
|---|
| 1940 |     ilItemImage = (HIMAGELIST) COMDLG32_SHGetFileInfoA ((LPCSTR) tmpFolder->pidlItem,
 | 
|---|
| 1941 |                                                 0, 
 | 
|---|
| 1942 |                                                 &sfi, 
 | 
|---|
| 1943 |                                                 sizeof (SHFILEINFOA), 
 | 
|---|
| 1944 |                                                 SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_OPENICON 
 | 
|---|
| 1945 |                                                 | SHGFI_SYSICONINDEX | SHGFI_DISPLAYNAME  );
 | 
|---|
| 1946 | 
 | 
|---|
| 1947 |   }
 | 
|---|
| 1948 |   else
 | 
|---|
| 1949 |   {
 | 
|---|
| 1950 |     iIndentation = tmpFolder->m_iIndent;
 | 
|---|
| 1951 |   }
 | 
|---|
| 1952 |   /* Draw text and icon */
 | 
|---|
| 1953 | 
 | 
|---|
| 1954 |   /* Initialise the icon display area */
 | 
|---|
| 1955 |   rectIcon.left = pDIStruct->rcItem.left + ICONWIDTH/2 * iIndentation;
 | 
|---|
| 1956 |   rectIcon.top = pDIStruct->rcItem.top;
 | 
|---|
| 1957 |   rectIcon.right = rectIcon.left + ICONWIDTH;
 | 
|---|
| 1958 |   rectIcon.bottom = pDIStruct->rcItem.bottom;
 | 
|---|
| 1959 | 
 | 
|---|
| 1960 |   /* Initialise the text display area */
 | 
|---|
| 1961 |   rectText.left = rectIcon.right;
 | 
|---|
| 1962 |   rectText.top = pDIStruct->rcItem.top + YTEXTOFFSET;
 | 
|---|
| 1963 |   rectText.right = pDIStruct->rcItem.right + XTEXTOFFSET;
 | 
|---|
| 1964 |   rectText.bottom = pDIStruct->rcItem.bottom;
 | 
|---|
| 1965 | 
 | 
|---|
| 1966 |  
 | 
|---|
| 1967 |   /* Draw the icon from the image list */
 | 
|---|
| 1968 |   COMDLG32_ImageList_Draw(ilItemImage,
 | 
|---|
| 1969 |                  sfi.iIcon,
 | 
|---|
| 1970 |                  pDIStruct->hDC,  
 | 
|---|
| 1971 |                  rectIcon.left,  
 | 
|---|
| 1972 |                  rectIcon.top,  
 | 
|---|
| 1973 |                  ILD_TRANSPARENT );  
 | 
|---|
| 1974 | 
 | 
|---|
| 1975 |   /* Draw the associated text */
 | 
|---|
| 1976 |   if(sfi.szDisplayName)
 | 
|---|
| 1977 |     TextOutA(pDIStruct->hDC,rectText.left,rectText.top,sfi.szDisplayName,strlen(sfi.szDisplayName));
 | 
|---|
| 1978 | 
 | 
|---|
| 1979 | 
 | 
|---|
| 1980 |   return NOERROR;
 | 
|---|
| 1981 | }
 | 
|---|
| 1982 | 
 | 
|---|
| 1983 | /***********************************************************************
 | 
|---|
| 1984 |  *      FILEDLG95_LOOKIN_OnCommand
 | 
|---|
| 1985 |  *
 | 
|---|
| 1986 |  * LookIn combo box WM_COMMAND message handler
 | 
|---|
| 1987 |  * If the function succeeds, the return value is nonzero.
 | 
|---|
| 1988 |  */
 | 
|---|
| 1989 | static BOOL FILEDLG95_LOOKIN_OnCommand(HWND hwnd, WORD wNotifyCode)
 | 
|---|
| 1990 | {
 | 
|---|
| 1991 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 1992 | 
 | 
|---|
| 1993 |   TRACE("%p\n", fodInfos);
 | 
|---|
| 1994 | 
 | 
|---|
| 1995 |   switch(wNotifyCode)
 | 
|---|
| 1996 |   {
 | 
|---|
| 1997 |     case CBN_SELENDOK:
 | 
|---|
| 1998 |     {
 | 
|---|
| 1999 |       LPSFOLDER tmpFolder;
 | 
|---|
| 2000 |       int iItem; 
 | 
|---|
| 2001 | 
 | 
|---|
| 2002 |       iItem = CBGetCurSel(fodInfos->DlgInfos.hwndLookInCB);
 | 
|---|
| 2003 | 
 | 
|---|
| 2004 |       if(!(tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,
 | 
|---|
| 2005 |                                                iItem)))
 | 
|---|
| 2006 |         return FALSE;
 | 
|---|
| 2007 | 
 | 
|---|
| 2008 | 
 | 
|---|
| 2009 |       if(SUCCEEDED(IShellBrowser_BrowseObject(fodInfos->Shell.FOIShellBrowser,
 | 
|---|
| 2010 |                                               tmpFolder->pidlItem,
 | 
|---|
| 2011 |                                               SBSP_ABSOLUTE)))
 | 
|---|
| 2012 |       {
 | 
|---|
| 2013 |         return TRUE;
 | 
|---|
| 2014 |       }
 | 
|---|
| 2015 |       break;
 | 
|---|
| 2016 |     }
 | 
|---|
| 2017 |       
 | 
|---|
| 2018 |   }
 | 
|---|
| 2019 |   return FALSE;
 | 
|---|
| 2020 | }
 | 
|---|
| 2021 | 
 | 
|---|
| 2022 | /***********************************************************************
 | 
|---|
| 2023 |  *      FILEDLG95_LOOKIN_AddItem
 | 
|---|
| 2024 |  *
 | 
|---|
| 2025 |  * Adds an absolute pidl item to the lookin combo box
 | 
|---|
| 2026 |  * returns the index of the inserted item
 | 
|---|
| 2027 |  */
 | 
|---|
| 2028 | static int FILEDLG95_LOOKIN_AddItem(HWND hwnd,LPITEMIDLIST pidl, int iInsertId)
 | 
|---|
| 2029 | {
 | 
|---|
| 2030 |   LPITEMIDLIST pidlNext;
 | 
|---|
| 2031 |   SHFILEINFOA sfi;
 | 
|---|
| 2032 |   SFOLDER *tmpFolder;
 | 
|---|
| 2033 |   LookInInfos *liInfos;
 | 
|---|
| 2034 | 
 | 
|---|
| 2035 |   TRACE("\n");
 | 
|---|
| 2036 | 
 | 
|---|
| 2037 |   if(!pidl)
 | 
|---|
| 2038 |     return -1;
 | 
|---|
| 2039 | 
 | 
|---|
| 2040 |   if(!(liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr)))
 | 
|---|
| 2041 |     return -1;
 | 
|---|
| 2042 |     
 | 
|---|
| 2043 |   tmpFolder = MemAlloc(sizeof(SFOLDER));
 | 
|---|
| 2044 |   tmpFolder->m_iIndent = 0;
 | 
|---|
| 2045 | 
 | 
|---|
| 2046 |   /* Calculate the indentation of the item in the lookin*/
 | 
|---|
| 2047 |   pidlNext = pidl;
 | 
|---|
| 2048 |   while( (pidlNext=COMDLG32_PIDL_ILGetNext(pidlNext)) )
 | 
|---|
| 2049 |   {
 | 
|---|
| 2050 |     tmpFolder->m_iIndent++;
 | 
|---|
| 2051 |   }
 | 
|---|
| 2052 | 
 | 
|---|
| 2053 |   tmpFolder->pidlItem = COMDLG32_PIDL_ILClone(pidl); /* FIXME: memory leak*/
 | 
|---|
| 2054 | 
 | 
|---|
| 2055 |   if(tmpFolder->m_iIndent > liInfos->iMaxIndentation)
 | 
|---|
| 2056 |     liInfos->iMaxIndentation = tmpFolder->m_iIndent;
 | 
|---|
| 2057 |   
 | 
|---|
| 2058 |   sfi.dwAttributes = SFGAO_FILESYSANCESTOR | SFGAO_FILESYSTEM;
 | 
|---|
| 2059 |   COMDLG32_SHGetFileInfoA((LPSTR)pidl,
 | 
|---|
| 2060 |                   0,
 | 
|---|
| 2061 |                   &sfi,
 | 
|---|
| 2062 |                   sizeof(sfi),
 | 
|---|
| 2063 |                   SHGFI_DISPLAYNAME | SHGFI_SYSICONINDEX 
 | 
|---|
| 2064 |                   | SHGFI_PIDL | SHGFI_SMALLICON | SHGFI_ATTRIBUTES | SHGFI_ATTR_SPECIFIED);
 | 
|---|
| 2065 | 
 | 
|---|
| 2066 | 
 | 
|---|
| 2067 |   if((sfi.dwAttributes & SFGAO_FILESYSANCESTOR) || (sfi.dwAttributes & SFGAO_FILESYSTEM))
 | 
|---|
| 2068 |   {
 | 
|---|
| 2069 |     int iItemID;
 | 
|---|
| 2070 |   
 | 
|---|
| 2071 |     /* Add the item at the end of the list */
 | 
|---|
| 2072 |     if(iInsertId < 0)
 | 
|---|
| 2073 |     {
 | 
|---|
| 2074 |       iItemID = CBAddString(hwnd,sfi.szDisplayName);
 | 
|---|
| 2075 |     }
 | 
|---|
| 2076 |     /* Insert the item at the iInsertId position*/
 | 
|---|
| 2077 |     else
 | 
|---|
| 2078 |     {
 | 
|---|
| 2079 |       iItemID = CBInsertString(hwnd,sfi.szDisplayName,iInsertId);
 | 
|---|
| 2080 |     }
 | 
|---|
| 2081 | 
 | 
|---|
| 2082 |     CBSetItemDataPtr(hwnd,iItemID,tmpFolder);
 | 
|---|
| 2083 |     return iItemID;
 | 
|---|
| 2084 |   }
 | 
|---|
| 2085 | 
 | 
|---|
| 2086 |   MemFree( tmpFolder );
 | 
|---|
| 2087 |   return -1;
 | 
|---|
| 2088 | 
 | 
|---|
| 2089 | }
 | 
|---|
| 2090 | 
 | 
|---|
| 2091 | /***********************************************************************
 | 
|---|
| 2092 |  *      FILEDLG95_LOOKIN_InsertItemAfterParent
 | 
|---|
| 2093 |  *
 | 
|---|
| 2094 |  * Insert an item below its parent 
 | 
|---|
| 2095 |  */
 | 
|---|
| 2096 | static int FILEDLG95_LOOKIN_InsertItemAfterParent(HWND hwnd,LPITEMIDLIST pidl)
 | 
|---|
| 2097 | {
 | 
|---|
| 2098 |   
 | 
|---|
| 2099 |   LPITEMIDLIST pidlParent = GetParentPidl(pidl);
 | 
|---|
| 2100 |   int iParentPos;
 | 
|---|
| 2101 | 
 | 
|---|
| 2102 |   TRACE("\n");
 | 
|---|
| 2103 | 
 | 
|---|
| 2104 |   iParentPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidlParent,SEARCH_PIDL);
 | 
|---|
| 2105 | 
 | 
|---|
| 2106 |   if(iParentPos < 0)
 | 
|---|
| 2107 |   {
 | 
|---|
| 2108 |     iParentPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidlParent);
 | 
|---|
| 2109 |   }
 | 
|---|
| 2110 | 
 | 
|---|
| 2111 |   /* Free pidlParent memory */
 | 
|---|
| 2112 |   COMDLG32_SHFree((LPVOID)pidlParent);
 | 
|---|
| 2113 | 
 | 
|---|
| 2114 |   return FILEDLG95_LOOKIN_AddItem(hwnd,pidl,iParentPos + 1);
 | 
|---|
| 2115 | }
 | 
|---|
| 2116 | 
 | 
|---|
| 2117 | /***********************************************************************
 | 
|---|
| 2118 |  *      FILEDLG95_LOOKIN_SelectItem
 | 
|---|
| 2119 |  *
 | 
|---|
| 2120 |  * Adds an absolute pidl item to the lookin combo box
 | 
|---|
| 2121 |  * returns the index of the inserted item
 | 
|---|
| 2122 |  */
 | 
|---|
| 2123 | int FILEDLG95_LOOKIN_SelectItem(HWND hwnd,LPITEMIDLIST pidl)
 | 
|---|
| 2124 | {
 | 
|---|
| 2125 |   int iItemPos;
 | 
|---|
| 2126 |   LookInInfos *liInfos;
 | 
|---|
| 2127 | 
 | 
|---|
| 2128 |   TRACE("\n");
 | 
|---|
| 2129 | 
 | 
|---|
| 2130 |   iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)pidl,SEARCH_PIDL);
 | 
|---|
| 2131 | 
 | 
|---|
| 2132 |   liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
 | 
|---|
| 2133 | 
 | 
|---|
| 2134 |   if(iItemPos < 0)
 | 
|---|
| 2135 |   {
 | 
|---|
| 2136 |     while(FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd) > -1);
 | 
|---|
| 2137 |     iItemPos = FILEDLG95_LOOKIN_InsertItemAfterParent(hwnd,pidl);
 | 
|---|
| 2138 |   }
 | 
|---|
| 2139 | 
 | 
|---|
| 2140 |   else
 | 
|---|
| 2141 |   {
 | 
|---|
| 2142 |     SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
 | 
|---|
| 2143 |     while(liInfos->iMaxIndentation > tmpFolder->m_iIndent)
 | 
|---|
| 2144 |     {
 | 
|---|
| 2145 |       int iRemovedItem;
 | 
|---|
| 2146 | 
 | 
|---|
| 2147 |       if(-1 == (iRemovedItem = FILEDLG95_LOOKIN_RemoveMostExpandedItem(hwnd)))
 | 
|---|
| 2148 |         break;
 | 
|---|
| 2149 |       if(iRemovedItem < iItemPos)
 | 
|---|
| 2150 |         iItemPos--;
 | 
|---|
| 2151 |     }
 | 
|---|
| 2152 |   }
 | 
|---|
| 2153 |   
 | 
|---|
| 2154 |   CBSetCurSel(hwnd,iItemPos);
 | 
|---|
| 2155 |   liInfos->uSelectedItem = iItemPos;
 | 
|---|
| 2156 | 
 | 
|---|
| 2157 |   return 0;
 | 
|---|
| 2158 | 
 | 
|---|
| 2159 | }
 | 
|---|
| 2160 | 
 | 
|---|
| 2161 | /***********************************************************************
 | 
|---|
| 2162 |  *      FILEDLG95_LOOKIN_RemoveMostExpandedItem
 | 
|---|
| 2163 |  *
 | 
|---|
| 2164 |  * Remove the item with an expansion level over iExpansionLevel
 | 
|---|
| 2165 |  */
 | 
|---|
| 2166 | static int FILEDLG95_LOOKIN_RemoveMostExpandedItem(HWND hwnd)
 | 
|---|
| 2167 | {
 | 
|---|
| 2168 |   int iItemPos;
 | 
|---|
| 2169 | 
 | 
|---|
| 2170 |   LookInInfos *liInfos = (LookInInfos *)GetPropA(hwnd,LookInInfosStr);
 | 
|---|
| 2171 | 
 | 
|---|
| 2172 |   TRACE("\n");
 | 
|---|
| 2173 | 
 | 
|---|
| 2174 |   if(liInfos->iMaxIndentation <= 2)
 | 
|---|
| 2175 |     return -1;
 | 
|---|
| 2176 | 
 | 
|---|
| 2177 |   if((iItemPos = FILEDLG95_LOOKIN_SearchItem(hwnd,(WPARAM)liInfos->iMaxIndentation,SEARCH_EXP)) >=0)
 | 
|---|
| 2178 |   {
 | 
|---|
| 2179 |     SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,iItemPos);
 | 
|---|
| 2180 |     COMDLG32_SHFree(tmpFolder->pidlItem);
 | 
|---|
| 2181 |     MemFree(tmpFolder);
 | 
|---|
| 2182 |     CBDeleteString(hwnd,iItemPos);
 | 
|---|
| 2183 |     liInfos->iMaxIndentation--;
 | 
|---|
| 2184 | 
 | 
|---|
| 2185 |     return iItemPos;
 | 
|---|
| 2186 |   }
 | 
|---|
| 2187 | 
 | 
|---|
| 2188 |   return -1;
 | 
|---|
| 2189 | }
 | 
|---|
| 2190 | 
 | 
|---|
| 2191 | /***********************************************************************
 | 
|---|
| 2192 |  *      FILEDLG95_LOOKIN_SearchItem
 | 
|---|
| 2193 |  *
 | 
|---|
| 2194 |  * Search for pidl in the lookin combo box
 | 
|---|
| 2195 |  * returns the index of the found item
 | 
|---|
| 2196 |  */
 | 
|---|
| 2197 | static int FILEDLG95_LOOKIN_SearchItem(HWND hwnd,WPARAM searchArg,int iSearchMethod)
 | 
|---|
| 2198 | {
 | 
|---|
| 2199 |   int i = 0;
 | 
|---|
| 2200 |   int iCount = CBGetCount(hwnd);
 | 
|---|
| 2201 | 
 | 
|---|
| 2202 |   TRACE("\n");
 | 
|---|
| 2203 | 
 | 
|---|
| 2204 |   if (iCount != CB_ERR)
 | 
|---|
| 2205 |   {
 | 
|---|
| 2206 |     for(;i<iCount;i++)
 | 
|---|
| 2207 |     {
 | 
|---|
| 2208 |       LPSFOLDER tmpFolder = (LPSFOLDER) CBGetItemDataPtr(hwnd,i);
 | 
|---|
| 2209 | 
 | 
|---|
| 2210 |       if(iSearchMethod == SEARCH_PIDL && COMDLG32_PIDL_ILIsEqual((LPITEMIDLIST)searchArg,tmpFolder->pidlItem))
 | 
|---|
| 2211 |         return i;
 | 
|---|
| 2212 |       if(iSearchMethod == SEARCH_EXP && tmpFolder->m_iIndent == (int)searchArg)
 | 
|---|
| 2213 |         return i;
 | 
|---|
| 2214 |     }
 | 
|---|
| 2215 |   }
 | 
|---|
| 2216 | 
 | 
|---|
| 2217 |   return -1;
 | 
|---|
| 2218 | }
 | 
|---|
| 2219 | 
 | 
|---|
| 2220 | /***********************************************************************
 | 
|---|
| 2221 |  *      FILEDLG95_LOOKIN_Clean
 | 
|---|
| 2222 |  *
 | 
|---|
| 2223 |  * Clean the memory used by the lookin combo box
 | 
|---|
| 2224 |  */
 | 
|---|
| 2225 | static void FILEDLG95_LOOKIN_Clean(HWND hwnd)
 | 
|---|
| 2226 | {
 | 
|---|
| 2227 |     FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 2228 |     int iPos;
 | 
|---|
| 2229 |     int iCount = CBGetCount(fodInfos->DlgInfos.hwndLookInCB);
 | 
|---|
| 2230 | 
 | 
|---|
| 2231 |     TRACE("\n");
 | 
|---|
| 2232 | 
 | 
|---|
| 2233 |     /* Delete each string of the combo and their associated data */
 | 
|---|
| 2234 |     if (iCount != CB_ERR)
 | 
|---|
| 2235 |     {
 | 
|---|
| 2236 |       for(iPos = iCount-1;iPos>=0;iPos--)
 | 
|---|
| 2237 |       {
 | 
|---|
| 2238 |         SFOLDER *tmpFolder = (LPSFOLDER) CBGetItemDataPtr(fodInfos->DlgInfos.hwndLookInCB,iPos);
 | 
|---|
| 2239 |         COMDLG32_SHFree(tmpFolder->pidlItem);
 | 
|---|
| 2240 |         MemFree(tmpFolder);
 | 
|---|
| 2241 |         CBDeleteString(fodInfos->DlgInfos.hwndLookInCB,iPos);
 | 
|---|
| 2242 |       }
 | 
|---|
| 2243 |     }
 | 
|---|
| 2244 | 
 | 
|---|
| 2245 |     /* LookInInfos structure */
 | 
|---|
| 2246 |     RemovePropA(fodInfos->DlgInfos.hwndLookInCB,LookInInfosStr);
 | 
|---|
| 2247 | 
 | 
|---|
| 2248 | }
 | 
|---|
| 2249 | /***********************************************************************
 | 
|---|
| 2250 |  * FILEDLG95_FILENAME_FillFromSelection
 | 
|---|
| 2251 |  *
 | 
|---|
| 2252 |  * fills the edit box from the cached DataObject
 | 
|---|
| 2253 |  */
 | 
|---|
| 2254 | void FILEDLG95_FILENAME_FillFromSelection (HWND hwnd)
 | 
|---|
| 2255 | {
 | 
|---|
| 2256 |     FileOpenDlgInfos *fodInfos;
 | 
|---|
| 2257 |     LPITEMIDLIST      pidl;
 | 
|---|
| 2258 |     UINT              nFiles = 0, nFileToOpen, nFileSelected, nLength = 0;
 | 
|---|
| 2259 |     char              lpstrTemp[MAX_PATH];
 | 
|---|
| 2260 |     LPSTR             lpstrAllFile = NULL, lpstrCurrFile = NULL;
 | 
|---|
| 2261 | 
 | 
|---|
| 2262 |     TRACE("\n");
 | 
|---|
| 2263 |     fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 2264 | 
 | 
|---|
| 2265 |     /* Count how many files we have */
 | 
|---|
| 2266 |     nFileSelected = GetNumSelected( fodInfos->Shell.FOIDataObject );
 | 
|---|
| 2267 | 
 | 
|---|
| 2268 |     /* calculate the string length, count files */
 | 
|---|
| 2269 |     if (nFileSelected >= 1)
 | 
|---|
| 2270 |     {
 | 
|---|
| 2271 |       nLength += 3;     /* first and last quotes, trailing \0 */
 | 
|---|
| 2272 |       for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
 | 
|---|
| 2273 |       {
 | 
|---|
| 2274 |         pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
 | 
|---|
| 2275 |     
 | 
|---|
| 2276 |         if (pidl)
 | 
|---|
| 2277 |         {
 | 
|---|
| 2278 |           /* get the total length of the selected file names*/
 | 
|---|
| 2279 |           lpstrTemp[0] = '\0';
 | 
|---|
| 2280 |           GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER, lpstrTemp );
 | 
|---|
| 2281 | 
 | 
|---|
| 2282 |           if ( ! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl) ) /* Ignore folders */
 | 
|---|
| 2283 |           {
 | 
|---|
| 2284 |             nLength += strlen( lpstrTemp ) + 3;
 | 
|---|
| 2285 |             nFiles++;
 | 
|---|
| 2286 |           }
 | 
|---|
| 2287 |           COMDLG32_SHFree( pidl );
 | 
|---|
| 2288 |         }
 | 
|---|
| 2289 |       }
 | 
|---|
| 2290 |     }
 | 
|---|
| 2291 | 
 | 
|---|
| 2292 |     /* allocate the buffer */
 | 
|---|
| 2293 |     if (nFiles <= 1) nLength = MAX_PATH;
 | 
|---|
| 2294 |     lpstrAllFile = (LPSTR)HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, nLength);
 | 
|---|
| 2295 |     lpstrAllFile[0] = '\0';
 | 
|---|
| 2296 | 
 | 
|---|
| 2297 |     /* Generate the string for the edit control */
 | 
|---|
| 2298 |     if(nFiles >= 1)
 | 
|---|
| 2299 |     {
 | 
|---|
| 2300 |       lpstrCurrFile = lpstrAllFile;
 | 
|---|
| 2301 |       for ( nFileToOpen = 0; nFileToOpen < nFileSelected; nFileToOpen++ )
 | 
|---|
| 2302 |       {
 | 
|---|
| 2303 |         pidl = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, nFileToOpen+1 );
 | 
|---|
| 2304 | 
 | 
|---|
| 2305 |         if (pidl)
 | 
|---|
| 2306 |         {
 | 
|---|
| 2307 |           /* get the file name */
 | 
|---|
| 2308 |           lpstrTemp[0] = '\0';
 | 
|---|
| 2309 |           GetName( fodInfos->Shell.FOIShellFolder, pidl, SHGDN_INFOLDER, lpstrTemp );
 | 
|---|
| 2310 | 
 | 
|---|
| 2311 |           if (! IsPidlFolder(fodInfos->Shell.FOIShellFolder, pidl)) /* Ignore folders */
 | 
|---|
| 2312 |           {
 | 
|---|
| 2313 |             if ( nFiles > 1)
 | 
|---|
| 2314 |             {
 | 
|---|
| 2315 |               *lpstrCurrFile++ =  '\"';
 | 
|---|
| 2316 |               strcpy( lpstrCurrFile, lpstrTemp );
 | 
|---|
| 2317 |               lpstrCurrFile += strlen( lpstrTemp );
 | 
|---|
| 2318 |               strcpy( lpstrCurrFile, "\" " );
 | 
|---|
| 2319 |               lpstrCurrFile += 2;
 | 
|---|
| 2320 |             }
 | 
|---|
| 2321 |             else
 | 
|---|
| 2322 |             {
 | 
|---|
| 2323 |               strcpy( lpstrAllFile, lpstrTemp );
 | 
|---|
| 2324 |             }
 | 
|---|
| 2325 |           }
 | 
|---|
| 2326 |           COMDLG32_SHFree( (LPVOID) pidl );
 | 
|---|
| 2327 |         }
 | 
|---|
| 2328 |       }
 | 
|---|
| 2329 |     }
 | 
|---|
| 2330 | 
 | 
|---|
| 2331 |     SetWindowTextA( fodInfos->DlgInfos.hwndFileName, lpstrAllFile );
 | 
|---|
| 2332 |     HeapFree(GetProcessHeap(),0, lpstrAllFile );
 | 
|---|
| 2333 | }
 | 
|---|
| 2334 | 
 | 
|---|
| 2335 | 
 | 
|---|
| 2336 | /* copied from shell32 to avoid linking to it */
 | 
|---|
| 2337 | static HRESULT COMDLG32_StrRetToStrNA (LPVOID dest, DWORD len, LPSTRRET src, LPITEMIDLIST pidl)
 | 
|---|
| 2338 | {
 | 
|---|
| 2339 |         switch (src->uType)
 | 
|---|
| 2340 |         {
 | 
|---|
| 2341 |           case STRRET_WSTR:
 | 
|---|
| 2342 |             WideCharToMultiByte(CP_ACP, 0, src->u.pOleStr, -1, (LPSTR)dest, len, NULL, NULL);
 | 
|---|
| 2343 |             COMDLG32_SHFree(src->u.pOleStr);
 | 
|---|
| 2344 |             break;
 | 
|---|
| 2345 | 
 | 
|---|
| 2346 |           case STRRET_CSTRA:
 | 
|---|
| 2347 |             lstrcpynA((LPSTR)dest, src->u.cStr, len);
 | 
|---|
| 2348 |             break;
 | 
|---|
| 2349 | 
 | 
|---|
| 2350 |           case STRRET_OFFSETA:
 | 
|---|
| 2351 |             lstrcpynA((LPSTR)dest, ((LPCSTR)&pidl->mkid)+src->u.uOffset, len);
 | 
|---|
| 2352 |             break;
 | 
|---|
| 2353 | 
 | 
|---|
| 2354 |           default:
 | 
|---|
| 2355 |             FIXME("unknown type!\n");
 | 
|---|
| 2356 |             if (len)
 | 
|---|
| 2357 |             {
 | 
|---|
| 2358 |               *(LPSTR)dest = '\0';
 | 
|---|
| 2359 |             }
 | 
|---|
| 2360 |             return(FALSE);
 | 
|---|
| 2361 |         }
 | 
|---|
| 2362 |         return S_OK;
 | 
|---|
| 2363 | }
 | 
|---|
| 2364 | 
 | 
|---|
| 2365 | /***********************************************************************
 | 
|---|
| 2366 |  * FILEDLG95_FILENAME_GetFileNames
 | 
|---|
| 2367 |  *
 | 
|---|
| 2368 |  * copies the filenames to a 0-delimited string list (A\0B\0C\0\0)
 | 
|---|
| 2369 |  */
 | 
|---|
| 2370 | int FILEDLG95_FILENAME_GetFileNames (HWND hwnd, LPSTR * lpstrFileList, UINT * sizeUsed)
 | 
|---|
| 2371 | {
 | 
|---|
| 2372 |         FileOpenDlgInfos *fodInfos  = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 2373 |         UINT nStrCharCount = 0; /* index in src buffer */
 | 
|---|
| 2374 |         UINT nFileIndex = 0;    /* index in dest buffer */
 | 
|---|
| 2375 |         UINT nFileCount = 0;    /* number of files */
 | 
|---|
| 2376 |         UINT nStrLen = 0;       /* length of string in edit control */
 | 
|---|
| 2377 |         LPSTR lpstrEdit;        /* buffer for string from edit control */
 | 
|---|
| 2378 | 
 | 
|---|
| 2379 |         TRACE("\n");
 | 
|---|
| 2380 | 
 | 
|---|
| 2381 |         /* get the filenames from the edit control */
 | 
|---|
| 2382 |         nStrLen = SendMessageA(fodInfos->DlgInfos.hwndFileName, WM_GETTEXTLENGTH, 0, 0);
 | 
|---|
| 2383 |         lpstrEdit = MemAlloc(nStrLen+1);
 | 
|---|
| 2384 |         GetDlgItemTextA(hwnd, IDC_FILENAME, lpstrEdit, nStrLen+1);
 | 
|---|
| 2385 | 
 | 
|---|
| 2386 |         TRACE("nStrLen=%u str=%s\n", nStrLen, lpstrEdit);
 | 
|---|
| 2387 |         
 | 
|---|
| 2388 |         /* we might get single filename without any '"',
 | 
|---|
| 2389 |          * so we need nStrLen + terminating \0 + end-of-list \0 */
 | 
|---|
| 2390 |         *lpstrFileList = MemAlloc(nStrLen+2);
 | 
|---|
| 2391 |         *sizeUsed = 0;
 | 
|---|
| 2392 | 
 | 
|---|
| 2393 |         /* build 0-delimited file list from filenames */
 | 
|---|
| 2394 |         while ( nStrCharCount <= nStrLen )
 | 
|---|
| 2395 |         {
 | 
|---|
| 2396 |           if ( lpstrEdit[nStrCharCount]=='"' )
 | 
|---|
| 2397 |           {
 | 
|---|
| 2398 |             nStrCharCount++;
 | 
|---|
| 2399 |             while ((lpstrEdit[nStrCharCount]!='"') && (nStrCharCount <= nStrLen))
 | 
|---|
| 2400 |             {
 | 
|---|
| 2401 |               (*lpstrFileList)[nFileIndex++] = lpstrEdit[nStrCharCount];
 | 
|---|
| 2402 |               (*sizeUsed)++;
 | 
|---|
| 2403 |               nStrCharCount++;
 | 
|---|
| 2404 |             }
 | 
|---|
| 2405 |             (*lpstrFileList)[nFileIndex++] = '\0';
 | 
|---|
| 2406 |             (*sizeUsed)++;
 | 
|---|
| 2407 |             nFileCount++;
 | 
|---|
| 2408 |           } 
 | 
|---|
| 2409 |           nStrCharCount++;
 | 
|---|
| 2410 |         }
 | 
|---|
| 2411 | 
 | 
|---|
| 2412 |         /* single, unquoted string */
 | 
|---|
| 2413 |         if ((nStrLen > 0) && (*sizeUsed == 0) )
 | 
|---|
| 2414 |         {
 | 
|---|
| 2415 |           strcpy(*lpstrFileList, lpstrEdit);
 | 
|---|
| 2416 |           nFileIndex = strlen(lpstrEdit) + 1;
 | 
|---|
| 2417 |           (*sizeUsed) = nFileIndex;
 | 
|---|
| 2418 |           nFileCount = 1;
 | 
|---|
| 2419 |         }
 | 
|---|
| 2420 | 
 | 
|---|
| 2421 |         /* trailing \0 */
 | 
|---|
| 2422 |         (*lpstrFileList)[nFileIndex] = '\0';
 | 
|---|
| 2423 |         (*sizeUsed)++;
 | 
|---|
| 2424 | 
 | 
|---|
| 2425 |         MemFree(lpstrEdit);
 | 
|---|
| 2426 |         return nFileCount;
 | 
|---|
| 2427 | }
 | 
|---|
| 2428 | 
 | 
|---|
| 2429 | #define SETDefFormatEtc(fe,cf,med) \
 | 
|---|
| 2430 | { \
 | 
|---|
| 2431 |     (fe).cfFormat = cf;\
 | 
|---|
| 2432 |     (fe).dwAspect = DVASPECT_CONTENT; \
 | 
|---|
| 2433 |     (fe).ptd =NULL;\
 | 
|---|
| 2434 |     (fe).tymed = med;\
 | 
|---|
| 2435 |     (fe).lindex = -1;\
 | 
|---|
| 2436 | };
 | 
|---|
| 2437 | 
 | 
|---|
| 2438 | /*
 | 
|---|
| 2439 |  * DATAOBJECT Helper functions
 | 
|---|
| 2440 |  */
 | 
|---|
| 2441 | 
 | 
|---|
| 2442 | /***********************************************************************
 | 
|---|
| 2443 |  * COMCTL32_ReleaseStgMedium
 | 
|---|
| 2444 |  *
 | 
|---|
| 2445 |  * like ReleaseStgMedium from ole32
 | 
|---|
| 2446 |  */
 | 
|---|
| 2447 | static void COMCTL32_ReleaseStgMedium (STGMEDIUM medium)
 | 
|---|
| 2448 | {
 | 
|---|
| 2449 |       if(medium.pUnkForRelease)
 | 
|---|
| 2450 |       {
 | 
|---|
| 2451 |         IUnknown_Release(medium.pUnkForRelease);
 | 
|---|
| 2452 |       }
 | 
|---|
| 2453 |       else
 | 
|---|
| 2454 |       {
 | 
|---|
| 2455 |         GlobalUnlock(medium.u.hGlobal);
 | 
|---|
| 2456 |         GlobalFree(medium.u.hGlobal);
 | 
|---|
| 2457 |       }
 | 
|---|
| 2458 | }
 | 
|---|
| 2459 | 
 | 
|---|
| 2460 | /***********************************************************************
 | 
|---|
| 2461 |  *          GetPidlFromDataObject
 | 
|---|
| 2462 |  *
 | 
|---|
| 2463 |  * Return pidl(s) by number from the cached DataObject
 | 
|---|
| 2464 |  *
 | 
|---|
| 2465 |  * nPidlIndex=0 gets the fully qualified root path
 | 
|---|
| 2466 |  */
 | 
|---|
| 2467 | LPITEMIDLIST GetPidlFromDataObject ( IDataObject *doSelected, UINT nPidlIndex)
 | 
|---|
| 2468 | {
 | 
|---|
| 2469 |      
 | 
|---|
| 2470 |     STGMEDIUM medium;
 | 
|---|
| 2471 |     FORMATETC formatetc;
 | 
|---|
| 2472 |     LPITEMIDLIST pidl = NULL;
 | 
|---|
| 2473 |     
 | 
|---|
| 2474 |     TRACE("sv=%p index=%u\n", doSelected, nPidlIndex);
 | 
|---|
| 2475 |     
 | 
|---|
| 2476 |     /* Set the FORMATETC structure*/
 | 
|---|
| 2477 |     SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
 | 
|---|
| 2478 | 
 | 
|---|
| 2479 |     /* Get the pidls from IDataObject */
 | 
|---|
| 2480 |     if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
 | 
|---|
| 2481 |     {
 | 
|---|
| 2482 |       LPIDA cida = GlobalLock(medium.u.hGlobal);
 | 
|---|
| 2483 |       if(nPidlIndex <= cida->cidl)
 | 
|---|
| 2484 |       {
 | 
|---|
| 2485 |         pidl = COMDLG32_PIDL_ILClone((LPITEMIDLIST)(&((LPBYTE)cida)[cida->aoffset[nPidlIndex]]));
 | 
|---|
| 2486 |       }
 | 
|---|
| 2487 |       COMCTL32_ReleaseStgMedium(medium);
 | 
|---|
| 2488 |     }
 | 
|---|
| 2489 |     return pidl;
 | 
|---|
| 2490 | }
 | 
|---|
| 2491 | 
 | 
|---|
| 2492 | /***********************************************************************
 | 
|---|
| 2493 |  *          GetNumSelected
 | 
|---|
| 2494 |  *
 | 
|---|
| 2495 |  * Return the number of selected items in the DataObject.
 | 
|---|
| 2496 |  *
 | 
|---|
| 2497 | */
 | 
|---|
| 2498 | UINT GetNumSelected( IDataObject *doSelected )
 | 
|---|
| 2499 | {
 | 
|---|
| 2500 |     UINT retVal = 0;
 | 
|---|
| 2501 |     STGMEDIUM medium;
 | 
|---|
| 2502 |     FORMATETC formatetc;
 | 
|---|
| 2503 | 
 | 
|---|
| 2504 |     TRACE("sv=%p\n", doSelected);
 | 
|---|
| 2505 | 
 | 
|---|
| 2506 |     if (!doSelected) return 0;
 | 
|---|
| 2507 | 
 | 
|---|
| 2508 |     /* Set the FORMATETC structure*/
 | 
|---|
| 2509 |     SETDefFormatEtc(formatetc, RegisterClipboardFormatA(CFSTR_SHELLIDLIST), TYMED_HGLOBAL);
 | 
|---|
| 2510 | 
 | 
|---|
| 2511 |     /* Get the pidls from IDataObject */
 | 
|---|
| 2512 |     if(SUCCEEDED(IDataObject_GetData(doSelected,&formatetc,&medium)))
 | 
|---|
| 2513 |     {
 | 
|---|
| 2514 |       LPIDA cida = GlobalLock(medium.u.hGlobal);
 | 
|---|
| 2515 |       retVal = cida->cidl;
 | 
|---|
| 2516 |       COMCTL32_ReleaseStgMedium(medium);
 | 
|---|
| 2517 |       return retVal;
 | 
|---|
| 2518 |     }
 | 
|---|
| 2519 |     return 0;
 | 
|---|
| 2520 | }
 | 
|---|
| 2521 | 
 | 
|---|
| 2522 | /*
 | 
|---|
| 2523 |  * TOOLS
 | 
|---|
| 2524 |  */
 | 
|---|
| 2525 | 
 | 
|---|
| 2526 | /***********************************************************************
 | 
|---|
| 2527 |  *      GetName
 | 
|---|
| 2528 |  *
 | 
|---|
| 2529 |  * Get the pidl's display name (relative to folder) and 
 | 
|---|
| 2530 |  * put it in lpstrFileName.
 | 
|---|
| 2531 |  * 
 | 
|---|
| 2532 |  * Return NOERROR on success,
 | 
|---|
| 2533 |  * E_FAIL otherwise
 | 
|---|
| 2534 |  */
 | 
|---|
| 2535 | 
 | 
|---|
| 2536 | HRESULT GetName(LPSHELLFOLDER lpsf, LPITEMIDLIST pidl,DWORD dwFlags,LPSTR lpstrFileName)
 | 
|---|
| 2537 | {
 | 
|---|
| 2538 |   STRRET str;
 | 
|---|
| 2539 |   HRESULT hRes;
 | 
|---|
| 2540 | 
 | 
|---|
| 2541 |   TRACE("sf=%p pidl=%p\n", lpsf, pidl);
 | 
|---|
| 2542 | 
 | 
|---|
| 2543 |   if(!lpsf)
 | 
|---|
| 2544 |   {
 | 
|---|
| 2545 |     HRESULT hRes;
 | 
|---|
| 2546 |     COMDLG32_SHGetDesktopFolder(&lpsf);
 | 
|---|
| 2547 |     hRes = GetName(lpsf,pidl,dwFlags,lpstrFileName);
 | 
|---|
| 2548 |     IShellFolder_Release(lpsf);
 | 
|---|
| 2549 |     return hRes;
 | 
|---|
| 2550 |   }
 | 
|---|
| 2551 | 
 | 
|---|
| 2552 |   /* Get the display name of the pidl relative to the folder */
 | 
|---|
| 2553 |   if (SUCCEEDED(hRes = IShellFolder_GetDisplayNameOf(lpsf, pidl, dwFlags, &str)))
 | 
|---|
| 2554 |   {
 | 
|---|
| 2555 |       return COMDLG32_StrRetToStrNA(lpstrFileName, MAX_PATH, &str, pidl);
 | 
|---|
| 2556 |   }
 | 
|---|
| 2557 |   return E_FAIL;
 | 
|---|
| 2558 | }
 | 
|---|
| 2559 | 
 | 
|---|
| 2560 | /***********************************************************************
 | 
|---|
| 2561 |  *      GetShellFolderFromPidl
 | 
|---|
| 2562 |  *
 | 
|---|
| 2563 |  * pidlRel is the item pidl relative 
 | 
|---|
| 2564 |  * Return the IShellFolder of the absolute pidl
 | 
|---|
| 2565 |  */
 | 
|---|
| 2566 | IShellFolder *GetShellFolderFromPidl(LPITEMIDLIST pidlAbs)
 | 
|---|
| 2567 | {
 | 
|---|
| 2568 |   IShellFolder *psf = NULL,*psfParent;
 | 
|---|
| 2569 | 
 | 
|---|
| 2570 |   TRACE("%p\n", pidlAbs);
 | 
|---|
| 2571 | 
 | 
|---|
| 2572 |   if(SUCCEEDED(COMDLG32_SHGetDesktopFolder(&psfParent)))
 | 
|---|
| 2573 |   {
 | 
|---|
| 2574 |     psf = psfParent;
 | 
|---|
| 2575 |     if(pidlAbs && pidlAbs->mkid.cb)
 | 
|---|
| 2576 |     {
 | 
|---|
| 2577 |       if(SUCCEEDED(IShellFolder_BindToObject(psfParent, pidlAbs, NULL, &IID_IShellFolder, (LPVOID*)&psf)))
 | 
|---|
| 2578 |       {
 | 
|---|
| 2579 |         IShellFolder_Release(psfParent);
 | 
|---|
| 2580 |         return psf;
 | 
|---|
| 2581 |       }
 | 
|---|
| 2582 |     }
 | 
|---|
| 2583 |     /* return the desktop */
 | 
|---|
| 2584 |     return psfParent;
 | 
|---|
| 2585 |   }
 | 
|---|
| 2586 |   return NULL;
 | 
|---|
| 2587 | }
 | 
|---|
| 2588 | 
 | 
|---|
| 2589 | /***********************************************************************
 | 
|---|
| 2590 |  *      GetParentPidl
 | 
|---|
| 2591 |  *
 | 
|---|
| 2592 |  * Return the LPITEMIDLIST to the parent of the pidl in the list
 | 
|---|
| 2593 |  */
 | 
|---|
| 2594 | LPITEMIDLIST GetParentPidl(LPITEMIDLIST pidl)
 | 
|---|
| 2595 | {
 | 
|---|
| 2596 |   LPITEMIDLIST pidlParent;
 | 
|---|
| 2597 | 
 | 
|---|
| 2598 |   TRACE("%p\n", pidl);
 | 
|---|
| 2599 | 
 | 
|---|
| 2600 |   pidlParent = COMDLG32_PIDL_ILClone(pidl);
 | 
|---|
| 2601 |   COMDLG32_PIDL_ILRemoveLastID(pidlParent);
 | 
|---|
| 2602 |      
 | 
|---|
| 2603 |   return pidlParent;
 | 
|---|
| 2604 | }
 | 
|---|
| 2605 | 
 | 
|---|
| 2606 | /***********************************************************************
 | 
|---|
| 2607 |  *      GetPidlFromName
 | 
|---|
| 2608 |  *
 | 
|---|
| 2609 |  * returns the pidl of the file name relative to folder 
 | 
|---|
| 2610 |  * NULL if an error occured
 | 
|---|
| 2611 |  */
 | 
|---|
| 2612 | LPITEMIDLIST GetPidlFromName(IShellFolder *lpsf,LPCSTR lpcstrFileName)
 | 
|---|
| 2613 | {
 | 
|---|
| 2614 |   LPITEMIDLIST pidl;
 | 
|---|
| 2615 |   ULONG ulEaten;
 | 
|---|
| 2616 |   WCHAR lpwstrDirName[MAX_PATH];
 | 
|---|
| 2617 | 
 | 
|---|
| 2618 |   TRACE("sf=%p file=%s\n", lpsf, lpcstrFileName);
 | 
|---|
| 2619 | 
 | 
|---|
| 2620 |   if(!lpcstrFileName) return NULL;
 | 
|---|
| 2621 |     
 | 
|---|
| 2622 |   MultiByteToWideChar(CP_ACP,MB_PRECOMPOSED,lpcstrFileName,-1,(LPWSTR)lpwstrDirName,MAX_PATH);  
 | 
|---|
| 2623 | 
 | 
|---|
| 2624 |   if(!lpsf)
 | 
|---|
| 2625 |   {
 | 
|---|
| 2626 |     COMDLG32_SHGetDesktopFolder(&lpsf);
 | 
|---|
| 2627 |     pidl = GetPidlFromName(lpsf, lpcstrFileName);
 | 
|---|
| 2628 |     IShellFolder_Release(lpsf);
 | 
|---|
| 2629 |   }
 | 
|---|
| 2630 |   else
 | 
|---|
| 2631 |   {
 | 
|---|
| 2632 |     IShellFolder_ParseDisplayName(lpsf, 0, NULL, (LPWSTR)lpwstrDirName, &ulEaten, &pidl, NULL); 
 | 
|---|
| 2633 |   }
 | 
|---|
| 2634 |   return pidl;
 | 
|---|
| 2635 | }
 | 
|---|
| 2636 | 
 | 
|---|
| 2637 | /*
 | 
|---|
| 2638 | */
 | 
|---|
| 2639 | BOOL IsPidlFolder (LPSHELLFOLDER psf, LPITEMIDLIST pidl)
 | 
|---|
| 2640 | {
 | 
|---|
| 2641 |         ULONG uAttr  = SFGAO_FOLDER | SFGAO_HASSUBFOLDER;
 | 
|---|
| 2642 |         HRESULT ret;
 | 
|---|
| 2643 |         
 | 
|---|
| 2644 |         TRACE("%p, %p\n", psf, pidl);
 | 
|---|
| 2645 |         
 | 
|---|
| 2646 |         ret = IShellFolder_GetAttributesOf( psf, 1, &pidl, &uAttr );
 | 
|---|
| 2647 |         
 | 
|---|
| 2648 |         TRACE("-- 0x%08lx 0x%08lx\n", uAttr, ret);
 | 
|---|
| 2649 |         /* see documentation shell 4.1*/
 | 
|---|
| 2650 |         return uAttr & (SFGAO_FOLDER | SFGAO_HASSUBFOLDER);
 | 
|---|
| 2651 | }
 | 
|---|
| 2652 | 
 | 
|---|
| 2653 | /***********************************************************************
 | 
|---|
| 2654 |  *      BrowseSelectedFolder
 | 
|---|
| 2655 |  */
 | 
|---|
| 2656 | static BOOL BrowseSelectedFolder(HWND hwnd)
 | 
|---|
| 2657 | {
 | 
|---|
| 2658 |   BOOL bBrowseSelFolder = FALSE;
 | 
|---|
| 2659 |   FileOpenDlgInfos *fodInfos = (FileOpenDlgInfos *) GetPropA(hwnd,FileOpenDlgInfosStr);
 | 
|---|
| 2660 | 
 | 
|---|
| 2661 |   TRACE("\n");
 | 
|---|
| 2662 | 
 | 
|---|
| 2663 |   if (GetNumSelected(fodInfos->Shell.FOIDataObject) == 1)
 | 
|---|
| 2664 |   {
 | 
|---|
| 2665 |       LPITEMIDLIST pidlSelection;
 | 
|---|
| 2666 | 
 | 
|---|
| 2667 |       /* get the file selected */
 | 
|---|
| 2668 |       pidlSelection  = GetPidlFromDataObject( fodInfos->Shell.FOIDataObject, 1);
 | 
|---|
| 2669 |       if (IsPidlFolder (fodInfos->Shell.FOIShellFolder, pidlSelection))
 | 
|---|
| 2670 |       {
 | 
|---|
| 2671 |           if ( FAILED( IShellBrowser_BrowseObject( fodInfos->Shell.FOIShellBrowser,
 | 
|---|
| 2672 |                          pidlSelection, SBSP_RELATIVE ) ) )
 | 
|---|
| 2673 |           {
 | 
|---|
| 2674 |                MessageBoxA( hwnd, "Path does not exist", fodInfos->ofnInfos->lpstrTitle,
 | 
|---|
| 2675 |                       MB_OK | MB_ICONEXCLAMATION );
 | 
|---|
| 2676 |           }
 | 
|---|
| 2677 | 
 | 
|---|
| 2678 |          bBrowseSelFolder = TRUE;
 | 
|---|
| 2679 |       }
 | 
|---|
| 2680 |       COMDLG32_SHFree( pidlSelection );
 | 
|---|
| 2681 |   }
 | 
|---|
| 2682 | 
 | 
|---|
| 2683 |   return bBrowseSelFolder;
 | 
|---|
| 2684 | } 
 | 
|---|
| 2685 | 
 | 
|---|
| 2686 | /*
 | 
|---|
| 2687 |  * Memory allocation methods */
 | 
|---|
| 2688 | static void *MemAlloc(UINT size)
 | 
|---|
| 2689 | {
 | 
|---|
| 2690 |     return HeapAlloc(GetProcessHeap(),HEAP_ZERO_MEMORY,size);
 | 
|---|
| 2691 | }
 | 
|---|
| 2692 | 
 | 
|---|
| 2693 | static void MemFree(void *mem)
 | 
|---|
| 2694 | {
 | 
|---|
| 2695 |     if(mem)
 | 
|---|
| 2696 |     {
 | 
|---|
| 2697 |         HeapFree(GetProcessHeap(),0,mem);
 | 
|---|
| 2698 |     }
 | 
|---|
| 2699 | }
 | 
|---|
| 2700 | 
 | 
|---|