ScanFolderBrowser.cpp 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  1. #include "main.h"
  2. #include "./scanfolderbrowser.h"
  3. #include "resource.h"
  4. /// New controls
  5. #define IDC_CHK_BGSCAN 0x1980
  6. #define IDC_TLB_BOOKMARKS 0x1978
  7. #define TOOLBAR_BTN_STARTID 0x1000
  8. #define PATHTYPE_CSIDL 0
  9. #define PATHTYPE_STRING 1
  10. #define PATHTYPE_PIDL 2
  11. typedef struct __FOLDER
  12. {
  13. int pathtype;
  14. INT_PTR path;
  15. LPCWSTR caption; // if NULL display name will be used
  16. LPCWSTR tooltip; // if NULL display name will be used
  17. } FOLDER;
  18. typedef struct _FBUTTON
  19. {
  20. LPITEMIDLIST pidl;
  21. LPWSTR caption;
  22. LPWSTR tooltip;
  23. INT iImage;
  24. } FBUTTON;
  25. static const FOLDER BOOKMARKS[] =
  26. {
  27. {PATHTYPE_STRING, (INT_PTR)L"C:\\Program Files\\Winamp", NULL, NULL },
  28. {PATHTYPE_CSIDL, CSIDL_MYMUSIC, NULL, NULL },
  29. {PATHTYPE_CSIDL, CSIDL_MYVIDEO, NULL, NULL },
  30. {PATHTYPE_CSIDL, CSIDL_PERSONAL, NULL, NULL },
  31. {PATHTYPE_CSIDL, CSIDL_DESKTOP, NULL, NULL },
  32. {PATHTYPE_CSIDL, CSIDL_DRIVES, NULL, NULL},
  33. {PATHTYPE_CSIDL, CSIDL_NETWORK, NULL, NULL },
  34. };
  35. static HIMAGELIST hSysImageList;
  36. //// XP THEME - BEGIN
  37. typedef HANDLE HTHEME;
  38. typedef HRESULT (WINAPI *XPT_CLOSETHEMEDATA)(HTHEME);
  39. typedef BOOL (WINAPI *XPT_ISAPPTHEMED)(void);
  40. typedef HTHEME (WINAPI *XPT_OPENTHEMEDATA)(HWND, LPCWSTR);
  41. typedef HRESULT (WINAPI *XPT_GETTHEMECOLOR)(HTHEME, INT, INT, INT, COLORREF*);
  42. #define GP_BORDER 1
  43. #define BSS_FLAT 1
  44. #define TMT_BORDERCOLOR 3801
  45. static XPT_CLOSETHEMEDATA xpCloseThemeData;
  46. static XPT_ISAPPTHEMED xpIsAppThemed;
  47. static XPT_OPENTHEMEDATA xpOpenThemeData;
  48. static XPT_GETTHEMECOLOR xpGetThemeColor;
  49. static HINSTANCE xpThemeDll = NULL;
  50. static BOOL LoadXPTheme(void);
  51. static void UnloadXPTheme(void);
  52. //// XP THEME - END
  53. static HBRUSH GetBorderBrush(HWND hwnd);
  54. static void Initialize(ScanFolderBrowser *browser, BOOL showBckScan, BOOL checkBckScan)
  55. {
  56. browser->buttonsCount = 0;
  57. browser->buttons = NULL;
  58. browser->bkScanChecked = checkBckScan;
  59. browser->bkScanShow = showBckScan;
  60. browser->pac = NULL;
  61. browser->pacl2 = NULL;
  62. HRESULT result = CoCreateInstance(CLSID_AutoComplete, NULL, CLSCTX_INPROC_SERVER, IID_IAutoComplete, (LPVOID*)&browser->pac);
  63. if (S_OK == result)
  64. {
  65. IAutoComplete2 *pac2;
  66. if (SUCCEEDED(browser->pac->QueryInterface(IID_IAutoComplete2, (LPVOID*)&pac2)))
  67. {
  68. pac2->SetOptions(ACO_AUTOSUGGEST | ACO_AUTOAPPEND | ACO_USETAB | 0x00000020/*ACF_UPDOWNKEYDROPSLIST*/);
  69. }
  70. result = CoCreateInstance(CLSID_ACListISF, NULL, CLSCTX_INPROC_SERVER, IID_IACList2, (LPVOID*)&browser->pacl2);
  71. if (S_OK == result) browser->pacl2->SetOptions(ACLO_FILESYSDIRS);
  72. else { browser->pac->Release(); browser->pac = NULL; }
  73. }
  74. lstrcpynW(browser->selectionPath, WASABI_API_APP->path_getWorkingPath(), MAX_PATH);
  75. browser->SetCaption(WASABI_API_LNGSTRINGW(IDS_ADD_MEDIA_TO_LIBRARY_));
  76. browser->SetTitle(WASABI_API_LNGSTRINGW(IDS_SELECT_FOLDER_TO_ADD_TO_WINAMP_MEDIA_LIBRARY));
  77. browser->SetSelection(browser->selectionPath);
  78. browser->SetFlags(BIF_RETURNONLYFSDIRS | BIF_EDITBOX | BIF_VALIDATE | BIF_USENEWUI | BIF_NONEWFOLDERBUTTON | BIF_NEWDIALOGSTYLE);
  79. browser->LoadBookmarks();
  80. }
  81. ScanFolderBrowser::ScanFolderBrowser(BOOL showBckScanOption)
  82. {
  83. Initialize(this, showBckScanOption, FALSE);
  84. }
  85. ScanFolderBrowser::ScanFolderBrowser(void)
  86. {
  87. Initialize(this, TRUE, FALSE);
  88. }
  89. ScanFolderBrowser::~ScanFolderBrowser(void)
  90. {
  91. if (pacl2) pacl2->Release();
  92. if (pac) pac->Release();
  93. FreeBookmarks();
  94. }
  95. void ScanFolderBrowser::LoadBookmarks(void)
  96. {
  97. FreeBookmarks();
  98. INT count = sizeof(BOOKMARKS)/sizeof(FOLDER);
  99. if (!count) return;
  100. buttons = (FBUTTON*)calloc(count, sizeof(FBUTTON));
  101. if (!buttons) return;
  102. buttonsCount = 0;
  103. for (int i = 0; i < count; i++)
  104. {
  105. const FOLDER *pfolder = &BOOKMARKS[i];
  106. FBUTTON *pfb = &buttons[buttonsCount];
  107. switch(BOOKMARKS[i].pathtype)
  108. {
  109. case PATHTYPE_PIDL:
  110. pfb->pidl = ILClone((LPITEMIDLIST)pfolder->path); // need to copy it
  111. break;
  112. case PATHTYPE_CSIDL:
  113. if (S_OK != SHGetSpecialFolderLocation(NULL, (INT)pfolder->path, &pfb->pidl)) pfb->pidl = NULL;
  114. break;
  115. case PATHTYPE_STRING:
  116. if (S_OK != ParseDisplayName((LPCWSTR)pfolder->path, NULL, &pfb->pidl, 0, NULL))pfb->pidl = NULL;
  117. break;
  118. }
  119. if (!buttons[buttonsCount].pidl)
  120. {
  121. continue;
  122. }
  123. SHFILEINFOW shfi = {0};
  124. hSysImageList = (HIMAGELIST)SHGetFileInfoW((LPCWSTR)pfb->pidl, 0, &shfi, sizeof(SHFILEINFO), SHGFI_DISPLAYNAME | SHGFI_ICON | SHGFI_LARGEICON | SHGFI_SYSICONINDEX | SHGFI_PIDL);
  125. pfb->caption = _wcsdup((pfolder->caption) ? pfolder->caption : shfi.szDisplayName);
  126. pfb->tooltip = _wcsdup((pfolder->tooltip) ? pfolder->tooltip : shfi.szDisplayName);
  127. pfb->iImage = shfi.iIcon;
  128. buttonsCount++;
  129. }
  130. }
  131. void ScanFolderBrowser::FreeBookmarks(void)
  132. {
  133. if (buttons)
  134. {
  135. FBUTTON *pbtn = buttons;
  136. while(buttonsCount--)
  137. {
  138. if (pbtn->caption) { free(pbtn->caption); pbtn->caption = NULL; }
  139. if (pbtn->tooltip) { free(pbtn->tooltip); pbtn->tooltip = NULL; }
  140. if (pbtn->pidl) { ILFree(pbtn->pidl); pbtn->pidl = NULL; }
  141. pbtn++;
  142. }
  143. free(buttons);
  144. }
  145. buttonsCount = 0;
  146. }
  147. void ScanFolderBrowser::OnInitialized(void)
  148. {
  149. HWND ctrlWnd;
  150. if (!FindWindowExW(GetHandle(), NULL,L"SHBrowseForFolder ShellNameSpace Control",NULL))
  151. {
  152. RECT rw;
  153. int cx;
  154. GetWindowRect(GetHandle(), &rw);
  155. cx = rw.right - rw.left;
  156. SetWindowPos(GetHandle(), NULL, 0, 0, cx, rw.bottom - rw.top, SWP_NOMOVE | SWP_NOACTIVATE | SWP_NOZORDER | SWP_FRAMECHANGED);
  157. GetWindowRect(GetHandle(), &rw);
  158. ShrinkWindows((rw.right - rw.left) - cx);
  159. }
  160. SetOKText(WASABI_API_LNGSTRINGW(IDS_ADD));
  161. ShiftWindows(88);
  162. ctrlWnd = CreateWindowExW(WS_EX_NOPARENTNOTIFY , TOOLBARCLASSNAMEW, NULL,
  163. WS_CHILD | WS_TABSTOP |
  164. CCS_TOP | CCS_NODIVIDER | CCS_NOPARENTALIGN | CCS_NORESIZE |
  165. TBSTYLE_FLAT | TBSTYLE_TRANSPARENT | TBSTYLE_WRAPABLE | TBSTYLE_CUSTOMERASE | TBSTYLE_TOOLTIPS,
  166. 12, 10, 84, 272, GetHandle(), (HMENU)IDC_TLB_BOOKMARKS, NULL, NULL);
  167. if (ctrlWnd)
  168. {
  169. ::SendMessage(ctrlWnd, TB_BUTTONSTRUCTSIZE, (WPARAM)sizeof(TBBUTTON), 0L);
  170. ::SendMessage(ctrlWnd, TB_SETBUTTONSIZE, (WPARAM)0, MAKELPARAM(84, 50));
  171. ::SendMessage(ctrlWnd, TB_SETBITMAPSIZE, (WPARAM)0, MAKELPARAM(32, 32));
  172. ::SendMessage(ctrlWnd, TB_SETPADDING, (WPARAM)0, MAKELPARAM(8, 8));
  173. ::SendMessage(ctrlWnd, TB_SETBUTTONWIDTH, (WPARAM)0, MAKELPARAM(84, 84));
  174. ::SendMessage(ctrlWnd, TB_SETEXTENDEDSTYLE, (WPARAM)0, 0x0000080 /*TBSTYLE_EX_DOUBLEBUFFER*/);
  175. ::SendMessage(ctrlWnd, TB_SETMAXTEXTROWS, (WPARAM)2, 0L);
  176. ::SendMessage(ctrlWnd, TB_SETIMAGELIST, (WPARAM)0, (LPARAM)hSysImageList);
  177. LPTBBUTTON ptbb = (LPTBBUTTON)calloc(buttonsCount, sizeof(TBBUTTON));
  178. for (int i = 0; i < buttonsCount; i++)
  179. {
  180. ptbb[i].fsState = TBSTATE_ENABLED | TBSTATE_WRAP;
  181. ptbb[i].idCommand = TOOLBAR_BTN_STARTID + i;
  182. ptbb[i].fsStyle = TBSTYLE_CHECKGROUP;
  183. ptbb[i].iString = (INT_PTR)buttons[i].caption;
  184. ptbb[i].iBitmap = (INT_PTR) buttons[i].iImage;
  185. }
  186. ::SendMessage(ctrlWnd, TB_ADDBUTTONSW, (WPARAM)buttonsCount,(LPARAM)ptbb);
  187. }
  188. ctrlWnd = CreateWindowExW(WS_EX_NOPARENTNOTIFY, L"BUTTON",
  189. WASABI_API_LNGSTRINGW(IDS_SCAN_FOLDER_IN_BACKGROUND),
  190. BS_AUTOCHECKBOX | WS_CHILD | WS_CLIPCHILDREN | WS_CLIPSIBLINGS | WS_TABSTOP,
  191. 0, 0, 100, 16, GetHandle(), (HMENU)IDC_CHK_BGSCAN, NULL, NULL);
  192. if (ctrlWnd)
  193. {
  194. ::SendMessage(ctrlWnd, WM_SETFONT, (WPARAM)SendMessage(WM_GETFONT, 0, 0), FALSE);
  195. ::SendMessage(ctrlWnd, BM_SETCHECK, (WPARAM) (bkScanChecked) ? BST_CHECKED : BST_UNCHECKED, 0L);
  196. }
  197. hbBorder = GetBorderBrush(GetHandle());
  198. RepositionWindows();
  199. ShowWindow(GetDlgItem(IDC_TLB_BOOKMARKS), SW_SHOWNORMAL);
  200. if (bkScanShow) ShowWindow(GetDlgItem(IDC_CHK_BGSCAN), SW_SHOWNORMAL);
  201. // edit box autocomplete chnages
  202. if(pac) pac->Init(GetDlgItem(IDC_EDT_PATH), pacl2, NULL, NULL);
  203. FolderBrowseEx::OnInitialized();
  204. }
  205. void ScanFolderBrowser::OnSelectionChanged(LPCITEMIDLIST pidl)
  206. {
  207. for(int i =0; i < buttonsCount; i++)
  208. {
  209. ::SendMessage(GetDlgItem(IDC_TLB_BOOKMARKS), TB_CHECKBUTTON, (WPARAM)TOOLBAR_BTN_STARTID + i, ILIsEqual(pidl, buttons[i].pidl));
  210. }
  211. FolderBrowseEx::OnSelectionChanged(pidl);
  212. }
  213. BOOL ScanFolderBrowser::OnValidateFailed(LPCWSTR lpName)
  214. {
  215. wchar_t buffer[2048] = {0}, titleStr[64] = {0};
  216. FolderBrowseEx::OnValidateFailed(lpName);
  217. wsprintfW(buffer, WASABI_API_LNGSTRINGW(IDS_FOLDER_NAME_IS_INCORRECT), lpName);
  218. MessageBoxW(GetHandle(), buffer, WASABI_API_LNGSTRINGW_BUF(IDS_INCORRECT_FOLDER_NAME,titleStr,64), MB_OK | MB_ICONERROR | MB_SETFOREGROUND);
  219. return TRUE;
  220. }
  221. void ScanFolderBrowser::OnSelectionDone(LPCITEMIDLIST pidl)
  222. {
  223. WCHAR pszPath[MAX_PATH] = {0};
  224. SHGetPathFromIDListW(pidl, pszPath);
  225. WASABI_API_APP->path_setWorkingPath(pszPath);
  226. }
  227. void ScanFolderBrowser::ShiftWindows(int cx)
  228. {
  229. HWND hwnd = GetWindow(GetHandle(), GW_CHILD);
  230. while(hwnd)
  231. {
  232. RECT rw;
  233. UINT ctrlID = GetDlgCtrlID(hwnd);
  234. if (ctrlID != IDOK && ctrlID != IDCANCEL && ctrlID != IDC_SB_GRIPPER)
  235. {
  236. GetWindowRect(hwnd, &rw);
  237. MapWindowPoints(HWND_DESKTOP, GetHandle(), (LPPOINT)&rw, 2);
  238. 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));
  239. }
  240. hwnd = GetWindow(hwnd, GW_HWNDNEXT);
  241. }
  242. }
  243. void ScanFolderBrowser::ShrinkWindows(int cx)
  244. {
  245. HWND hwnd = GetWindow(GetHandle(), GW_CHILD);
  246. while(hwnd)
  247. {
  248. UINT ctrlID = GetDlgCtrlID(hwnd);
  249. if (ctrlID != IDC_LBL_FOLDER)
  250. {
  251. RECT rw;
  252. GetWindowRect(hwnd, &rw);
  253. MapWindowPoints(HWND_DESKTOP, GetHandle(), (LPPOINT)&rw, 2);
  254. SetWindowPos(hwnd, NULL,
  255. rw.left + cx, rw.top, (rw.right - rw.left) + cx, rw.bottom - rw.top,
  256. SWP_NOACTIVATE | SWP_NOZORDER | ((ctrlID == IDOK || ctrlID == IDCANCEL) ? SWP_NOSIZE : SWP_NOMOVE));
  257. }
  258. hwnd = GetWindow(hwnd, GW_HWNDNEXT);
  259. }
  260. }
  261. void ScanFolderBrowser::RepositionWindows(void)
  262. {
  263. RECT rwBtn, rwLV, rwCtrl;
  264. HWND pwnd, ctrlWnd;
  265. GetWindowRect(GetDlgItem(IDOK), &rwBtn);
  266. pwnd = FindWindowExW(GetHandle(), NULL,L"SHBrowseForFolder ShellNameSpace Control",NULL);
  267. GetWindowRect((pwnd) ? pwnd : GetDlgItem(IDC_TV_FOLDERS), &rwLV);
  268. ctrlWnd = GetDlgItem(IDC_CHK_BGSCAN);
  269. GetWindowRect(ctrlWnd, &rwCtrl);
  270. SetRect(&rwCtrl, rwLV.left, rwBtn.bottom - (rwCtrl.bottom - rwCtrl.top), rwBtn.left - 4 - rwLV.left, rwCtrl.bottom - rwCtrl.top);
  271. MapWindowPoints(HWND_DESKTOP, GetHandle(), (LPPOINT)&rwCtrl, 1);
  272. SetWindowPos(ctrlWnd, NULL, rwCtrl.left, rwCtrl.top, rwCtrl.right, rwCtrl.bottom, SWP_NOACTIVATE | SWP_NOZORDER);
  273. ctrlWnd = GetDlgItem(IDC_TLB_BOOKMARKS);
  274. GetWindowRect(ctrlWnd, &rwCtrl);
  275. GetWindowRect(GetDlgItem(IDC_LBL_CAPTION), &rwLV);
  276. SetWindowPos(ctrlWnd, NULL, 0, 0, rwCtrl.right - rwCtrl.left, rwBtn.bottom - rwLV.top, SWP_NOACTIVATE | SWP_NOZORDER | SWP_NOMOVE);
  277. }
  278. void ScanFolderBrowser::OnSize(UINT nType, int cx, int cy)
  279. {
  280. FolderBrowseEx::DialogProc(WM_SIZE, nType, MAKELPARAM(cx, cy));
  281. RepositionWindows();
  282. }
  283. void ScanFolderBrowser::OnWindowPosChanging(WINDOWPOS *lpwp)
  284. {
  285. if (lpwp->cx < 346 + 88) lpwp->cx = 346 + 88;
  286. }
  287. BOOL ScanFolderBrowser::OnNotify(UINT idCtrl, LPNMHDR pnmh, LRESULT *result)
  288. {
  289. switch(pnmh->code)
  290. {
  291. case NM_CUSTOMDRAW:
  292. switch(pnmh->idFrom)
  293. {
  294. case IDC_TLB_BOOKMARKS:
  295. *result = OnToolBarCustomDraw((LPNMTBCUSTOMDRAW)pnmh);
  296. return TRUE;
  297. }
  298. break;
  299. case TTN_GETDISPINFOW:
  300. OnToolTipGetDispInfo((LPNMTTDISPINFOW)pnmh);
  301. break;
  302. }
  303. return FALSE;
  304. }
  305. BOOL ScanFolderBrowser::OnCommand(UINT idCtrl, UINT idEvnt, HWND hwndCtrl)
  306. {
  307. int tbid;
  308. tbid = idCtrl - TOOLBAR_BTN_STARTID;
  309. if (tbid >= 0 && tbid < buttonsCount)
  310. {
  311. LPITEMIDLIST pidl1 = buttons[tbid].pidl;
  312. SetExpanded(pidl1);
  313. SetSelection(pidl1);
  314. wchar_t test_path[MAX_PATH] = {0};
  315. EnableOK(SHGetPathFromIDListW(pidl1, test_path));
  316. return TRUE;
  317. }
  318. return FALSE;
  319. }
  320. LRESULT ScanFolderBrowser::OnToolBarCustomDraw(LPNMTBCUSTOMDRAW pnmcd)
  321. {
  322. switch(pnmcd->nmcd.dwDrawStage)
  323. {
  324. case CDDS_PREPAINT:
  325. FrameRect(pnmcd->nmcd.hdc, &pnmcd->nmcd.rc, hbBorder);
  326. InflateRect(&pnmcd->nmcd.rc, -1, -1);
  327. IntersectClipRect(pnmcd->nmcd.hdc, pnmcd->nmcd.rc.left, pnmcd->nmcd.rc.top, pnmcd->nmcd.rc.right, pnmcd->nmcd.rc.bottom);
  328. return CDRF_NOTIFYITEMDRAW;
  329. case CDDS_ITEMPREPAINT:
  330. InflateRect(&pnmcd->nmcd.rc, -1, 0);
  331. if (0 == pnmcd->nmcd.rc.top) pnmcd->nmcd.rc.top++;
  332. return CDRF_DODEFAULT;
  333. }
  334. return CDRF_DODEFAULT;
  335. }
  336. void ScanFolderBrowser::OnToolTipGetDispInfo(LPNMTTDISPINFOW lpnmtdi)
  337. {
  338. int tbid;
  339. tbid = lpnmtdi->hdr.idFrom - TOOLBAR_BTN_STARTID;
  340. lpnmtdi->lpszText = (tbid >= 0 && tbid < buttonsCount) ? buttons[tbid].tooltip : L"";
  341. }
  342. INT_PTR ScanFolderBrowser::DialogProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  343. {
  344. LRESULT result;
  345. switch(uMsg)
  346. {
  347. case WM_WINDOWPOSCHANGING: OnWindowPosChanging((WINDOWPOS*)lParam);
  348. case WM_SIZE: OnSize(wParam, LOWORD(lParam), HIWORD(lParam)); return 0;
  349. case WM_NOTIFY:
  350. if (OnNotify(wParam, (LPNMHDR)lParam, &result))
  351. {
  352. SetDialogResult(result);
  353. return TRUE;
  354. }
  355. break;
  356. case WM_COMMAND:
  357. if (OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam)) return 0;
  358. break;
  359. case WM_DESTROY:
  360. if (hbBorder) DeleteObject(hbBorder);
  361. hbBorder = NULL;
  362. bkScanChecked = (BST_CHECKED == IsDlgButtonChecked(GetHandle(), IDC_CHK_BGSCAN));
  363. break;
  364. }
  365. return FolderBrowseEx::DialogProc(uMsg, wParam, lParam);
  366. }
  367. static BOOL LoadXPTheme(void)
  368. {
  369. xpThemeDll = LoadLibraryW(L"UxTheme.dll");
  370. if (!xpThemeDll) return FALSE;
  371. xpCloseThemeData = (XPT_CLOSETHEMEDATA) GetProcAddress(xpThemeDll, "CloseThemeData");
  372. xpIsAppThemed = (XPT_ISAPPTHEMED) GetProcAddress(xpThemeDll, "IsAppThemed");
  373. xpOpenThemeData = (XPT_OPENTHEMEDATA) GetProcAddress(xpThemeDll, "OpenThemeData");
  374. xpGetThemeColor = (XPT_GETTHEMECOLOR) GetProcAddress(xpThemeDll, "GetThemeColor");
  375. if (!xpCloseThemeData || !xpIsAppThemed || !xpOpenThemeData || !xpGetThemeColor) UnloadXPTheme();
  376. return (NULL != xpThemeDll);
  377. }
  378. static void UnloadXPTheme(void)
  379. {
  380. xpCloseThemeData = NULL;
  381. xpIsAppThemed = NULL;
  382. xpOpenThemeData = NULL;
  383. xpGetThemeColor = NULL;
  384. if (xpThemeDll)
  385. {
  386. FreeLibrary(xpThemeDll);
  387. xpThemeDll = NULL;
  388. }
  389. }
  390. static HBRUSH GetBorderBrush(HWND hwnd)
  391. {
  392. HBRUSH hb;
  393. COLORREF clr;
  394. HRESULT result;
  395. clr = 0x00000;
  396. result = S_FALSE;
  397. if(LoadXPTheme())
  398. {
  399. if(xpIsAppThemed())
  400. {
  401. HTHEME ht;
  402. ht = xpOpenThemeData(GetDlgItem(hwnd, IDC_EDT_PATH), L"Edit");
  403. if (ht)
  404. {
  405. result = xpGetThemeColor(ht, GP_BORDER, BSS_FLAT, TMT_BORDERCOLOR, &clr);
  406. xpCloseThemeData(ht);
  407. }
  408. }
  409. UnloadXPTheme();
  410. }
  411. hb = CreateSolidBrush((S_OK == result) ? clr : GetSysColor(COLOR_WINDOWFRAME));
  412. return hb;
  413. }