navigation.cpp 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684
  1. #include "main.h"
  2. #include "./navigation.h"
  3. #include "./resource.h"
  4. #include "./wasabi.h"
  5. #include "./service.h"
  6. #include "../omBrowser/browserView.h"
  7. #include "../winamp/wa_ipc.h"
  8. #include "../replicant/nu/Autowide.h"
  9. #include "../gen_ml/ml_ipc_0313.h"
  10. #include "./local_menu.h"
  11. #include "../gen_ml/menu.h"
  12. #include <strsafe.h>
  13. #define NAVITEM_PREFIX L"nowplaying_svc_"
  14. #define E_NAVITEM_UNKNOWN E_NOINTERFACE
  15. typedef struct __NAVENUMRESULT
  16. {
  17. HNAVITEM hItem;
  18. OmService *service;
  19. UINT serviceId;
  20. LPCWSTR pszPrefix;
  21. INT cchPrefix;
  22. HWND hLibrary;
  23. NAVITEM itemInfo;
  24. WCHAR szBuffer[256];
  25. } NAVENUMRESULT;
  26. typedef struct __FORCEURLDATA
  27. {
  28. UINT serviceId;
  29. LPWSTR url;
  30. } FORCEURLDATA;
  31. #define FORCEURLPROP L"MLNOWPLAYING_FORCEURL"
  32. static void Navigation_RemoveForceUrl()
  33. {
  34. HWND hLibrary = Plugin_GetLibrary();
  35. if (NULL == hLibrary) return;
  36. FORCEURLDATA *data = (FORCEURLDATA*)GetProp(hLibrary, FORCEURLPROP);
  37. RemoveProp(hLibrary, FORCEURLPROP);
  38. if (NULL != data)
  39. {
  40. Plugin_FreeString(data->url);
  41. free(data);
  42. }
  43. }
  44. static HRESULT Navigation_SetForceUrl(UINT serviceId, LPCWSTR pszUrl)
  45. {
  46. if (NULL == pszUrl) return E_INVALIDARG;
  47. HWND hLibrary = Plugin_GetLibrary();
  48. if (NULL == hLibrary) return E_FAIL;
  49. FORCEURLDATA *data = (FORCEURLDATA*)GetProp(hLibrary, FORCEURLPROP);
  50. if (NULL != data)
  51. {
  52. Plugin_FreeString(data->url);
  53. if (data->serviceId != serviceId)
  54. {
  55. free(data);
  56. data = NULL;
  57. }
  58. }
  59. if (NULL == data)
  60. {
  61. data = (FORCEURLDATA*)calloc(1, sizeof(FORCEURLDATA));
  62. if (NULL == data) return E_OUTOFMEMORY;
  63. data->serviceId = serviceId;
  64. }
  65. data->url = Plugin_CopyString(pszUrl);
  66. if (NULL == data->url || FALSE == SetProp(hLibrary, FORCEURLPROP, data))
  67. {
  68. Navigation_RemoveForceUrl();
  69. return E_FAIL;
  70. }
  71. return S_OK;
  72. }
  73. static HRESULT Navigation_GetForceUrl(UINT serviceId, const wchar_t **ppszUrl)
  74. {
  75. if (NULL == ppszUrl) return E_POINTER;
  76. *ppszUrl = NULL;
  77. HWND hLibrary = Plugin_GetLibrary();
  78. if (NULL == hLibrary) return E_FAIL;
  79. FORCEURLDATA *data = (FORCEURLDATA*)GetProp(hLibrary, FORCEURLPROP);
  80. if (NULL == data || data->serviceId != serviceId)
  81. return E_NOINTERFACE;
  82. *ppszUrl = data->url;
  83. return S_OK;
  84. }
  85. static INT Navigation_GetIconIndex(LPCWSTR pszImage)
  86. {
  87. HWND hLibrary = Plugin_GetLibrary();
  88. if (NULL == hLibrary) return -1;
  89. HMLIMGLST hmlilNavigation = MLNavCtrl_GetImageList(hLibrary);
  90. if (NULL == hmlilNavigation) return -1;
  91. MLIMAGESOURCE mlis;
  92. ZeroMemory(&mlis, sizeof(mlis));
  93. mlis.cbSize = sizeof(mlis);
  94. mlis.hInst = NULL;
  95. mlis.bpp = 24;
  96. mlis.lpszName = pszImage;
  97. mlis.type = SRC_TYPE_PNG;
  98. mlis.flags = ISF_FORCE_BPP | ISF_PREMULTIPLY | ISF_LOADFROMFILE;
  99. MLIMAGELISTITEM item;
  100. ZeroMemory(&item, sizeof(item));
  101. item.cbSize = sizeof(item);
  102. item.hmlil = hmlilNavigation;
  103. item.filterUID = MLIF_FILTER3_UID;
  104. item.pmlImgSource = &mlis;
  105. return MLImageList_Add(hLibrary, &item);
  106. }
  107. static HNAVITEM Navigation_CreateItem(HWND hLibrary, HNAVITEM hParent, OmService *service)
  108. {
  109. if (NULL == hLibrary || NULL == service)
  110. return NULL;
  111. WCHAR szName[256] = {0}, szInvariant[64] = {0};
  112. if (FAILED(service->GetName(szName, ARRAYSIZE(szName))))
  113. return NULL;
  114. if (FAILED(StringCchPrintf(szInvariant, ARRAYSIZE(szInvariant), NAVITEM_PREFIX L"%u", service->GetId())))
  115. return NULL;
  116. NAVINSERTSTRUCT nis = {0};
  117. nis.hInsertAfter = NULL;
  118. nis.hParent = hParent;
  119. WCHAR szIcon[512] = {0};
  120. INT iIcon = (SUCCEEDED(service->GetIcon(szIcon, ARRAYSIZE(szIcon)))) ?
  121. Navigation_GetIconIndex(szIcon) : -1;
  122. nis.item.cbSize = sizeof(NAVITEM);
  123. nis.item.mask = NIMF_TEXT | NIMF_STYLE | NIMF_TEXTINVARIANT | NIMF_PARAM;
  124. if (-1 != iIcon)
  125. nis.item.mask |= (NIMF_IMAGE | NIMF_IMAGESEL);
  126. nis.item.id = 0;
  127. nis.item.pszText = szName;
  128. nis.item.pszInvariant = szInvariant;
  129. nis.item.style = NIS_ALLOWCHILDMOVE;
  130. nis.item.styleMask = nis.item.style;
  131. nis.item.lParam = (LPARAM)service;
  132. nis.item.iImage = iIcon;
  133. nis.item.iSelectedImage = iIcon;
  134. HNAVITEM hItem = MLNavCtrl_InsertItem(hLibrary, &nis);
  135. if (NULL != hItem)
  136. service->AddRef();
  137. return hItem;
  138. }
  139. static HNAVITEM Navigation_GetMessageItem(INT msg, INT_PTR param1)
  140. {
  141. HWND hLibrary = Plugin_GetLibrary();
  142. HNAVITEM hItem = (msg < ML_MSG_NAVIGATION_FIRST) ? MLNavCtrl_FindItemById(hLibrary, param1) : (HNAVITEM)param1;
  143. return hItem;
  144. }
  145. static HRESULT Navigation_GetService(HWND hLibrary, HNAVITEM hItem, OmService **service)
  146. {
  147. WCHAR szBuffer[64] = {0};
  148. if (NULL == service) return E_POINTER;
  149. *service = NULL;
  150. if (NULL == hLibrary || NULL == hItem) return E_INVALIDARG;
  151. NAVITEM itemInfo = {0};
  152. itemInfo.cbSize = sizeof(NAVITEM);
  153. itemInfo.hItem = hItem;
  154. itemInfo.pszInvariant = szBuffer;
  155. itemInfo.cchInvariantMax = ARRAYSIZE(szBuffer);
  156. itemInfo.mask = NIMF_PARAM | NIMF_TEXTINVARIANT;
  157. if (FALSE == MLNavItem_GetInfo(hLibrary, &itemInfo))
  158. return E_FAIL;
  159. INT cchInvariant = lstrlen(szBuffer);
  160. INT cchPrefix = ARRAYSIZE(NAVITEM_PREFIX) - 1;
  161. if (cchInvariant <= cchPrefix ||
  162. CSTR_EQUAL != CompareString(CSTR_INVARIANT, 0, NAVITEM_PREFIX, cchPrefix, szBuffer, cchPrefix))
  163. {
  164. return E_NAVITEM_UNKNOWN;
  165. }
  166. *service = (OmService*)itemInfo.lParam;
  167. (*service)->AddRef();
  168. return S_OK;
  169. }
  170. static BOOL CALLBACK Navigation_ItemEnumerator(HNAVITEM hItem, LPARAM param)
  171. {
  172. if (NULL == hItem) return TRUE;
  173. NAVENUMRESULT *result = (NAVENUMRESULT*)param;
  174. if (NULL == result) return FALSE;
  175. result->itemInfo .hItem = hItem;
  176. if (FALSE != MLNavItem_GetInfo(result->hLibrary, &result->itemInfo) &&
  177. CSTR_EQUAL == CompareString(CSTR_INVARIANT, NORM_IGNORECASE, result->itemInfo.pszInvariant, result->cchPrefix,
  178. result->pszPrefix, result->cchPrefix))
  179. {
  180. OmService *service = (OmService*)result->itemInfo.lParam;
  181. if (NULL != service && service->GetId() == result->serviceId)
  182. {
  183. result->hItem = hItem;
  184. result->service = service;
  185. service->AddRef();
  186. return FALSE;
  187. }
  188. }
  189. return TRUE;
  190. }
  191. static HRESULT Navigation_CreateView(HNAVITEM hItem, HWND hParent, HWND *hView)
  192. {
  193. if (NULL == hView) return E_POINTER;
  194. *hView = NULL;
  195. HWND hLibrary = Plugin_GetLibrary();
  196. if (NULL == hLibrary) return E_UNEXPECTED;
  197. if (NULL == hItem || NULL == hParent) return E_INVALIDARG;
  198. HRESULT hr;
  199. OmService *service = NULL;
  200. hr = Navigation_GetService(hLibrary, hItem, &service);
  201. if (SUCCEEDED(hr))
  202. {
  203. if (NULL == OMBROWSERMNGR)
  204. hr = E_UNEXPECTED;
  205. if (SUCCEEDED(hr))
  206. {
  207. hr = OMBROWSERMNGR->Initialize(NULL, Plugin_GetWinamp());
  208. if (SUCCEEDED(hr))
  209. {
  210. LPCWSTR forceUrl;
  211. if (FAILED(Navigation_GetForceUrl(service->GetId(), &forceUrl)))
  212. forceUrl = NULL;
  213. hr = OMBROWSERMNGR->CreateView(service, hParent, forceUrl, 0, hView);
  214. Navigation_RemoveForceUrl();
  215. }
  216. }
  217. wchar_t nowplayingurl[1024] = {0};
  218. // May 2022 - this service url is dead and would need either fixing up or replacing
  219. lstrcpynW(nowplayingurl, AutoWide(g_config->ReadString("nowplayingurl", "http://client.winamp.com/nowplaying")), ARRAYSIZE(nowplayingurl));
  220. service->SetUrl(nowplayingurl[0] ? nowplayingurl : SERVICE_HOMEURL);
  221. service->Release();
  222. }
  223. return hr;
  224. }
  225. static BOOL Navigation_GetViewRect(RECT *rect)
  226. {
  227. if (NULL == rect) return FALSE;
  228. HWND hWinamp = Plugin_GetWinamp();
  229. HWND hLibrary = Plugin_GetLibrary();
  230. if (NULL == hWinamp || NULL == hLibrary)
  231. return FALSE;
  232. HWND hFrame = (HWND)SENDMLIPC(hLibrary, ML_IPC_GETCURRENTVIEW, 0);
  233. if (NULL == hFrame)
  234. hFrame = hLibrary;
  235. return GetWindowRect(hFrame, rect);
  236. }
  237. static HRESULT Navigation_CreatePopup(HNAVITEM hItem, HWND *hWindow)
  238. {
  239. if (NULL == hWindow) return E_POINTER;
  240. *hWindow = NULL;
  241. HWND hLibrary = Plugin_GetLibrary();
  242. if (NULL == hLibrary) return E_UNEXPECTED;
  243. if (NULL == hItem) return E_INVALIDARG;
  244. HRESULT hr;
  245. OmService *service;
  246. hr = Navigation_GetService(hLibrary, hItem, &service);
  247. if (SUCCEEDED(hr))
  248. {
  249. HWND hWinamp = Plugin_GetWinamp();
  250. if (NULL == OMBROWSERMNGR)
  251. hr = E_UNEXPECTED;
  252. if (SUCCEEDED(hr))
  253. {
  254. hr = OMBROWSERMNGR->Initialize(NULL, hWinamp);
  255. if (SUCCEEDED(hr))
  256. {
  257. RECT rect;
  258. if (FALSE == Navigation_GetViewRect(&rect))
  259. hr = E_FAIL;
  260. if (SUCCEEDED(hr))
  261. {
  262. rect.left += 16;
  263. rect.top += 16;
  264. hr = OMBROWSERMNGR->CreatePopup(service, rect.left, rect.top,
  265. rect.right - rect.left, rect.bottom - rect.top, hWinamp, NULL, 0, hWindow);
  266. }
  267. }
  268. }
  269. service->Release();
  270. }
  271. return hr;
  272. }
  273. static void Navigation_OnDestroy()
  274. {
  275. Navigation_RemoveForceUrl();
  276. if (NULL != OMBROWSERMNGR)
  277. {
  278. OMBROWSERMNGR->Finish();
  279. }
  280. }
  281. static void Navigation_OpenPreferences()
  282. {
  283. winampMediaLibraryPlugin *(*gp)();
  284. gp = (winampMediaLibraryPlugin * (__cdecl *)(void))GetProcAddress(GetModuleHandle(L"ml_online.dll"), "winampGetMediaLibraryPlugin");
  285. if (gp)
  286. {
  287. winampMediaLibraryPlugin *mlplugin = gp();
  288. if (mlplugin && (mlplugin->version >= MLHDR_VER_OLD && mlplugin->version <= MLHDR_VER))
  289. {
  290. mlplugin->MessageProc(ML_MSG_CONFIG, 0, 0, 0);
  291. }
  292. else
  293. SendMessage(Plugin_GetWinamp(), WM_WA_IPC, (WPARAM)-1, IPC_OPENPREFSTOPAGE);
  294. }
  295. else
  296. SendMessage(Plugin_GetWinamp(), WM_WA_IPC, (WPARAM)-1, IPC_OPENPREFSTOPAGE);
  297. }
  298. static HRESULT Navigation_ShowContextMenu(HNAVITEM hItem, HWND hHost, POINTS pts)
  299. {
  300. if (NULL == hItem || NULL == hHost)
  301. return E_INVALIDARG;
  302. HWND hLibrary = Plugin_GetLibrary();
  303. if (NULL == hLibrary) return E_UNEXPECTED;
  304. HRESULT hr;
  305. OmService *service;
  306. hr = Navigation_GetService(hLibrary, hItem, &service);
  307. if (FAILED(hr)) return hr;
  308. POINT pt;
  309. POINTSTOPOINT(pt, pts);
  310. if (-1 == pt.x || -1 == pt.y)
  311. {
  312. NAVITEMGETRECT itemRect;
  313. itemRect.fItem = FALSE;
  314. itemRect.hItem = hItem;
  315. if (MLNavItem_GetRect(hLibrary, &itemRect))
  316. {
  317. MapWindowPoints(hHost, HWND_DESKTOP, (POINT*)&itemRect.rc, 2);
  318. pt.x = itemRect.rc.left + 2;
  319. pt.y = itemRect.rc.top + 2;
  320. }
  321. }
  322. HMENU hMenu = Menu_GetMenu(MENU_NAVIGATIONCONTEXT);
  323. if (NULL != hMenu)
  324. {
  325. INT commandId = Menu_TrackPopup(hLibrary, hMenu,
  326. TPM_LEFTALIGN | TPM_TOPALIGN | TPM_NONOTIFY | TPM_RETURNCMD,
  327. pt.x, pt.y, hHost, NULL);
  328. Menu_ReleaseMenu(hMenu, MENU_NAVIGATIONCONTEXT);
  329. switch(commandId)
  330. {
  331. case ID_NAVIGATION_OPEN:
  332. MLNavItem_Select(hLibrary, hItem);
  333. break;
  334. case ID_NAVIGATION_OPENNEWWINDOW:
  335. {
  336. HWND hWindow;
  337. if (SUCCEEDED(Navigation_CreatePopup(hItem, &hWindow)))
  338. {
  339. ShowWindow(hWindow, SW_SHOWNORMAL);
  340. }
  341. }
  342. break;
  343. case ID_NAVIGATION_HELP:
  344. SENDWAIPC(Plugin_GetWinamp(), IPC_OPEN_URL, L"https://help.winamp.com/hc/articles/8105304048660-The-Winamp-Media-Library");
  345. break;
  346. case ID_PLUGIN_PREFERENCES:
  347. Navigation_OpenPreferences();
  348. break;
  349. }
  350. }
  351. service->Release();
  352. return hr;
  353. }
  354. BOOL Navigation_Initialize(void)
  355. {
  356. OmService *service;
  357. HWND hLibrary = Plugin_GetLibrary();
  358. MLNavCtrl_BeginUpdate(hLibrary, NUF_LOCK_TOP);
  359. if (SUCCEEDED(OmService::CreateInstance(&service)))
  360. {
  361. HNAVITEM hParent = NULL;
  362. Navigation_CreateItem(hLibrary, hParent, service);
  363. service->Release();
  364. }
  365. MLNavCtrl_EndUpdate(hLibrary);
  366. return TRUE;
  367. }
  368. static void Navigation_OnDeleteItem(HNAVITEM hItem)
  369. {
  370. if (NULL == hItem) return;
  371. HWND hLibrary = Plugin_GetLibrary();
  372. if (NULL == hLibrary) return;
  373. OmService *service;
  374. if (SUCCEEDED(Navigation_GetService(hLibrary, hItem, &service)))
  375. {
  376. NAVITEM itemInfo;
  377. itemInfo.cbSize = sizeof(NAVITEM);
  378. itemInfo.hItem = hItem;
  379. itemInfo.mask = NIMF_PARAM;
  380. itemInfo.lParam = 0L;
  381. MLNavItem_SetInfo(hLibrary, &itemInfo);
  382. service->Release(); // create
  383. service->Release(); // Navigation_GetService
  384. }
  385. }
  386. BOOL Navigation_ProcessMessage(INT msg, INT_PTR param1, INT_PTR param2, INT_PTR param3, INT_PTR *result)
  387. {
  388. if (msg == ML_MSG_NO_CONFIG)
  389. {
  390. if (!GetModuleHandle(L"ml_online.dll"))
  391. {
  392. *result = TRUE;
  393. return TRUE;
  394. }
  395. }
  396. else if (msg == ML_MSG_CONFIG)
  397. {
  398. Navigation_OpenPreferences();
  399. *result = TRUE;
  400. return TRUE;
  401. }
  402. if (msg < ML_MSG_TREE_BEGIN || msg > ML_MSG_TREE_END)
  403. return FALSE;
  404. switch(msg)
  405. {
  406. case ML_MSG_TREE_ONCREATEVIEW:
  407. {
  408. HWND hView;
  409. HNAVITEM hItem = Navigation_GetMessageItem(msg, param1);
  410. HRESULT hr = Navigation_CreateView(hItem, (HWND)param2, &hView);
  411. if (SUCCEEDED(hr))
  412. {
  413. *result = (INT_PTR)hView;
  414. return TRUE;
  415. }
  416. }
  417. break;
  418. case ML_MSG_NAVIGATION_ONDESTROY:
  419. Navigation_OnDestroy();
  420. break;
  421. case ML_MSG_NAVIGATION_CONTEXTMENU:
  422. {
  423. HNAVITEM hItem = Navigation_GetMessageItem(msg, param1);
  424. HRESULT hr = Navigation_ShowContextMenu(hItem, (HWND)param2, MAKEPOINTS(param3));
  425. if (SUCCEEDED(hr))
  426. {
  427. *result = TRUE;
  428. return TRUE;
  429. }
  430. }
  431. break;
  432. case ML_MSG_NAVIGATION_ONDELETE:
  433. {
  434. HNAVITEM hItem = Navigation_GetMessageItem(msg, param1);
  435. Navigation_OnDeleteItem(hItem);
  436. break;
  437. }
  438. }
  439. return FALSE;
  440. }
  441. HNAVITEM Navigation_FindService(UINT serviceId, OmService **serviceOut)
  442. {
  443. NAVENUMRESULT result;
  444. result.hItem = NULL;
  445. result.service = NULL;
  446. result.serviceId = serviceId;
  447. result.pszPrefix = NAVITEM_PREFIX;
  448. result.cchPrefix = lstrlen(result.pszPrefix);
  449. result.hLibrary = Plugin_GetLibrary();
  450. result.itemInfo.cbSize = sizeof(result.itemInfo);
  451. result.itemInfo.mask = NIMF_TEXTINVARIANT | NIMF_PARAM;
  452. result.itemInfo.cchInvariantMax = ARRAYSIZE(result.szBuffer);
  453. result.itemInfo.pszInvariant = result.szBuffer;
  454. NAVCTRLENUMPARAMS param;
  455. param.enumProc = Navigation_ItemEnumerator;
  456. param.hItemStart = NULL;
  457. param.lParam = (LPARAM)&result;
  458. if (NULL != result.hLibrary)
  459. MLNavCtrl_EnumItems(result.hLibrary, &param);
  460. if (NULL != serviceOut)
  461. *serviceOut = result.service;
  462. else if (NULL != result.service)
  463. result.service->Release();
  464. return result.hItem;
  465. }
  466. HRESULT Navigation_ShowService(UINT serviceId, LPCWSTR pszUrl, UINT navFlags)
  467. {
  468. HWND hLibrary = Plugin_GetLibrary();
  469. if (NULL == hLibrary)
  470. return E_FAIL;
  471. OmService *service;
  472. HNAVITEM hItem = Navigation_FindService(serviceId, &service);
  473. if (NULL == hItem)
  474. return E_FAIL;
  475. OmService *activeService;
  476. HWND hView = Navigation_GetActiveView(&activeService);
  477. if (NULL == hView || activeService->GetId() != service->GetId())
  478. {
  479. hView = NULL;
  480. activeService = NULL;
  481. }
  482. HRESULT hr = S_OK;
  483. if (NULL != hView)
  484. {
  485. if (NULL == pszUrl && 0 != (NAVFLAG_FORCEACTIVE & navFlags))
  486. pszUrl = NAVIGATE_HOME;
  487. if (NULL != pszUrl && FALSE == BrowserView_Navigate(hView, pszUrl, TRUE))
  488. hr = E_FAIL;
  489. }
  490. else
  491. {
  492. if (NULL != pszUrl)
  493. hr = Navigation_SetForceUrl(serviceId, pszUrl);
  494. else
  495. Navigation_RemoveForceUrl();
  496. if (SUCCEEDED(hr) && FALSE == MLNavItem_Select(hLibrary, hItem))
  497. {
  498. Navigation_RemoveForceUrl();
  499. hr = E_FAIL;
  500. }
  501. }
  502. if (SUCCEEDED(hr))
  503. {
  504. if (0 != (NAVFLAG_ENSUREITEMVISIBLE & navFlags))
  505. MLNavItem_EnsureVisible(hLibrary, hItem);
  506. if (0 != (NAVFLAG_ENSUREMLVISIBLE & navFlags))
  507. SENDMLIPC(hLibrary, ML_IPC_ENSURE_VISIBLE, 0L);
  508. }
  509. service->Release();
  510. if (NULL != activeService)
  511. activeService->Release();
  512. return hr;
  513. }
  514. HNAVITEM Navigation_GetActive(OmService **serviceOut)
  515. {
  516. HWND hLibrary = Plugin_GetLibrary();
  517. OmService *service;
  518. HNAVITEM hActive = (NULL != hLibrary) ? MLNavCtrl_GetSelection(hLibrary) : NULL;
  519. if (NULL == hActive || FAILED(Navigation_GetService(hLibrary, hActive, &service)))
  520. {
  521. hActive = NULL;
  522. service = NULL;
  523. }
  524. if (NULL != serviceOut)
  525. *serviceOut = service;
  526. return hActive;
  527. }
  528. HWND Navigation_GetActiveView(OmService **serviceOut)
  529. {
  530. HWND hLibrary = Plugin_GetLibrary();
  531. if (NULL == hLibrary)
  532. {
  533. if (NULL != serviceOut) *serviceOut = NULL;
  534. return NULL;
  535. }
  536. HWND hView =((HWND)SENDMLIPC(hLibrary, ML_IPC_GETCURRENTVIEW, 0));
  537. if (NULL != hView)
  538. {
  539. WCHAR szBuffer[128] = {0};
  540. if (!GetClassName(hView, szBuffer, ARRAYSIZE(szBuffer)) || CSTR_EQUAL != CompareStringW(CSTR_INVARIANT, NORM_IGNORECASE, szBuffer, -1, L"Nullsoft_omBrowserView", -1))
  541. hView = NULL;
  542. }
  543. OmService *service;
  544. HNAVITEM hActive = (NULL != hLibrary) ? MLNavCtrl_GetSelection(hLibrary) : NULL;
  545. if (NULL == hView || FALSE == BrowserView_GetService(hView, &service))
  546. {
  547. hView = NULL;
  548. service = NULL;
  549. }
  550. if (NULL != serviceOut)
  551. *serviceOut = service;
  552. else if (NULL != service)
  553. service->Release();
  554. return hView;
  555. }