summaryrefslogtreecommitdiffstats
path: root/docs/release/src/osd/winui/directories.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'docs/release/src/osd/winui/directories.cpp')
-rw-r--r--docs/release/src/osd/winui/directories.cpp703
1 files changed, 703 insertions, 0 deletions
diff --git a/docs/release/src/osd/winui/directories.cpp b/docs/release/src/osd/winui/directories.cpp
new file mode 100644
index 00000000000..034ed91f2fa
--- /dev/null
+++ b/docs/release/src/osd/winui/directories.cpp
@@ -0,0 +1,703 @@
+// For licensing and usage information, read docs/winui_license.txt
+// MASTER
+//****************************************************************************
+
+/***************************************************************************
+
+ directories.c
+
+***************************************************************************/
+
+// standard windows headers
+#include <windows.h>
+#include <windowsx.h>
+
+// standard C headers
+#include <sys/stat.h> // S_IFDIR
+#include <tchar.h>
+
+// MAME/MAMEUI headers
+#include "directories.h"
+#include "resource.h"
+#include "mui_util.h"
+
+// SHELL DIR header
+#include <shlobj.h>
+
+#define MAX_DIRS 256
+
+/***************************************************************************
+ Internal structures
+ ***************************************************************************/
+
+typedef struct
+{
+ TCHAR m_Directories[MAX_DIRS][MAX_PATH];
+ int m_NumDirectories;
+ BOOL m_bModified;
+} tPath;
+
+typedef struct
+{
+ tPath *m_Path;
+ TCHAR *m_tDirectory;
+} tDirInfo;
+
+/***************************************************************************
+ Function prototypes
+ ***************************************************************************/
+
+static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData);
+BOOL BrowseForDirectory(HWND hwnd, LPCTSTR pStartDir, TCHAR* pResult);
+
+static void DirInfo_SetDir(tDirInfo *pInfo, int nType, int nItem, LPCTSTR pText);
+static TCHAR* DirInfo_Dir(tDirInfo *pInfo, int nType);
+static TCHAR* DirInfo_Path(tDirInfo *pInfo, int nType, int nItem);
+static void DirInfo_SetModified(tDirInfo *pInfo, int nType, BOOL bModified);
+static BOOL DirInfo_Modified(tDirInfo *pInfo, int nType);
+static TCHAR* FixSlash(TCHAR *s);
+
+static void UpdateDirectoryList(HWND hDlg);
+
+static void Directories_OnSelChange(HWND hDlg);
+static BOOL Directories_OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lParam);
+static void Directories_OnDestroy(HWND hDlg);
+static void Directories_OnClose(HWND hDlg);
+static void Directories_OnOk(HWND hDlg);
+static void Directories_OnCancel(HWND hDlg);
+static void Directories_OnInsert(HWND hDlg);
+static void Directories_OnBrowse(HWND hDlg);
+static void Directories_OnDelete(HWND hDlg);
+static BOOL Directories_OnBeginLabelEdit(HWND hDlg, NMHDR* pNMHDR);
+static BOOL Directories_OnEndLabelEdit(HWND hDlg, NMHDR* pNMHDR);
+static void Directories_OnCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify);
+static BOOL Directories_OnNotify(HWND hDlg, int id, NMHDR* pNMHDR);
+
+/***************************************************************************
+ External variables
+ ***************************************************************************/
+
+/***************************************************************************
+ Internal variables
+ ***************************************************************************/
+
+static tDirInfo *g_pDirInfo;
+
+/***************************************************************************
+ External function definitions
+ ***************************************************************************/
+
+INT_PTR CALLBACK DirectoriesDialogProc(HWND hDlg, UINT Msg, WPARAM wParam, LPARAM lParam)
+{
+ BOOL bReturn = false;
+
+ switch (Msg)
+ {
+ case WM_INITDIALOG:
+ return (BOOL)HANDLE_WM_INITDIALOG(hDlg, wParam, lParam, Directories_OnInitDialog);
+
+ case WM_COMMAND:
+ HANDLE_WM_COMMAND(hDlg, wParam, lParam, Directories_OnCommand);
+ bReturn = true;
+ break;
+
+ case WM_NOTIFY:
+ return (BOOL)HANDLE_WM_NOTIFY(hDlg, wParam, lParam, Directories_OnNotify);
+
+ case WM_CLOSE:
+ HANDLE_WM_CLOSE(hDlg, wParam, lParam, Directories_OnClose);
+ break;
+
+ case WM_DESTROY:
+ HANDLE_WM_DESTROY(hDlg, wParam, lParam, Directories_OnDestroy);
+ break;
+
+ default:
+ break;
+ }
+ return bReturn;
+}
+
+/***************************************************************************
+ Internal function definitions
+ ***************************************************************************/
+
+static BOOL IsMultiDir(int nType)
+{
+ return g_directoryInfo[nType].bMulti;
+}
+
+static void DirInfo_SetDir(tDirInfo *pInfo, int nType, int nItem, LPCTSTR pText)
+{
+ TCHAR *t_s;
+ TCHAR *t_pOldText;
+
+ if (IsMultiDir(nType))
+ {
+ assert(nItem >= 0);
+ _tcscpy(DirInfo_Path(pInfo, nType, nItem), pText);
+ DirInfo_SetModified(pInfo, nType, TRUE);
+ }
+ else
+ {
+ t_s = win_tstring_strdup(pText);
+ if (!t_s)
+ return;
+ t_pOldText = pInfo[nType].m_tDirectory;
+ if (t_pOldText)
+ free(t_pOldText);
+ pInfo[nType].m_tDirectory = t_s; // don't free t_s else directory name is corrupted
+ }
+}
+
+static TCHAR* DirInfo_Dir(tDirInfo *pInfo, int nType)
+{
+ // if a multipath exists in a single-path-only area then truncate it
+ return _tcstok(pInfo[nType].m_tDirectory, TEXT(";"));
+}
+
+static TCHAR* DirInfo_Path(tDirInfo *pInfo, int nType, int nItem)
+{
+ return pInfo[nType].m_Path->m_Directories[nItem];
+}
+
+static void DirInfo_SetModified(tDirInfo *pInfo, int nType, BOOL bModified)
+{
+ //assert(IsMultiDir(nType));
+ pInfo[nType].m_Path->m_bModified = bModified;
+}
+
+static BOOL DirInfo_Modified(tDirInfo *pInfo, int nType)
+{
+ //assert(IsMultiDir(nType));
+ return pInfo[nType].m_Path->m_bModified;
+}
+
+#define DirInfo_NumDir(pInfo, path) \
+ ((pInfo)[(path)].m_Path->m_NumDirectories)
+
+/* lop off trailing backslash if it exists */
+static TCHAR * FixSlash(TCHAR *s)
+{
+ int len = 0;
+
+ if (s)
+ len = _tcslen(s);
+
+ if (len>3 && s[len - 1] == '\\')
+ s[len - 1] = '\0';
+
+ return s;
+}
+
+static void UpdateDirectoryList(HWND hDlg)
+{
+ HWND hList = GetDlgItem(hDlg, IDC_DIR_LIST);
+ HWND hCombo = GetDlgItem(hDlg, IDC_DIR_COMBO);
+
+ /* Remove previous */
+ BOOL b_res = ListView_DeleteAllItems(hList);
+
+ /* Update list */
+ LV_ITEM Item;
+ memset(&Item, 0, sizeof(LV_ITEM));
+ Item.mask = LVIF_TEXT;
+
+ int nType = ComboBox_GetCurSel(hCombo);
+ if (IsMultiDir(nType))
+ {
+ Item.pszText = (TCHAR*) TEXT(DIRLIST_NEWENTRYTEXT); // puts the < > empty entry in
+ (void)ListView_InsertItem(hList, &Item);
+ int t = DirInfo_NumDir(g_pDirInfo, nType);
+ // directories are inserted in reverse order
+ for (int i = t; 0 < i; i--)
+ {
+ Item.pszText = DirInfo_Path(g_pDirInfo, nType, i-1);
+ (void)ListView_InsertItem(hList, &Item);
+ }
+ }
+ else
+ {
+ Item.pszText = DirInfo_Dir(g_pDirInfo, nType);
+ (void)ListView_InsertItem(hList, &Item);
+ }
+
+ /* select first one */
+
+ ListView_SetItemState(hList, 0, LVIS_SELECTED, LVIS_SELECTED);
+ b_res++;
+}
+
+static void Directories_OnSelChange(HWND hDlg)
+{
+ UpdateDirectoryList(hDlg);
+
+ HWND hCombo = GetDlgItem(hDlg, IDC_DIR_COMBO);
+ int nType = ComboBox_GetCurSel(hCombo);
+ if (IsMultiDir(nType))
+ {
+ EnableWindow(GetDlgItem(hDlg, IDC_DIR_DELETE), TRUE);
+ EnableWindow(GetDlgItem(hDlg, IDC_DIR_INSERT), TRUE);
+ }
+ else
+ {
+ EnableWindow(GetDlgItem(hDlg, IDC_DIR_DELETE), FALSE);
+ EnableWindow(GetDlgItem(hDlg, IDC_DIR_INSERT), FALSE);
+ }
+}
+
+static BOOL Directories_OnInitDialog(HWND hDlg, HWND hwndFocus, LPARAM lParam)
+{
+ RECT rectClient;
+ LVCOLUMN LVCol;
+ int i = 0;
+ std::string s;
+ TCHAR *token;
+ TCHAR buf[MAX_PATH * MAX_DIRS];
+ TCHAR* t_s = NULL;
+ HRESULT res = 0;
+
+ /* count how many dirinfos there are */
+ int nDirInfoCount = 0;
+ while(g_directoryInfo[nDirInfoCount].lpName)
+ nDirInfoCount++;
+
+ g_pDirInfo = (tDirInfo *) malloc(sizeof(tDirInfo) * nDirInfoCount);
+ if (!g_pDirInfo) /* bummer */
+ goto error;
+ memset(g_pDirInfo, 0, sizeof(tDirInfo) * nDirInfoCount);
+
+ for (i = nDirInfoCount - 1; i >= 0; i--)
+ {
+ t_s = ui_wstring_from_utf8(g_directoryInfo[i].lpName);
+ if( !t_s )
+ return FALSE;
+ (void)ComboBox_InsertString(GetDlgItem(hDlg, IDC_DIR_COMBO), 0, win_tstring_strdup(t_s));
+ free(t_s);
+ t_s = NULL;
+ }
+
+ (void)ComboBox_SetCurSel(GetDlgItem(hDlg, IDC_DIR_COMBO), 0);
+
+ GetClientRect(GetDlgItem(hDlg, IDC_DIR_LIST), &rectClient);
+
+ memset(&LVCol, 0, sizeof(LVCOLUMN));
+ LVCol.mask = LVCF_WIDTH;
+ LVCol.cx = rectClient.right - rectClient.left - GetSystemMetrics(SM_CXHSCROLL);
+
+ res = ListView_InsertColumn(GetDlgItem(hDlg, IDC_DIR_LIST), 0, &LVCol);
+ res++;
+
+ /* Keep a temporary copy of the directory strings in g_pDirInfo. */
+ for (i = 0; i < nDirInfoCount; i++)
+ {
+ s = g_directoryInfo[i].pfnGetTheseDirs();
+ t_s = ui_wstring_from_utf8(s.c_str());
+ if( !t_s )
+ return false;
+ /* Copy the string to our own buffer so that we can mutilate it */
+ _tcscpy(buf, t_s);
+
+ if (IsMultiDir(i))
+ {
+ g_pDirInfo[i].m_Path = (tPath*)malloc(sizeof(tPath));
+ if (!g_pDirInfo[i].m_Path)
+ goto error;
+
+ g_pDirInfo[i].m_Path->m_NumDirectories = 0;
+ token = _tcstok(buf, TEXT(";"));
+ while ((DirInfo_NumDir(g_pDirInfo, i) < MAX_DIRS) && token)
+ {
+ _tcscpy(DirInfo_Path(g_pDirInfo, i, DirInfo_NumDir(g_pDirInfo, i)), token);
+ DirInfo_NumDir(g_pDirInfo, i)++;
+ token = _tcstok(NULL, TEXT(";"));
+ }
+ DirInfo_SetModified(g_pDirInfo, i, FALSE);
+ }
+ else
+ {
+ // multi not supported so get first directory only
+ token = _tcstok(buf, TEXT(";"));
+ if (token)
+ DirInfo_SetDir(g_pDirInfo, i, -1, token);
+ else
+ DirInfo_SetDir(g_pDirInfo, i, -1, t_s);
+ }
+ free(t_s);
+ t_s = NULL;
+ }
+
+ UpdateDirectoryList(hDlg);
+ return true;
+
+error:
+ if( t_s )
+ free(t_s);
+ Directories_OnDestroy(hDlg);
+ EndDialog(hDlg, -1);
+ return false;
+}
+
+static void Directories_OnDestroy(HWND hDlg)
+{
+ if (g_pDirInfo)
+ {
+ /* count how many dirinfos there are */
+ int nDirInfoCount = 0;
+ while(g_directoryInfo[nDirInfoCount].lpName)
+ nDirInfoCount++;
+
+ for (int i = 0; i < nDirInfoCount; i++)
+ {
+ if (g_pDirInfo[i].m_Path)
+ free(g_pDirInfo[i].m_Path);
+ if (g_pDirInfo[i].m_tDirectory)
+ free(g_pDirInfo[i].m_tDirectory);
+ }
+ free(g_pDirInfo);
+ g_pDirInfo = NULL;
+ }
+}
+
+static void Directories_OnClose(HWND hDlg)
+{
+ EndDialog(hDlg, IDCANCEL);
+}
+
+static int RetrieveDirList(int nDir, int nFlagResult, void (*SetTheseDirs)(const char *s))
+{
+ int nResult = 0;
+
+ if (DirInfo_Modified(g_pDirInfo, nDir))
+ {
+ TCHAR buf[MAX_PATH * MAX_DIRS];
+ memset(buf, 0, sizeof(buf));
+ int nPaths = DirInfo_NumDir(g_pDirInfo, nDir);
+ for (int i = 0; i < nPaths; i++)
+ {
+ _tcscat(buf, FixSlash(DirInfo_Path(g_pDirInfo, nDir, i)));
+
+ if (i < nPaths - 1)
+ _tcscat(buf, TEXT(";"));
+ }
+ char* utf8_buf = ui_utf8_from_wstring(buf);
+ SetTheseDirs(utf8_buf);
+ free(utf8_buf);
+
+ nResult |= nFlagResult;
+ }
+ return nResult;
+}
+
+static void Directories_OnOk(HWND hDlg)
+{
+ int nResult = 0;
+
+ for (int i = 0; g_directoryInfo[i].lpName; i++)
+ {
+ if (IsMultiDir(i))
+ nResult |= RetrieveDirList(i, g_directoryInfo[i].nDirDlgFlags, g_directoryInfo[i].pfnSetTheseDirs);
+ else
+ {
+ LPTSTR s = FixSlash(DirInfo_Dir(g_pDirInfo, i));
+ char* utf8_s = ui_utf8_from_wstring(s);
+ g_directoryInfo[i].pfnSetTheseDirs(utf8_s);
+ free(utf8_s);
+ }
+ }
+ EndDialog(hDlg, nResult);
+}
+
+static void Directories_OnCancel(HWND hDlg)
+{
+ EndDialog(hDlg, IDCANCEL);
+}
+
+static void Directories_OnInsert(HWND hDlg)
+{
+ HWND hList = GetDlgItem(hDlg, IDC_DIR_LIST);
+ int nItem = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
+
+ TCHAR buf[MAX_PATH];
+ if (BrowseForDirectory(hDlg, NULL, buf) == true)
+ {
+ /* list was empty */
+ if (nItem == -1)
+ nItem = 0;
+
+ int nType = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_DIR_COMBO));
+ if (IsMultiDir(nType))
+ {
+ if (MAX_DIRS <= DirInfo_NumDir(g_pDirInfo, nType))
+ return;
+
+ for (int i = DirInfo_NumDir(g_pDirInfo, nType); nItem < i; i--)
+ _tcscpy(DirInfo_Path(g_pDirInfo, nType, i), DirInfo_Path(g_pDirInfo, nType, i - 1));
+
+ _tcscpy(DirInfo_Path(g_pDirInfo, nType, nItem), buf);
+ DirInfo_NumDir(g_pDirInfo, nType)++;
+ DirInfo_SetModified(g_pDirInfo, nType, true);
+ }
+
+ UpdateDirectoryList(hDlg);
+
+ ListView_SetItemState(hList, nItem, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
+ }
+}
+
+static void Directories_OnBrowse(HWND hDlg)
+{
+ HWND hList = GetDlgItem(hDlg, IDC_DIR_LIST);
+ int nItem = ListView_GetNextItem(hList, -1, LVNI_SELECTED);
+
+ if (nItem == -1)
+ return;
+
+ int nType = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_DIR_COMBO));
+ if (IsMultiDir(nType))
+ {
+ /* Last item is placeholder for append */
+ if (nItem == ListView_GetItemCount(hList) - 1)
+ {
+ Directories_OnInsert(hDlg);
+ return;
+ }
+ }
+
+ TCHAR inbuf[MAX_PATH], outbuf[MAX_PATH];
+ ListView_GetItemText(hList, nItem, 0, inbuf, MAX_PATH);
+
+ if (BrowseForDirectory(hDlg, inbuf, outbuf) == true)
+ {
+ nType = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_DIR_COMBO));
+ DirInfo_SetDir(g_pDirInfo, nType, nItem, outbuf);
+ UpdateDirectoryList(hDlg);
+ }
+}
+
+static void Directories_OnDelete(HWND hDlg)
+{
+ HWND hList = GetDlgItem(hDlg, IDC_DIR_LIST);
+ int nItem = ListView_GetNextItem(hList, -1, LVNI_SELECTED | LVNI_ALL);
+
+ if (nItem == -1)
+ return;
+
+ /* Don't delete "Append" placeholder. */
+ if (nItem == ListView_GetItemCount(hList) - 1)
+ return;
+
+ int nType = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_DIR_COMBO));
+ if (IsMultiDir(nType))
+ {
+ for (int i = nItem; i < DirInfo_NumDir(g_pDirInfo, nType) - 1; i++)
+ _tcscpy(DirInfo_Path(g_pDirInfo, nType, i), DirInfo_Path(g_pDirInfo, nType, i + 1));
+
+ _tcscpy(DirInfo_Path(g_pDirInfo, nType, DirInfo_NumDir(g_pDirInfo, nType) - 1), TEXT(""));
+ DirInfo_NumDir(g_pDirInfo, nType)--;
+
+ DirInfo_SetModified(g_pDirInfo, nType, TRUE);
+ }
+
+ UpdateDirectoryList(hDlg);
+
+ int nCount = ListView_GetItemCount(hList);
+ if (nCount <= 1)
+ return;
+
+ /* If the last item was removed, select the item above. */
+ int nSelect;
+ if (nItem == nCount - 1)
+ nSelect = nCount - 2;
+ else
+ nSelect = nItem;
+
+ ListView_SetItemState(hList, nSelect, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
+}
+
+static BOOL Directories_OnBeginLabelEdit(HWND hDlg, NMHDR* pNMHDR)
+{
+ BOOL bResult = false;
+ NMLVDISPINFO* pDispInfo = (NMLVDISPINFO*)pNMHDR;
+ LVITEM* pItem = &pDispInfo->item;
+
+ int nType = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_DIR_COMBO));
+ if (IsMultiDir(nType))
+ {
+ /* Last item is placeholder for append */
+ if (pItem->iItem == ListView_GetItemCount(GetDlgItem(hDlg, IDC_DIR_LIST)) - 1)
+ {
+ if (MAX_DIRS <= DirInfo_NumDir(g_pDirInfo, nType))
+ return true; /* don't edit */
+
+ HWND hEdit = (HWND)(LRESULT)(int)SendDlgItemMessage(hDlg, IDC_DIR_LIST, LVM_GETEDITCONTROL, 0, 0);
+ Edit_SetText(hEdit, TEXT(""));
+ }
+ }
+
+ return bResult;
+}
+
+static BOOL Directories_OnEndLabelEdit(HWND hDlg, NMHDR* pNMHDR)
+{
+ BOOL bResult = false;
+ NMLVDISPINFO* pDispInfo = (NMLVDISPINFO*)pNMHDR;
+ LVITEM* pItem = &pDispInfo->item;
+
+ if (pItem->pszText)
+ {
+ struct _stat file_stat;
+
+ /* Don't allow empty entries. */
+ if (!_tcscmp(pItem->pszText, TEXT("")))
+ return false;
+
+ /* Check validity of edited directory. */
+ if (_tstat(pItem->pszText, &file_stat) == 0
+ && (file_stat.st_mode & S_IFDIR))
+ bResult = true;
+ else
+ if (MessageBox(NULL, TEXT("Directory does not exist, continue anyway?"), TEXT(MAMEUINAME), MB_OKCANCEL) == IDOK)
+ bResult = true;
+ }
+
+ if (bResult == true)
+ {
+ int nType = ComboBox_GetCurSel(GetDlgItem(hDlg, IDC_DIR_COMBO));
+ if (IsMultiDir(nType))
+ {
+ /* Last item is placeholder for append */
+ if (pItem->iItem == ListView_GetItemCount(GetDlgItem(hDlg, IDC_DIR_LIST)) - 1)
+ {
+ if (MAX_DIRS <= DirInfo_NumDir(g_pDirInfo, nType))
+ return false;
+
+ for (int i = DirInfo_NumDir(g_pDirInfo, nType); pItem->iItem < i; i--)
+ _tcscpy(DirInfo_Path(g_pDirInfo, nType, i), DirInfo_Path(g_pDirInfo, nType, i - 1));
+
+ _tcscpy(DirInfo_Path(g_pDirInfo, nType, pItem->iItem), pItem->pszText);
+
+ DirInfo_SetModified(g_pDirInfo, nType, true);
+ DirInfo_NumDir(g_pDirInfo, nType)++;
+ }
+ else
+ DirInfo_SetDir(g_pDirInfo, nType, pItem->iItem, pItem->pszText);
+ }
+ else
+ DirInfo_SetDir(g_pDirInfo, nType, pItem->iItem, pItem->pszText);
+
+ UpdateDirectoryList(hDlg);
+ ListView_SetItemState(GetDlgItem(hDlg, IDC_DIR_LIST), pItem->iItem, LVIS_FOCUSED | LVIS_SELECTED, LVIS_FOCUSED | LVIS_SELECTED);
+ }
+
+ return bResult;
+}
+
+static void Directories_OnCommand(HWND hDlg, int id, HWND hwndCtl, UINT codeNotify)
+{
+ switch (id)
+ {
+ case IDOK:
+ if (codeNotify == BN_CLICKED)
+ Directories_OnOk(hDlg);
+ break;
+
+ case IDCANCEL:
+ if (codeNotify == BN_CLICKED)
+ Directories_OnCancel(hDlg);
+ break;
+
+ case IDC_DIR_BROWSE:
+ if (codeNotify == BN_CLICKED)
+ Directories_OnBrowse(hDlg);
+ break;
+
+ case IDC_DIR_INSERT:
+ if (codeNotify == BN_CLICKED)
+ Directories_OnInsert(hDlg);
+ break;
+
+ case IDC_DIR_DELETE:
+ if (codeNotify == BN_CLICKED)
+ Directories_OnDelete(hDlg);
+ break;
+
+ case IDC_DIR_COMBO:
+ switch (codeNotify)
+ {
+ case CBN_SELCHANGE:
+ Directories_OnSelChange(hDlg);
+ break;
+ }
+ break;
+ }
+}
+
+static BOOL Directories_OnNotify(HWND hDlg, int id, NMHDR* pNMHDR)
+{
+ switch (id)
+ {
+ case IDC_DIR_LIST:
+ switch (pNMHDR->code)
+ {
+ case LVN_ENDLABELEDIT:
+ return Directories_OnEndLabelEdit(hDlg, pNMHDR);
+
+ case LVN_BEGINLABELEDIT:
+ return Directories_OnBeginLabelEdit(hDlg, pNMHDR);
+ }
+ }
+ return FALSE;
+}
+
+/**************************************************************************
+
+ Use the shell to select a Directory.
+
+ **************************************************************************/
+
+static int CALLBACK BrowseCallbackProc(HWND hwnd, UINT uMsg, LPARAM lParam, LPARAM lpData)
+{
+ /*
+ Called just after the dialog is initialized
+ Select the dir passed in BROWSEINFO.lParam
+ */
+ if (uMsg == BFFM_INITIALIZED)
+ {
+ if ((const char*)lpData)
+ SendMessage(hwnd, BFFM_SETSELECTION, TRUE, lpData);
+ }
+
+ return 0;
+}
+
+BOOL BrowseForDirectory(HWND hwnd, LPCTSTR pStartDir, TCHAR* pResult)
+{
+ BOOL bResult = false;
+ TCHAR buf[MAX_PATH];
+
+ BROWSEINFO Info;
+ Info.hwndOwner = hwnd;
+ Info.pidlRoot = NULL;
+ Info.pszDisplayName = buf;
+ Info.lpszTitle = TEXT("Select a directory:");
+ Info.ulFlags = BIF_RETURNONLYFSDIRS | BIF_USENEWUI;
+ Info.lpfn = BrowseCallbackProc;
+ Info.lParam = (LPARAM)pStartDir;
+
+ LPITEMIDLIST pItemIDList = SHBrowseForFolder(&Info);
+
+ if (pItemIDList)
+ {
+ if (SHGetPathFromIDList(pItemIDList, buf) == true)
+ {
+ _sntprintf(pResult, MAX_PATH, TEXT("%s"), buf);
+ bResult = true;
+ }
+ }
+ else
+ bResult = false;
+
+ return bResult;
+}
+