diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/Plugins/Library/ml_local/ScanFolderBrowser.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/Plugins/Library/ml_local/ScanFolderBrowser.cpp')
-rw-r--r-- | Src/Plugins/Library/ml_local/ScanFolderBrowser.cpp | 475 |
1 files changed, 475 insertions, 0 deletions
diff --git a/Src/Plugins/Library/ml_local/ScanFolderBrowser.cpp b/Src/Plugins/Library/ml_local/ScanFolderBrowser.cpp new file mode 100644 index 00000000..ae49d0a0 --- /dev/null +++ b/Src/Plugins/Library/ml_local/ScanFolderBrowser.cpp @@ -0,0 +1,475 @@ +#include "main.h" +#include "./scanfolderbrowser.h" +#include "resource.h" + +/// New controls +#define IDC_CHK_BGSCAN 0x1980 +#define IDC_TLB_BOOKMARKS 0x1978 +#define TOOLBAR_BTN_STARTID 0x1000 + +#define PATHTYPE_CSIDL 0 +#define PATHTYPE_STRING 1 +#define PATHTYPE_PIDL 2 + +typedef struct __FOLDER +{ + int pathtype; + INT_PTR path; + LPCWSTR caption; // if NULL display name will be used + LPCWSTR tooltip; // if NULL display name will be used +} FOLDER; + +typedef struct _FBUTTON +{ + LPITEMIDLIST pidl; + LPWSTR caption; + LPWSTR tooltip; + INT iImage; +} FBUTTON; + +static const FOLDER BOOKMARKS[] = +{ + {PATHTYPE_STRING, (INT_PTR)L"C:\\Program Files\\Winamp", NULL, NULL }, + {PATHTYPE_CSIDL, CSIDL_MYMUSIC, NULL, NULL }, + {PATHTYPE_CSIDL, CSIDL_MYVIDEO, NULL, NULL }, + {PATHTYPE_CSIDL, CSIDL_PERSONAL, NULL, NULL }, + {PATHTYPE_CSIDL, CSIDL_DESKTOP, NULL, NULL }, + {PATHTYPE_CSIDL, CSIDL_DRIVES, NULL, NULL}, + {PATHTYPE_CSIDL, CSIDL_NETWORK, NULL, NULL }, +}; + +static HIMAGELIST hSysImageList; + +//// XP THEME - BEGIN +typedef HANDLE HTHEME; + +typedef HRESULT (WINAPI *XPT_CLOSETHEMEDATA)(HTHEME); +typedef BOOL (WINAPI *XPT_ISAPPTHEMED)(void); +typedef HTHEME (WINAPI *XPT_OPENTHEMEDATA)(HWND, LPCWSTR); +typedef HRESULT (WINAPI *XPT_GETTHEMECOLOR)(HTHEME, INT, INT, INT, COLORREF*); + +#define GP_BORDER 1 +#define BSS_FLAT 1 +#define TMT_BORDERCOLOR 3801 + +static XPT_CLOSETHEMEDATA xpCloseThemeData; +static XPT_ISAPPTHEMED xpIsAppThemed; +static XPT_OPENTHEMEDATA xpOpenThemeData; +static XPT_GETTHEMECOLOR xpGetThemeColor; + +static HINSTANCE xpThemeDll = NULL; + +static BOOL LoadXPTheme(void); +static void UnloadXPTheme(void); +//// XP THEME - END + +static HBRUSH GetBorderBrush(HWND hwnd); + +static void Initialize(ScanFolderBrowser *browser, BOOL showBckScan, BOOL checkBckScan) +{ + browser->buttonsCount = 0; + browser->buttons = NULL; + browser->bkScanChecked = checkBckScan; + browser->bkScanShow = showBckScan; + browser->pac = NULL; + browser->pacl2 = NULL; + + HRESULT result = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, IID_IAutoComplete, (LPVOID*)&browser->pac); + if (S_OK == result) + { + IAutoComplete2 *pac2; + if (SUCCEEDED(browser->pac->QueryInterface(IID_IAutoComplete2, (LPVOID*)&pac2))) + { + pac2->SetOptions(ACO_AUTOSUGGEST | ACO_AUTOAPPEND | ACO_USETAB | 0x00000020/*ACF_UPDOWNKEYDROPSLIST*/); + } + result = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_INPROC_SERVER, IID_IACList2, (LPVOID*)&browser->pacl2); + if (S_OK == result) browser->pacl2->SetOptions(ACLO_FILESYSDIRS); + else { browser->pac->Release(); browser->pac = NULL; } + } + + lstrcpynW(browser->selectionPath, WASABI_API_APP->path_getWorkingPath(), MAX_PATH); + + browser->SetCaption(WASABI_API_LNGSTRINGW(IDS_ADD_MEDIA_TO_LIBRARY_)); + browser->SetTitle(WASABI_API_LNGSTRINGW(IDS_SELECT_FOLDER_TO_ADD_TO_WINAMP_MEDIA_LIBRARY)); + browser->SetSelection(browser->selectionPath); + browser->SetFlags(BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_VALIDATE | BIF_USENEWUI | BIF_NONEWFOLDERBUTTON | BIF_NEWDIALOGSTYLE); + browser->LoadBookmarks(); +} + +ScanFolderBrowser::ScanFolderBrowser(BOOL showBckScanOption) +{ + Initialize(this, showBckScanOption, FALSE); +} + +ScanFolderBrowser::ScanFolderBrowser(void) +{ + Initialize(this, TRUE, FALSE); +} + +ScanFolderBrowser::~ScanFolderBrowser(void) +{ + if (pacl2) pacl2->Release(); + if (pac) pac->Release(); + FreeBookmarks(); +} + +void ScanFolderBrowser::LoadBookmarks(void) +{ + FreeBookmarks(); + INT count = sizeof(BOOKMARKS)/sizeof(FOLDER); + if (!count) return; + + buttons = (FBUTTON*)calloc(count, sizeof(FBUTTON)); + if (!buttons) return; + buttonsCount = 0; + + for (int i = 0; i < count; i++) + { + const FOLDER *pfolder = &BOOKMARKS[i]; + FBUTTON *pfb = &buttons[buttonsCount]; + switch(BOOKMARKS[i].pathtype) + { + case PATHTYPE_PIDL: + pfb->pidl = ILClone((LPITEMIDLIST)pfolder->path); // need to copy it + break; + case PATHTYPE_CSIDL: + if (S_OK != SHGetSpecialFolderLocation(NULL, (INT)pfolder->path, &pfb->pidl)) pfb->pidl = NULL; + break; + case PATHTYPE_STRING: + if (S_OK != ParseDisplayName((LPCWSTR)pfolder->path, NULL, &pfb->pidl, 0, NULL))pfb->pidl = NULL; + break; + } + if (!buttons[buttonsCount].pidl) + { + continue; + } + + SHFILEINFOW shfi = {0}; + hSysImageList = (HIMAGELIST)SHGetFileInfoW((LPCWSTR)pfb->pidl, 0, &shfi, sizeof(SHFILEINFO), SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SYSICONINDEX | SHGFI_PIDL); + pfb->caption = _wcsdup((pfolder->caption) ? pfolder->caption : shfi.szDisplayName); + pfb->tooltip = _wcsdup((pfolder->tooltip) ? pfolder->tooltip : shfi.szDisplayName); + pfb->iImage = shfi.iIcon; + buttonsCount++; + } +} + +void ScanFolderBrowser::FreeBookmarks(void) +{ + if (buttons) + { + FBUTTON *pbtn = buttons; + while(buttonsCount--) + { + if (pbtn->caption) { free(pbtn->caption); pbtn->caption = NULL; } + if (pbtn->tooltip) { free(pbtn->tooltip); pbtn->tooltip = NULL; } + if (pbtn->pidl) { ILFree(pbtn->pidl); pbtn->pidl = NULL; } + pbtn++; + } + free(buttons); + } + buttonsCount = 0; +} + +void ScanFolderBrowser::OnInitialized(void) +{ + HWND ctrlWnd; + + if (!FindWindowExW(GetHandle(), NULL,L"SHBrowseForFolder ShellNameSpace Control",NULL)) + { + RECT rw; + int cx; + GetWindowRect(GetHandle(), &rw); + cx = rw.right - rw.left; + SetWindowPos(GetHandle(), NULL, 0, 0, cx, rw.bottom - rw.top, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED); + GetWindowRect(GetHandle(), &rw); + ShrinkWindows((rw.right - rw.left) - cx); + } + SetOKText(WASABI_API_LNGSTRINGW(IDS_ADD)); + + ShiftWindows(88); + + ctrlWnd = CreateWindowExW(WS_EX_NOPARENTNOTIFY , TOOLBARCLASSNAMEW, NULL, + WS_CHILD | WS_TABSTOP | + CCS_TOP | CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE | + TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_WRAPABLE | TBSTYLE_CUSTOMERASE | TBSTYLE_TOOLTIPS, + 12, 10, 84, 272, GetHandle(), (HMENU)IDC_TLB_BOOKMARKS, NULL, NULL); + if (ctrlWnd) + { + ::SendMessage(ctrlWnd, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0L); + ::SendMessage(ctrlWnd, TB_SETBUTTONSIZE, (WPARAM)0, MAKELPARAM(84, 50)); + ::SendMessage(ctrlWnd, TB_SETBITMAPSIZE, (WPARAM)0, MAKELPARAM(32, 32)); + ::SendMessage(ctrlWnd, TB_SETPADDING, (WPARAM)0, MAKELPARAM(8, 8)); + ::SendMessage(ctrlWnd, TB_SETBUTTONWIDTH, (WPARAM)0, MAKELPARAM(84, 84)); + ::SendMessage(ctrlWnd, TB_SETEXTENDEDSTYLE, (WPARAM)0, 0x0000080 /*TBSTYLE_EX_DOUBLEBUFFER*/); + ::SendMessage(ctrlWnd, TB_SETMAXTEXTROWS, (WPARAM)2, 0L); + ::SendMessage(ctrlWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hSysImageList); + + LPTBBUTTON ptbb = (LPTBBUTTON)calloc(buttonsCount, sizeof(TBBUTTON)); + for (int i = 0; i < buttonsCount; i++) + { + ptbb[i].fsState = TBSTATE_ENABLED | TBSTATE_WRAP; + ptbb[i].idCommand = TOOLBAR_BTN_STARTID + i; + ptbb[i].fsStyle = TBSTYLE_CHECKGROUP; + ptbb[i].iString = (INT_PTR)buttons[i].caption; + ptbb[i].iBitmap = (INT_PTR) buttons[i].iImage; + } + ::SendMessage(ctrlWnd, TB_ADDBUTTONSW, (WPARAM)buttonsCount,(LPARAM)ptbb); + } + + ctrlWnd = CreateWindowExW(WS_EX_NOPARENTNOTIFY, L"BUTTON", + WASABI_API_LNGSTRINGW(IDS_SCAN_FOLDER_IN_BACKGROUND), + BS_AUTOCHECKBOX | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP, + 0, 0, 100, 16, GetHandle(), (HMENU)IDC_CHK_BGSCAN, NULL, NULL); + if (ctrlWnd) + { + ::SendMessage(ctrlWnd, WM_SETFONT, (WPARAM)SendMessage(WM_GETFONT, 0, 0), FALSE); + ::SendMessage(ctrlWnd, BM_SETCHECK, (WPARAM) (bkScanChecked) ? BST_CHECKED : BST_UNCHECKED, 0L); + } + + hbBorder = GetBorderBrush(GetHandle()); + RepositionWindows(); + + ShowWindow(GetDlgItem(IDC_TLB_BOOKMARKS), SW_SHOWNORMAL); + if (bkScanShow) ShowWindow(GetDlgItem(IDC_CHK_BGSCAN), SW_SHOWNORMAL); + + // edit box autocomplete chnages + if(pac) pac->Init(GetDlgItem(IDC_EDT_PATH), pacl2, NULL, NULL); + + FolderBrowseEx::OnInitialized(); +} + +void ScanFolderBrowser::OnSelectionChanged(LPCITEMIDLIST pidl) +{ + for(int i =0; i < buttonsCount; i++) + { + ::SendMessage(GetDlgItem(IDC_TLB_BOOKMARKS), TB_CHECKBUTTON, (WPARAM)TOOLBAR_BTN_STARTID + i, ILIsEqual(pidl, buttons[i].pidl)); + } + + FolderBrowseEx::OnSelectionChanged(pidl); +} + +BOOL ScanFolderBrowser::OnValidateFailed(LPCWSTR lpName) +{ + wchar_t buffer[2048] = {0}, titleStr[64] = {0}; + FolderBrowseEx::OnValidateFailed(lpName); + wsprintfW(buffer, WASABI_API_LNGSTRINGW(IDS_FOLDER_NAME_IS_INCORRECT), lpName); + MessageBoxW(GetHandle(), buffer, WASABI_API_LNGSTRINGW_BUF(IDS_INCORRECT_FOLDER_NAME,titleStr,64), MB_OK | MB_ICONERROR | MB_SETFOREGROUND); + return TRUE; +} + +void ScanFolderBrowser::OnSelectionDone(LPCITEMIDLIST pidl) +{ + WCHAR pszPath[MAX_PATH] = {0}; + SHGetPathFromIDListW(pidl, pszPath); + WASABI_API_APP->path_setWorkingPath(pszPath); +} + +void ScanFolderBrowser::ShiftWindows(int cx) +{ + HWND hwnd = GetWindow(GetHandle(), GW_CHILD); + while(hwnd) + { + RECT rw; + UINT ctrlID = GetDlgCtrlID(hwnd); + if (ctrlID != IDOK && ctrlID != IDCANCEL && ctrlID != IDC_SB_GRIPPER) + { + GetWindowRect(hwnd, &rw); + MapWindowPoints(HWND_DESKTOP, GetHandle(), (LPPOINT)&rw, 2); + SetWindowPos(hwnd, NULL, rw.left + cx, rw.top, (rw.right - (rw.left + cx)), rw.bottom - rw.top, SWP_NOACTIVATE | SWP_NOZORDER | ((ctrlID == IDC_LBL_FOLDER) ? SWP_NOSIZE : 0)); + } + hwnd = GetWindow(hwnd, GW_HWNDNEXT); + } +} + +void ScanFolderBrowser::ShrinkWindows(int cx) +{ + HWND hwnd = GetWindow(GetHandle(), GW_CHILD); + while(hwnd) + { + UINT ctrlID = GetDlgCtrlID(hwnd); + if (ctrlID != IDC_LBL_FOLDER) + { + RECT rw; + GetWindowRect(hwnd, &rw); + MapWindowPoints(HWND_DESKTOP, GetHandle(), (LPPOINT)&rw, 2); + SetWindowPos(hwnd, NULL, + rw.left + cx, rw.top, (rw.right - rw.left) + cx, rw.bottom - rw.top, + SWP_NOACTIVATE | SWP_NOZORDER | ((ctrlID == IDOK || ctrlID == IDCANCEL) ? SWP_NOSIZE : SWP_NOMOVE)); + } + hwnd = GetWindow(hwnd, GW_HWNDNEXT); + } +} + +void ScanFolderBrowser::RepositionWindows(void) +{ + RECT rwBtn, rwLV, rwCtrl; + HWND pwnd, ctrlWnd; + + GetWindowRect(GetDlgItem(IDOK), &rwBtn); + pwnd = FindWindowExW(GetHandle(), NULL,L"SHBrowseForFolder ShellNameSpace Control",NULL); + + GetWindowRect((pwnd) ? pwnd : GetDlgItem(IDC_TV_FOLDERS), &rwLV); + ctrlWnd = GetDlgItem(IDC_CHK_BGSCAN); + GetWindowRect(ctrlWnd, &rwCtrl); + SetRect(&rwCtrl, rwLV.left, rwBtn.bottom - (rwCtrl.bottom - rwCtrl.top), rwBtn.left - 4 - rwLV.left, rwCtrl.bottom - rwCtrl.top); + MapWindowPoints(HWND_DESKTOP, GetHandle(), (LPPOINT)&rwCtrl, 1); + SetWindowPos(ctrlWnd, NULL, rwCtrl.left, rwCtrl.top, rwCtrl.right, rwCtrl.bottom, SWP_NOACTIVATE | SWP_NOZORDER); + + ctrlWnd = GetDlgItem(IDC_TLB_BOOKMARKS); + GetWindowRect(ctrlWnd, &rwCtrl); + GetWindowRect(GetDlgItem(IDC_LBL_CAPTION), &rwLV); + SetWindowPos(ctrlWnd, NULL, 0, 0, rwCtrl.right - rwCtrl.left, rwBtn.bottom - rwLV.top, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE); +} + +void ScanFolderBrowser::OnSize(UINT nType, int cx, int cy) +{ + FolderBrowseEx::DialogProc(WM_SIZE, nType, MAKELPARAM(cx, cy)); + + RepositionWindows(); +} + +void ScanFolderBrowser::OnWindowPosChanging(WINDOWPOS *lpwp) +{ + if (lpwp->cx < 346 + 88) lpwp->cx = 346 + 88; +} + +BOOL ScanFolderBrowser::OnNotify(UINT idCtrl, LPNMHDR pnmh, LRESULT *result) +{ + switch(pnmh->code) + { + case NM_CUSTOMDRAW: + switch(pnmh->idFrom) + { + case IDC_TLB_BOOKMARKS: + *result = OnToolBarCustomDraw((LPNMTBCUSTOMDRAW)pnmh); + return TRUE; + } + break; + case TTN_GETDISPINFOW: + OnToolTipGetDispInfo((LPNMTTDISPINFOW)pnmh); + break; + } + return FALSE; +} + +BOOL ScanFolderBrowser::OnCommand(UINT idCtrl, UINT idEvnt, HWND hwndCtrl) +{ + int tbid; + tbid = idCtrl - TOOLBAR_BTN_STARTID; + if (tbid >= 0 && tbid < buttonsCount) + { + LPITEMIDLIST pidl1 = buttons[tbid].pidl; + SetExpanded(pidl1); + SetSelection(pidl1); + + wchar_t test_path[MAX_PATH] = {0}; + EnableOK(SHGetPathFromIDListW(pidl1, test_path)); + return TRUE; + } + return FALSE; +} + +LRESULT ScanFolderBrowser::OnToolBarCustomDraw(LPNMTBCUSTOMDRAW pnmcd) +{ + switch(pnmcd->nmcd.dwDrawStage) + { + case CDDS_PREPAINT: + FrameRect(pnmcd->nmcd.hdc, &pnmcd->nmcd.rc, hbBorder); + InflateRect(&pnmcd->nmcd.rc, -1, -1); + IntersectClipRect(pnmcd->nmcd.hdc, pnmcd->nmcd.rc.left, pnmcd->nmcd.rc.top, pnmcd->nmcd.rc.right, pnmcd->nmcd.rc.bottom); + return CDRF_NOTIFYITEMDRAW; + case CDDS_ITEMPREPAINT: + InflateRect(&pnmcd->nmcd.rc, -1, 0); + if (0 == pnmcd->nmcd.rc.top) pnmcd->nmcd.rc.top++; + return CDRF_DODEFAULT; + } + return CDRF_DODEFAULT; +} + +void ScanFolderBrowser::OnToolTipGetDispInfo(LPNMTTDISPINFOW lpnmtdi) +{ + int tbid; + tbid = lpnmtdi->hdr.idFrom - TOOLBAR_BTN_STARTID; + lpnmtdi->lpszText = (tbid >= 0 && tbid < buttonsCount) ? buttons[tbid].tooltip : L""; +} + +INT_PTR ScanFolderBrowser::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; + switch(uMsg) + { + case WM_WINDOWPOSCHANGING: OnWindowPosChanging((WINDOWPOS*)lParam); + case WM_SIZE: OnSize(wParam, LOWORD(lParam), HIWORD(lParam)); return 0; + case WM_NOTIFY: + if (OnNotify(wParam, (LPNMHDR)lParam, &result)) + { + SetDialogResult(result); + return TRUE; + } + break; + case WM_COMMAND: + if (OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam)) return 0; + break; + case WM_DESTROY: + if (hbBorder) DeleteObject(hbBorder); + hbBorder = NULL; + bkScanChecked = (BST_CHECKED == IsDlgButtonChecked(GetHandle(), IDC_CHK_BGSCAN)); + break; + } + return FolderBrowseEx::DialogProc(uMsg, wParam, lParam); +} + +static BOOL LoadXPTheme(void) +{ + xpThemeDll = LoadLibraryW(L"UxTheme.dll"); + if (!xpThemeDll) return FALSE; + + xpCloseThemeData = (XPT_CLOSETHEMEDATA) GetProcAddress(xpThemeDll, "CloseThemeData"); + xpIsAppThemed = (XPT_ISAPPTHEMED) GetProcAddress(xpThemeDll, "IsAppThemed"); + xpOpenThemeData = (XPT_OPENTHEMEDATA) GetProcAddress(xpThemeDll, "OpenThemeData"); + xpGetThemeColor = (XPT_GETTHEMECOLOR) GetProcAddress(xpThemeDll, "GetThemeColor"); + + if (!xpCloseThemeData || !xpIsAppThemed || !xpOpenThemeData || !xpGetThemeColor) UnloadXPTheme(); + return (NULL != xpThemeDll); +} + +static void UnloadXPTheme(void) +{ + xpCloseThemeData = NULL; + xpIsAppThemed = NULL; + xpOpenThemeData = NULL; + xpGetThemeColor = NULL; + if (xpThemeDll) + { + FreeLibrary(xpThemeDll); + xpThemeDll = NULL; + } +} + +static HBRUSH GetBorderBrush(HWND hwnd) +{ + HBRUSH hb; + COLORREF clr; + HRESULT result; + + clr = 0x00000; + result = S_FALSE; + if(LoadXPTheme()) + { + if(xpIsAppThemed()) + { + HTHEME ht; + ht = xpOpenThemeData(GetDlgItem(hwnd, IDC_EDT_PATH), L"Edit"); + if (ht) + { + result = xpGetThemeColor(ht, GP_BORDER, BSS_FLAT, TMT_BORDERCOLOR, &clr); + xpCloseThemeData(ht); + } + } + UnloadXPTheme(); + } + + hb = CreateSolidBrush((S_OK == result) ? clr : GetSysColor(COLOR_WINDOWFRAME)); + + return hb; +}
\ No newline at end of file |