view_ml.cpp 50 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723
  1. #include "main.h"
  2. #include "api__gen_ml.h"
  3. #include <windowsx.h>
  4. #include <time.h>
  5. #include <rpc.h>
  6. #include "../winamp/gen.h"
  7. #include "resource.h"
  8. #include "../nu/ns_wc.h"
  9. #include "config.h"
  10. #include "../winamp/ipc_pe.h"
  11. #include "../winamp/wa_dlg.h"
  12. #include "ml.h"
  13. #include "ml_ipc.h"
  14. #include "sendto.h"
  15. #include "../gen_hotkeys/wa_hotkeys.h"
  16. #include "MediaLibraryCOM.h"
  17. #include "../nu/CCVersion.h"
  18. #include "../nu/AutoWide.h"
  19. #include "../nu/AutoChar.h"
  20. #include "./navigation.h"
  21. #include "./ml_imagelist.h"
  22. #include "./ml_imagefilter.h"
  23. #include "./imagefilters.h" // default filters
  24. #include <shlwapi.h>
  25. #include "./ml_ipc_0313.h"
  26. #include "./skinning.h"
  27. #include "./ml_ratingcolumn.h"
  28. #include "./ml_cloudcolumn.h"
  29. #include "./colors.h"
  30. #include "./stockobjects.h"
  31. #include "./service.h"
  32. #include "./skinnedbutton.h"
  33. #include "../Winamp/wasabicfg.h"
  34. #ifdef _DEBUG
  35. #define BETA
  36. #endif
  37. // messages
  38. #define WMML_FIRST (WM_APP + 0)
  39. #define WMML_UPDATEVIEW (WMML_FIRST + 1)
  40. #define WMML_SHOWCONTAINER (WMML_FIRST + 10)
  41. #define BLOCK_ACCELTOGGLE_PROP TEXT("BLOCK_ACCELTOGGLE")
  42. // timers
  43. #define TIMER_UPDATEVIEW_ID 1970
  44. #define TIMER_UPDATEVIEW_DELAY 7
  45. #define TIMER_NAVAUTOSCROLL_ID 1971
  46. #define TIMER_NAVAUTOSCROLL_DELAY 80
  47. #define TIMER_NAVAUTOEXPAND_ID 1972
  48. #define TIMER_NAVAUTOEXPAND_DELAY 500
  49. #define TIMER_UNBLOCKACCELTOGGLE_ID 1973
  50. #define TIMER_UNBLOCKACCELTOGGLE_DELAY 200
  51. #define IDC_CURRENTVIEW 0x1001
  52. #define IDC_NAVIGATION 0x03FD // (this is the same that old versions used)
  53. #define MEDIALIBRARY_HELP_URL L"https://help.winamp.com/hc/articles/8105304048660-The-Winamp-Media-Library"
  54. SendToMenu *main_sendtomenu;
  55. HMENU main_sendto_hmenu;
  56. int main_sendto_mode;
  57. extern "C" HWND g_ownerwnd;
  58. static int ldiv_clickoffs, ldiv_paintleftborder;
  59. static WNDPROC ldiv_oldWndProc;
  60. static WNDPROC add_oldWndProc;
  61. HNAVITEM g_treedrag_lastSel;
  62. static HNAVITEM m_query_moving_dragplace;
  63. static HNAVITEM m_query_moving_item, m_query_moving_lastdest;
  64. static int m_query_moving_dragplaceisbelow;
  65. static int m_query_moving;
  66. static int m_query_moving_type;
  67. HWND m_curview_hwnd = NULL;
  68. HNAVCTRL hNavigation = NULL; // navigation control
  69. HMLIMGLST hmlilRating = NULL; // default rating images
  70. HMLIMGLST hmlilCloud = NULL; // default cloud images
  71. UINT ratingGlobalStyle = RATING_DEFAULT_STYLE;
  72. static HMLIMGLST hmlilNavigation = NULL; // default navigation image list
  73. HMLIMGFLTRMNGR hmlifMngr = NULL; /// default image filters
  74. static HRGN g_rgnUpdate = NULL;
  75. static INT divider_pos;
  76. static BOOL firstShow = TRUE;
  77. static BOOL m_nav_autoscroll = FALSE;
  78. static HNAVITEM m_nav_autoexpand_item = NULL;
  79. static HIMAGELIST m_nav_dragitem_imagelist = NULL;
  80. void OpenMediaLibraryPreferences();
  81. typedef struct _LAYOUT
  82. {
  83. INT id;
  84. HWND hwnd;
  85. INT x;
  86. INT y;
  87. INT cx;
  88. INT cy;
  89. DWORD flags;
  90. HRGN rgn;
  91. }LAYOUT, PLAYOUT;
  92. #define SETLAYOUTPOS(_layout, _x, _y, _cx, _cy) { _layout->x=_x; _layout->y=_y;_layout->cx=_cx;_layout->cy=_cy;_layout->rgn=NULL; }
  93. static void LayoutWindows( HWND hwnd, INT divX, BOOL fRedraw )
  94. {
  95. static BOOL useDefer = ( GetVersion() < 0x80000000 );
  96. static INT controls[] = { IDC_BTN_LIB, IDC_NAVIGATION, IDC_VDELIM, IDC_CURRENTVIEW, IDC_NO_VIEW };
  97. RECT rc, ri, roTree;
  98. LAYOUT layout[ sizeof( controls ) / sizeof( controls[ 0 ] ) ], *pl;
  99. INT divCX = 0, btnY;
  100. GetClientRect( hwnd, &rc );
  101. if ( rc.bottom == rc.top || rc.left == rc.right )
  102. return;
  103. if ( rc.bottom > WASABI_API_APP->getScaleY( 2 ) )
  104. rc.bottom -= WASABI_API_APP->getScaleY( 2 );
  105. HRGN rgn = CreateRectRgn( 0, 0, 0, 0 );
  106. if ( divX > rc.right - WASABI_API_APP->getScaleY( 41 ) )
  107. divX = rc.right - WASABI_API_APP->getScaleY( 9 );
  108. if ( divX < WASABI_API_APP->getScaleY( 32 ) )
  109. divX = 0;
  110. else if ( divX > ( rc.right - rc.left ) )
  111. divX = ( rc.right - rc.left );
  112. pl = layout;
  113. btnY = rc.bottom; // in case button is broken
  114. InvalidateRgn( hwnd, NULL, TRUE );
  115. for ( int i = 0; i < sizeof( controls ) / sizeof( controls[ 0 ] ); i++ )
  116. {
  117. pl->id = controls[ i ];
  118. switch ( pl->id )
  119. {
  120. case IDC_NAVIGATION: pl->hwnd = NavCtrlI_GetHWND( hNavigation ); break;
  121. case IDC_CURRENTVIEW: pl->hwnd = m_curview_hwnd; break;
  122. default: pl->hwnd = GetDlgItem( hwnd, pl->id ); break;
  123. }
  124. if ( !pl->hwnd )
  125. continue;
  126. pl->rgn = NULL;
  127. GetWindowRect( pl->hwnd, &ri );
  128. MapWindowPoints( HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2 );
  129. pl->flags = SWP_NOZORDER | SWP_NOACTIVATE | SWP_NOREDRAW | SWP_NOCOPYBITS;
  130. switch ( pl->id )
  131. {
  132. case IDC_BTN_LIB:
  133. {
  134. wchar_t buffer[ 128 ] = { 0 };
  135. GetWindowTextW( pl->hwnd, buffer, ARRAYSIZE( buffer ) );
  136. LRESULT idealSize = MLSkinnedButton_GetIdealSize( pl->hwnd, buffer );
  137. btnY = WASABI_API_APP->getScaleY( HIWORD( idealSize ) );
  138. SETLAYOUTPOS( pl, rc.left, rc.bottom - btnY, rc.left + divX, btnY );
  139. break;
  140. }
  141. case IDC_NAVIGATION:
  142. GetClientRect( pl->hwnd, &roTree );
  143. NavCtrlI_MapPointsTo( hNavigation, hwnd, (LPPOINT)&roTree, 2 );
  144. SETLAYOUTPOS( pl, rc.left, rc.top, rc.left + divX, rc.bottom - btnY - WASABI_API_APP->getScaleY( 3 ) );
  145. ldiv_paintleftborder = ( pl->cx > 0 );
  146. break;
  147. case IDC_VDELIM:
  148. divCX = ( ri.right - ri.left );
  149. SETLAYOUTPOS( pl, divX + WASABI_API_APP->getScaleX( 1 ), rc.top, divCX, max( 0, rc.bottom - rc.top ) );
  150. break;
  151. case IDC_CURRENTVIEW: // current view;
  152. SETLAYOUTPOS( pl, divX + divCX, rc.top, max( 0, rc.right - pl->x - WASABI_API_APP->getScaleX( 2 ) ), max( 0, rc.bottom - rc.top ) );
  153. if ( !SendMessage( pl->hwnd, WM_USER + 0x200, 0, 0 ) ) pl->flags &= ~( SWP_NOREDRAW );
  154. break;
  155. case IDC_NO_VIEW:
  156. SETLAYOUTPOS( pl, divX + divCX + 20, rc.top, max( 0, rc.right - pl->x - WASABI_API_APP->getScaleX( 2 ) - 20 ), max( 0, rc.bottom - rc.top ) );
  157. if ( !SendMessage( pl->hwnd, WM_USER + 0x200, 0, 0 ) ) pl->flags &= ~( SWP_NOREDRAW );
  158. break;
  159. }
  160. if ( pl->x == ri.left && pl->y == ri.top )
  161. pl->flags |= SWP_NOMOVE;
  162. if ( pl->cx == ( ri.right - ri.left ) && pl->cy == ( ri.bottom - ri.top ) )
  163. pl->flags |= SWP_NOSIZE;
  164. if ( ( SWP_NOMOVE | SWP_NOSIZE ) != ( ( SWP_NOMOVE | SWP_NOSIZE ) & pl->flags ) )
  165. pl++;
  166. else if ( IsWindowVisible( pl->hwnd ) )
  167. {
  168. ValidateRect( hwnd, &ri );
  169. if ( GetUpdateRect( pl->hwnd, NULL, FALSE ) )
  170. {
  171. GetUpdateRgn( pl->hwnd, rgn, FALSE );
  172. OffsetRgn( rgn, pl->x, pl->y );
  173. InvalidateRgn( hwnd, rgn, FALSE );
  174. }
  175. }
  176. }
  177. if ( pl != layout )
  178. {
  179. LAYOUT *pc;
  180. HDWP hdwp = ( useDefer ) ? BeginDeferWindowPos( (INT)( pl - layout ) ) : NULL;
  181. for ( pc = layout; pc < pl && ( !useDefer || hdwp ); pc++ )
  182. {
  183. if ( IDC_CURRENTVIEW == pc->id && ( SWP_NOREDRAW & pc->flags ) && IsWindowVisible( pc->hwnd ) )
  184. {
  185. if ( !pc->rgn )
  186. pc->rgn = CreateRectRgn( 0, 0, pc->cx, pc->cy );
  187. GetWindowRect( pc->hwnd, &ri );
  188. NavCtrlI_MapPointsFrom( hNavigation, HWND_DESKTOP, (LPPOINT)&ri, 1 );
  189. SendMessage( pc->hwnd, WM_USER + 0x201, MAKEWPARAM( pc->x - ri.left, pc->y - ri.top ), (LPARAM)pc->rgn );
  190. }
  191. if ( useDefer )
  192. hdwp = DeferWindowPos( hdwp, pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags );
  193. else
  194. SetWindowPos( pc->hwnd, NULL, pc->x, pc->y, pc->cx, pc->cy, pc->flags );
  195. }
  196. if ( hdwp )
  197. EndDeferWindowPos( hdwp );
  198. for ( pc = layout; pc < pl; pc++ )
  199. {
  200. if ( IDC_NAVIGATION == pc->id )
  201. {
  202. GetWindowRect( pc->hwnd, &ri );
  203. OffsetRect( &ri, -ri.left, -ri.top );
  204. pc->rgn = CreateRectRgnIndirect( &ri );
  205. GetClientRect( pc->hwnd, &ri );
  206. NavCtrlI_MapPointsTo( hNavigation, hwnd, (LPPOINT)&ri, 1 );
  207. IntersectRect( &ri, &roTree, &ri );
  208. SetRectRgn( rgn, ri.left, ri.top, ri.right, ri.bottom );
  209. CombineRgn( pc->rgn, pc->rgn, rgn, RGN_DIFF );
  210. if ( GetUpdateRect( pc->hwnd, NULL, FALSE ) )
  211. {
  212. GetUpdateRgn( pc->hwnd, rgn, FALSE );
  213. CombineRgn( pc->rgn, pc->rgn, rgn, RGN_OR );
  214. }
  215. }
  216. else if ( IDC_CURRENTVIEW == pc->id && pc->rgn )
  217. SendMessage( pc->hwnd, WM_USER + 0x201, 0, 0L );
  218. if ( IsWindowVisible( pc->hwnd ) )
  219. {
  220. GetWindowRect( pc->hwnd, &ri );
  221. MapWindowPoints( HWND_DESKTOP, hwnd, (LPPOINT)&ri, 2 );
  222. ValidateRect( hwnd, &ri );
  223. }
  224. }
  225. if ( fRedraw )
  226. {
  227. HRGN rgnTmp = CreateRectRgn( 0, 0, 0, 0 );
  228. GetUpdateRgn( hwnd, rgn, FALSE );
  229. for ( pc = layout; pc < pl; pc++ )
  230. {
  231. if ( SWP_NOREDRAW & pc->flags )
  232. {
  233. if ( pc->rgn )
  234. OffsetRgn( pc->rgn, pc->x, pc->y );
  235. else
  236. SetRectRgn( rgnTmp, pc->x, pc->y, pc->x + pc->cx, pc->y + pc->cy );
  237. CombineRgn( rgn, rgn, ( pc->rgn ) ? pc->rgn : rgnTmp, RGN_OR );
  238. }
  239. }
  240. DeleteObject( rgnTmp );
  241. RedrawWindow( hwnd, NULL, rgn, RDW_INVALIDATE | RDW_ERASE | RDW_UPDATENOW | RDW_ERASENOW | RDW_ALLCHILDREN );
  242. }
  243. else if ( g_rgnUpdate )
  244. {
  245. GetUpdateRgn( hwnd, g_rgnUpdate, FALSE );
  246. ValidateRect( hwnd, NULL );
  247. for ( pc = layout; pc < pl; pc++ )
  248. {
  249. if ( SWP_NOREDRAW & pc->flags )
  250. {
  251. if ( pc->rgn )
  252. OffsetRgn( pc->rgn, pc->x, pc->y );
  253. else
  254. SetRectRgn( rgn, pc->x, pc->y, pc->x + pc->cx, pc->y + pc->cy );
  255. CombineRgn( g_rgnUpdate, g_rgnUpdate, ( pc->rgn ) ? pc->rgn : rgn, RGN_OR );
  256. }
  257. }
  258. }
  259. for ( pc = layout; pc < pl; pc++ )
  260. if ( pc->rgn )
  261. DeleteObject( pc->rgn );
  262. }
  263. if ( rgn )
  264. DeleteObject( rgn );
  265. }
  266. // a default right-pane view to show if a plugin failed to return us an HWND
  267. static INT_PTR CALLBACK view_Error( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  268. {
  269. if ( uMsg == WM_INITDIALOG )
  270. {
  271. ShowWindow( GetDlgItem( g_hwnd, IDC_NO_VIEW ), SW_SHOW );
  272. }
  273. return WADlg_handleDialogMsgs( hwndDlg, uMsg, wParam, lParam );
  274. }
  275. static void CreateCurrentView( HWND hwndDlg )
  276. {
  277. HNAVITEM hItem;
  278. DLGPROC proc;
  279. proc = view_Error;
  280. hItem = NavCtrlI_GetSelection( hNavigation );
  281. if ( hItem )
  282. {
  283. INT itemId = NavItemI_GetId( hItem );
  284. #if 0
  285. #ifdef BETA
  286. wchar_t pszText[ 32 ] = { 0 };
  287. if ( NavItemI_GetInvariantText( hItem, pszText, 32 ) && !lstrcmpW( pszText, L"winamp_labs" ) )
  288. {
  289. OmService *om_service;
  290. OmService::CreateInstance( SERVICE_LABS, L"Winamp Labs", &om_service );
  291. if ( AGAVE_OBJ_BROWSER )
  292. {
  293. HWND hView = 0;
  294. HRESULT hr = AGAVE_OBJ_BROWSER->CreateView( om_service, (HWND)hwndDlg, 0, 0, &hView );
  295. om_service->Release();
  296. if ( SUCCEEDED( hr ) )
  297. {
  298. m_curview_hwnd = hView;
  299. }
  300. }
  301. }
  302. else
  303. #endif
  304. #endif
  305. m_curview_hwnd = (HWND)plugin_SendMessage( ML_MSG_TREE_ONCREATEVIEW, (INT_PTR)itemId, (INT_PTR)hwndDlg, 0 );
  306. }
  307. if ( !IsWindow( m_curview_hwnd ) )
  308. m_curview_hwnd = WASABI_API_CREATEDIALOGPARAMW( IDD_VIEW_EMPTY, hwndDlg, proc, 0 );
  309. else
  310. ShowWindow( GetDlgItem( g_hwnd, IDC_NO_VIEW ), SW_HIDE );
  311. if ( IsWindow( m_curview_hwnd ) )
  312. {
  313. SetWindowPos( m_curview_hwnd, NavCtrlI_GetHWND( hNavigation ), 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOMOVE | SWP_NOSIZE | SWP_NOREDRAW );
  314. LayoutWindows( hwndDlg, divider_pos, FALSE );
  315. // moved 08/12/09 from start of block to here along with SkinnedWnd::OnSkinChanged(..) change to hopefully resolve bold font issues
  316. MLSkinnedWnd_SkinChanged( m_curview_hwnd, TRUE, FALSE );
  317. ShowWindow( m_curview_hwnd, SW_SHOWNORMAL );
  318. RedrawWindow( m_curview_hwnd, NULL, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN );
  319. PostMessage( m_curview_hwnd, WMML_UPDATEVIEW, 0, 0 ); //refresh view
  320. }
  321. }
  322. static void DisplayItemDragImage( HNAVITEM hItem, LPCWSTR pszTip, HWND hwndOwner, POINT *ppt ) // ppt in hwndOwner coordinates
  323. {
  324. if ( !hwndOwner )
  325. return;
  326. if ( m_nav_dragitem_imagelist )
  327. {
  328. ImageList_DragLeave( hwndOwner );
  329. ImageList_EndDrag();
  330. ImageList_Destroy( m_nav_dragitem_imagelist );
  331. }
  332. m_nav_dragitem_imagelist = NavItemI_CreateDragImage( hItem, pszTip );
  333. if ( m_nav_dragitem_imagelist )
  334. {
  335. INT cx, cy;
  336. ImageList_GetIconSize( m_nav_dragitem_imagelist, &cx, &cy );
  337. if ( ImageList_BeginDrag( m_nav_dragitem_imagelist, 0, cx / 2, cy / 2 ) )
  338. {
  339. NavCtrlI_Update( hNavigation );
  340. ImageList_DragEnter( hwndOwner, ppt->x, ppt->y );
  341. }
  342. }
  343. }
  344. VOID CALLBACK CreateViewTimerProc( HWND hwnd, UINT uMsg, UINT_PTR idEvent, DWORD dwTime )
  345. {
  346. if ( idEvent == TIMER_UPDATEVIEW_ID )
  347. {
  348. KillTimer( hwnd, TIMER_UPDATEVIEW_ID );
  349. CreateCurrentView( hwnd );
  350. }
  351. }
  352. static void CALLBACK OnNavCtrl_Selected( HNAVCTRL hMngr, HNAVITEM hItemOld, HNAVITEM hItemNew )
  353. {
  354. KillTimer( g_hwnd, TIMER_UPDATEVIEW_ID );
  355. if ( IsWindow( m_curview_hwnd ) )
  356. {
  357. RedrawWindow( g_hwnd, NULL, NULL, RDW_UPDATENOW | RDW_ALLCHILDREN );
  358. SendMessageW( g_hwnd, WM_SETREDRAW, FALSE, 0L ); // freeze window
  359. ShowWindow( m_curview_hwnd, SW_HIDE );
  360. SendMessageW( g_hwnd, WM_SETREDRAW, TRUE, 0L );
  361. DestroyWindow( m_curview_hwnd );
  362. m_curview_hwnd = NULL;
  363. }
  364. // 07/05/2010 DRO - changed to use a callback proc as ml_disc was managing to trigger
  365. // the same timer message multiple times on (at least) older XP machines which was
  366. // causing multiple ml view dialogs to be created but hidden behind the currently
  367. // opened view - intermittent issue i've been seeing for a year on my XP machine.
  368. SetTimer( g_hwnd, TIMER_UPDATEVIEW_ID, TIMER_UPDATEVIEW_DELAY, CreateViewTimerProc );
  369. }
  370. static BOOL CALLBACK OnNavCtrl_Click( HNAVCTRL hMngr, HNAVITEM hItem, INT actionId )
  371. {
  372. if ( hItem )
  373. {
  374. INT mlAction = -1;
  375. switch ( actionId )
  376. {
  377. case ACTION_CLICKL_I: mlAction = ML_ACTION_LCLICK; break;
  378. case ACTION_CLICKR_I: mlAction = ML_ACTION_RCLICK; break;
  379. case ACTION_ENTER_I: mlAction = ML_ACTION_ENTER; break;
  380. case ACTION_DBLCLICKL_I: mlAction = ML_ACTION_DBLCLICK; break;
  381. case ACTION_DBLCLICKR_I: break;
  382. }
  383. if ( -1 != mlAction )
  384. {
  385. BOOL ret = (BOOL)plugin_SendMessage( ML_MSG_TREE_ONCLICK,
  386. NavItemI_GetId( hItem ),
  387. mlAction,
  388. (INT_PTR)GetParent( NavCtrlI_GetHWND( hMngr ) ) );
  389. if ( mlAction != ML_ACTION_LCLICK )
  390. return ret;
  391. }
  392. }
  393. return FALSE;
  394. }
  395. static BOOL CALLBACK OnNavCtrl_KeyDown( HNAVCTRL hMngr, HNAVITEM hItem, NMTVKEYDOWN *ptvkd )
  396. {
  397. return ( hItem ) ? (BOOL)plugin_SendMessage( ML_MSG_TREE_ONKEYDOWN,
  398. NavItemI_GetId( hItem ),
  399. (INT_PTR)ptvkd,
  400. (INT_PTR)NavCtrlI_GetHWND( hMngr ) ) : FALSE;
  401. }
  402. static BOOL CALLBACK OnNavCtrl_BeginTitleEdit( HNAVCTRL hMngr, HNAVITEM hItem )
  403. {
  404. return !(BOOL)plugin_SendMessage( ML_MSG_NAVIGATION_ONBEGINTITLEEDIT, (INT_PTR)hItem, 0, 0 );
  405. }
  406. static BOOL CALLBACK OnNavCtrl_EndTitleEdit( HNAVCTRL hMngr, HNAVITEM hItem, LPCWSTR pszNewTitle )
  407. {
  408. return (BOOL)plugin_SendMessage( ML_MSG_NAVIGATION_ONENDTITLEEDIT, (INT_PTR)hItem, (INT_PTR)pszNewTitle, 0 );
  409. }
  410. static void CALLBACK OnNavItem_Delete( HNAVCTRL hMngr, HNAVITEM hItem )
  411. {
  412. plugin_SendMessage( ML_MSG_NAVIGATION_ONDELETE, (INT_PTR)hItem, 0, 0 );
  413. }
  414. static void CALLBACK OnNavCtrl_Destroy( HNAVCTRL hMngr )
  415. {
  416. plugin_SendMessage( ML_MSG_NAVIGATION_ONDESTROY, 0, 0, 0 );
  417. }
  418. static INT CALLBACK OnNavItem_CustomDraw( HNAVCTRL hMngr, HNAVITEM hItem, NAVITEMDRAW_I *pnicd, LPARAM lParam )
  419. {
  420. INT result = (INT)plugin_SendMessage( ML_MSG_NAVIGATION_ONCUSTOMDRAW, (INT_PTR)hItem, (INT_PTR)pnicd, (INT_PTR)lParam );
  421. if ( NICDRF_NOTMINE == result )
  422. result = NICDRF_DODEFAULT_I;
  423. return result;
  424. }
  425. static INT CALLBACK OnNavItem_SetCursor( HNAVCTRL hMngr, HNAVITEM hItem, LPARAM lParam )
  426. {
  427. INT result = (INT)plugin_SendMessage( ML_MSG_NAVIGATION_ONSETCURSOR, (INT_PTR)hItem, (INT_PTR)0, (INT_PTR)lParam );
  428. return ( result > 0 );
  429. }
  430. static void CALLBACK OnNavItem_HitTest( HNAVCTRL hMngr, POINT pt, UINT *pHitFlags, HNAVITEM *phItem, LPARAM lParam )
  431. {
  432. NAVHITTEST ht;
  433. ht.flags = *pHitFlags;
  434. ht.pt = pt;
  435. ht.hItem = *phItem;
  436. if ( 0 != plugin_SendMessage( ML_MSG_NAVIGATION_ONHITTEST, (INT_PTR)*phItem, (INT_PTR)&ht, (INT_PTR)lParam ) )
  437. {
  438. *pHitFlags = ht.flags;
  439. *phItem = ht.hItem;
  440. }
  441. }
  442. static void CALLBACK OnNavCtrl_BeginDrag( HNAVCTRL hMngr, HNAVITEM hItem, POINT pt )
  443. {
  444. #ifdef BETA
  445. wchar_t pszText[ 32 ] = { 0 };
  446. if ( ( !( sneak & 4 ) ) && NavItemI_GetInvariantText( hItem, pszText, 32 ) && !lstrcmpW( pszText, L"winamp_labs" ) )
  447. {
  448. return;
  449. }
  450. #endif
  451. if ( plugin_SendMessage( ML_MSG_TREE_ONDRAG, NavItemI_GetId( hItem ), (INT_PTR)&pt, (INT_PTR)&m_query_moving_type ) < 1 )
  452. {
  453. HNAVITEM hParent;
  454. hParent = NavItemI_GetParent( hItem );
  455. m_query_moving_type = ( NULL == hParent || NIS_ALLOWCHILDMOVE_I == NavItemI_GetStyle( hParent, NIS_ALLOWCHILDMOVE_I ) ) ?
  456. ML_TYPE_TREEITEM : ML_TYPE_UNKNOWN;
  457. }
  458. m_query_moving = 1;
  459. m_query_moving_item = hItem;
  460. m_query_moving_dragplace = NULL;
  461. m_query_moving_lastdest = NULL;
  462. m_query_moving_dragplaceisbelow = FALSE;
  463. HWND hwndDlg = GetParent( NavCtrlI_GetHWND( hMngr ) );
  464. NavCtrlI_MapPointsTo( hMngr, hwndDlg, &pt, 1 );
  465. DisplayItemDragImage( hItem, NULL, hwndDlg, &pt );
  466. SetCapture( g_hwnd );
  467. }
  468. static INT CALLBACK OnNavCtrl_GetImageIndex( HNAVCTRL hMngr, HNAVITEM hItem, INT imageType )
  469. {
  470. if ( NavItemI_HasChildren( hItem ) )
  471. {
  472. INT_PTR tag;
  473. tag = ( NavItemI_HasChildrenReal( hItem ) ) ?
  474. ( ( NavItemI_IsExpanded( hItem ) ) ? MLTREEIMAGE_BRANCH_EXPANDED : MLTREEIMAGE_BRANCH_COLLAPSED ) :
  475. MLTREEIMAGE_BRANCH_NOCHILD;
  476. INT mlilIndex = MLImageListI_GetIndexFromTag( NavCtrlI_GetImageList( hMngr ), tag );
  477. return ( -1 != mlilIndex ) ? mlilIndex : 0;
  478. }
  479. return 0;
  480. }
  481. static void OnWindowPosChanged( HWND hwnd, WINDOWPOS *pwp )
  482. {
  483. if ( SWP_NOSIZE != ( ( SWP_NOSIZE | SWP_FRAMECHANGED | SWP_SHOWWINDOW ) & pwp->flags ) )
  484. {
  485. LayoutWindows( hwnd, divider_pos, ( 0 == ( SWP_NOREDRAW & pwp->flags ) ) );
  486. }
  487. }
  488. HWND wa3wnd_fixwnd( HWND h )
  489. {
  490. if ( IsChild( h, g_hwnd ) )
  491. return h; // if the library window is a child of this window, don't touch it
  492. if ( IsChild( h, g_PEWindow ) )
  493. return g_PEWindow; // if the playlist window is a child of this window, treat it as the playlist window
  494. HWND hParent = (HWND)SENDWAIPC( plugin.hwndParent, IPC_GETDIALOGBOXPARENT, 0 );
  495. if ( plugin.hwndParent != hParent && h == hParent )
  496. h = plugin.hwndParent;
  497. //DWORD pid;
  498. //DWORD threadID = GetWindowThreadProcessId(h, &pid);
  499. //if (pid != GetCurrentProcessId() || threadID != GetCurrentThreadId()) return h; // if other process, dont mangle
  500. //char buf[64] = {0};
  501. //GetClassName(h, buf, sizeof(buf) - 1);
  502. //if (!strcmp(buf, "BaseWindow_RootWnd")) return plugin.hwndParent; // if a wa3 window, treat as main window
  503. return h;
  504. }
  505. static void CALLBACK OnDividerMoved( HWND hdiv, INT nPos, LPARAM param )
  506. {
  507. HWND hwndParent;
  508. divider_pos = nPos;
  509. hwndParent = GetParent( hdiv );
  510. LayoutWindows( hwndParent, nPos, TRUE );
  511. }
  512. static void Navigation_DropHelper( HWND hwndDlg, HWND hwndNav, HNAVITEM hItemHit, UINT hitFlags, POINT pt )
  513. {
  514. if ( hItemHit && ( ( NAVHT_ONITEMINDENT_I | NAVHT_ONITEMRIGHT_I | NAVHT_ONITEM_I | NAVHT_ONITEMBUTTON_I ) & hitFlags ) )
  515. {
  516. RECT rc;
  517. GetClientRect( hwndNav, &rc );
  518. if ( !m_nav_autoscroll && ( rc.left <= pt.x && rc.right >= pt.x ) )
  519. {
  520. INT sbCommand;
  521. if ( rc.top <= pt.y && pt.y < ( rc.top + 24 ) )
  522. sbCommand = 1;
  523. else if ( ( rc.bottom - 24 ) < pt.y && pt.y <= rc.bottom )
  524. sbCommand = 2;
  525. else
  526. sbCommand = 0;
  527. if ( sbCommand )
  528. {
  529. SCROLLINFO si = { 0 };
  530. si.cbSize = sizeof( SCROLLINFO );
  531. si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
  532. if ( !GetScrollInfo( hwndNav, SB_VERT, &si ) )
  533. ZeroMemory( &si, sizeof( SCROLLINFO ) );
  534. if ( ( 1 == sbCommand && si.nMin < si.nPos ) || ( 2 == sbCommand && si.nMax >= (INT)( si.nPos + si.nPage ) ) )
  535. {
  536. if ( SetTimer( hwndDlg, TIMER_NAVAUTOSCROLL_ID, TIMER_NAVAUTOSCROLL_DELAY, NULL ) )
  537. m_nav_autoscroll = TRUE;
  538. }
  539. }
  540. }
  541. if ( ( NAVHT_ONITEMBUTTON_I & hitFlags ) && m_nav_autoexpand_item != hItemHit && !NavItemI_IsExpanded( hItemHit ) )
  542. {
  543. KillTimer( hwndDlg, TIMER_NAVAUTOEXPAND_ID );
  544. if ( SetTimer( hwndDlg, TIMER_NAVAUTOEXPAND_ID, TIMER_NAVAUTOEXPAND_DELAY, NULL ) )
  545. m_nav_autoexpand_item = hItemHit;
  546. }
  547. }
  548. }
  549. int handleDragDropMove( HWND hwndDlg, int type, POINT p, int do_cursors )
  550. {
  551. BOOL valid = FALSE;
  552. HWND h = WindowFromPoint( p );
  553. HNAVITEM hItemPrevHilited = g_treedrag_lastSel;
  554. g_treedrag_lastSel = NULL;
  555. if ( h )
  556. {
  557. h = wa3wnd_fixwnd( h );
  558. if ( IsChild( plugin.hwndParent, h ) )
  559. h = plugin.hwndParent;
  560. else if ( g_PEWindow && IsChild( g_PEWindow, h ) )
  561. h = g_PEWindow;
  562. else
  563. {
  564. HWND vid = (HWND)SendMessage( plugin.hwndParent, WM_WA_IPC, IPC_GETWND_VIDEO, IPC_GETWND );
  565. if ( vid )
  566. {
  567. if ( h == vid || IsChild( vid, h ) )
  568. h = plugin.hwndParent;
  569. }
  570. }
  571. if ( h && ( h == plugin.hwndParent || h == g_PEWindow ) )
  572. {
  573. valid = ( type == ML_TYPE_ITEMRECORDLISTW || type == ML_TYPE_ITEMRECORDLIST ||
  574. type == ML_TYPE_FILENAMES || type == ML_TYPE_STREAMNAMES ||
  575. type == ML_TYPE_CDTRACKS ||
  576. type == ML_TYPE_FILENAMESW || type == ML_TYPE_STREAMNAMESW );
  577. }
  578. else if ( h == NavCtrlI_GetHWND( hNavigation ) )
  579. {
  580. HNAVITEM hItemHit, hItemSel;
  581. UINT hitFlags;
  582. POINT pt = p;
  583. MapWindowPoints( HWND_DESKTOP, h, &pt, 1 );
  584. hItemHit = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
  585. hItemSel = NavCtrlI_GetSelection( hNavigation );
  586. Navigation_DropHelper( hwndDlg, h, hItemHit, hitFlags, pt );
  587. if ( hItemHit && hItemHit != hItemSel && ( !m_query_moving_item || NavItemI_GetParent( m_query_moving_item ) != hItemHit ) )
  588. {
  589. valid = ( plugin_SendMessage( ML_MSG_TREE_ONDROPTARGET, NavItemI_GetId( hItemHit ), type, NULL ) > 0 );
  590. if ( valid )
  591. g_treedrag_lastSel = hItemHit;
  592. }
  593. }
  594. else if ( IsWindow( m_curview_hwnd ) && IsWindow( h ) && ( h == m_curview_hwnd || IsChild( m_curview_hwnd, h ) ) )
  595. {
  596. mlDropItemStruct dis = { 0, };
  597. dis.type = type;
  598. dis.p = p;
  599. while ( 1 )
  600. {
  601. SendMessage( h, WM_ML_CHILDIPC, (WPARAM)&dis, ML_CHILDIPC_DROPITEM );
  602. if ( dis.result || h == m_curview_hwnd )
  603. break;
  604. h = GetParent( h ); // traverse up the tree
  605. }
  606. valid = dis.result > 0;
  607. }
  608. }
  609. if ( g_treedrag_lastSel != hItemPrevHilited )
  610. {
  611. ImageList_DragShowNolock( FALSE );
  612. if ( hItemPrevHilited )
  613. NavItemI_SetState( hItemPrevHilited, 0, NIS_DROPHILITED_I );
  614. if ( g_treedrag_lastSel )
  615. NavItemI_SetState( g_treedrag_lastSel, NIS_DROPHILITED_I, NIS_DROPHILITED_I );
  616. NavCtrlI_Update( hNavigation );
  617. ImageList_DragShowNolock( TRUE );
  618. }
  619. if ( do_cursors )
  620. SetCursor( ( valid ) ? hDragNDropCursor : LoadCursor( NULL, IDC_NO ) );
  621. return valid;
  622. }
  623. static void CancelNavigationMove( void )
  624. {
  625. m_query_moving_dragplace = NULL;
  626. ImageList_DragShowNolock( FALSE );
  627. NavCtrlI_SetInsertMark( hNavigation, NULL, FALSE );
  628. NavCtrlI_Update( hNavigation );
  629. ImageList_DragShowNolock( TRUE );
  630. }
  631. static void OnInitMenuPopUp( HMENU menu );
  632. static void OnDisplayChange( HWND hwndDlg, UINT imgDepth, UINT hRes, UINT vRes );
  633. static int OnInitDialog( HWND hwndDlg );
  634. static void OnDestroy( HWND hwndDlg );
  635. static void OnClose( HWND hwndDlg );
  636. static void OnSize( HWND hwndDlg, UINT type, int cx, int cy );
  637. static void OnShowWindow( HWND hwndDlg, BOOL fShow );
  638. LRESULT OnMediaLibraryIPC( HWND hwndDlg, WPARAM wParam, LPARAM lParam );
  639. static void OnGetMaxMinInfo( MINMAXINFO *info );
  640. static void OnBtnLibraryClick( HWND hwndBtn );
  641. static HWND hwndTweak = NULL;
  642. static BOOL CALLBACK RatingTweak_OnApplyChanges( UINT fStyle, BOOL bClosing )
  643. {
  644. ratingGlobalStyle = fStyle;
  645. g_config->WriteInt( L"rating_style", ratingGlobalStyle );
  646. MLRatingColumnI_Update();
  647. if ( IsWindow( m_curview_hwnd ) )
  648. PostMessage( m_curview_hwnd, WM_DISPLAYCHANGE, 0, MAKELPARAM( 0, 0 ) );
  649. if ( bClosing )
  650. hwndTweak = NULL;
  651. return TRUE;
  652. }
  653. static void OnTimer_NavAutoScroll( HWND hwndDlg )
  654. {
  655. RECT rc;
  656. POINT pt;
  657. HWND hwndNav = NavCtrlI_GetHWND( hNavigation );
  658. INT command = 0;
  659. KillTimer( hwndDlg, TIMER_NAVAUTOSCROLL_ID );
  660. if ( !hwndNav || !IsWindowVisible( hwndNav ) )
  661. {
  662. m_nav_autoscroll = FALSE;
  663. return;
  664. }
  665. GetCursorPos( &pt );
  666. NavCtrlI_MapPointsFrom( hNavigation, HWND_DESKTOP, &pt, 1 );
  667. GetClientRect( hwndNav, &rc );
  668. if ( rc.left <= pt.x && rc.right >= pt.x )
  669. {
  670. if ( rc.top <= pt.y && pt.y < ( rc.top + 24 ) )
  671. command = 1;
  672. else if ( ( rc.bottom - 24 ) < pt.y && pt.y <= rc.bottom )
  673. command = 2;
  674. }
  675. if ( command )
  676. {
  677. SCROLLINFO si = { 0 };
  678. si.cbSize = sizeof( SCROLLINFO );
  679. si.fMask = SIF_POS | SIF_RANGE | SIF_PAGE;
  680. if ( !GetScrollInfo( hwndNav, SB_VERT, &si ) )
  681. ZeroMemory( &si, sizeof( SCROLLINFO ) );
  682. if ( ( 1 == command && si.nMin == si.nPos ) || ( 2 == command && si.nMax < (INT)( si.nPos + si.nPage ) ) )
  683. command = 0;
  684. else
  685. {
  686. ImageList_DragShowNolock( FALSE );
  687. SendMessageW( hwndNav, WM_VSCROLL, MAKEWPARAM( ( 1 == command ) ? SB_LINEUP : SB_LINEDOWN, 0 ), NULL );
  688. NavCtrlI_Update( hNavigation );
  689. ImageList_DragShowNolock( TRUE );
  690. SetTimer( hwndDlg, TIMER_NAVAUTOSCROLL_ID, TIMER_NAVAUTOSCROLL_DELAY, NULL );
  691. }
  692. }
  693. if ( !command )
  694. m_nav_autoscroll = FALSE;
  695. }
  696. static void OnTimer_NavAutoExpand( HWND hwndDlg )
  697. {
  698. POINT pt;
  699. HWND hwndNav = NavCtrlI_GetHWND( hNavigation );
  700. HNAVITEM hItem;
  701. UINT hitFlags;
  702. KillTimer( hwndDlg, TIMER_NAVAUTOEXPAND_ID );
  703. if ( !hwndNav || !IsWindowVisible( hwndNav ) )
  704. return;
  705. GetCursorPos( &pt );
  706. NavCtrlI_MapPointsFrom( hNavigation, HWND_DESKTOP, &pt, 1 );
  707. hItem = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
  708. if ( NAVHT_ONITEMBUTTON_I & hitFlags && hItem == m_nav_autoexpand_item )
  709. {
  710. ImageList_DragShowNolock( FALSE );
  711. NavCtrlI_SetInsertMark( hNavigation, NULL, FALSE );
  712. NavItemI_Expand( hItem, NAVITEM_EXPAND_I );
  713. NavCtrlI_Update( hNavigation );
  714. ImageList_DragShowNolock( TRUE );
  715. }
  716. m_nav_autoexpand_item = NULL;
  717. }
  718. static void OnTimer( HWND hwndDlg, UINT_PTR idTimer )
  719. {
  720. switch ( idTimer )
  721. {
  722. case TIMER_NAVAUTOSCROLL_ID: OnTimer_NavAutoScroll( hwndDlg ); break;
  723. case TIMER_NAVAUTOEXPAND_ID: OnTimer_NavAutoExpand( hwndDlg ); break;
  724. case TIMER_UNBLOCKACCELTOGGLE_ID:
  725. KillTimer( hwndDlg, idTimer );
  726. RemoveProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP );
  727. break;
  728. }
  729. }
  730. static HMLIMGLST CreateNavigationImages( HMLIMGFLTRMNGR filterManager )
  731. {
  732. MLIMAGESOURCE_I is = { 0 };
  733. static INT resourceId[] = { IDB_TREEITEM_DEFAULT, IDB_TREEITEM_COLLAPSED, IDB_TREEITEM_EXPANDED, IDB_TREEITEM_NOCHILD };
  734. static INT_PTR imageTag[] = { MLTREEIMAGE_DEFAULT, MLTREEIMAGE_BRANCH_COLLAPSED, MLTREEIMAGE_BRANCH_EXPANDED, MLTREEIMAGE_BRANCH_NOCHILD };
  735. HMLIMGLST hmlil = MLImageListI_Create( 16, 16, 24, 30, 2, 3, filterManager );
  736. if ( !hmlil )
  737. return NULL;
  738. is.bpp = 24;
  739. is.hInst = plugin.hDllInstance;
  740. is.type = SRC_TYPE_BMP_I;
  741. is.flags = ISF_FORCE_BPP_I;
  742. for ( INT index = 0; index < sizeof( resourceId ) / sizeof( resourceId[ 0 ] ); index++ )
  743. {
  744. is.lpszName = MAKEINTRESOURCEW( resourceId[ index ] );
  745. MLImageListI_Add( hmlil, &is, MLIF_FILTER1_UID, imageTag[ index ] );
  746. }
  747. return hmlil;
  748. }
  749. static void OnMouseMove( HWND hwndDlg, POINT pt, UINT flags )
  750. {
  751. RECT rc;
  752. if ( !m_query_moving ) return;
  753. MapWindowPoints( hwndDlg, HWND_DESKTOP, &pt, 1 );
  754. GetWindowRect( hwndDlg, &rc );
  755. ImageList_DragMove( pt.x - rc.left, pt.y - rc.top );
  756. HWND hWndHit = WindowFromPoint( pt );
  757. if ( hWndHit == NavCtrlI_GetHWND( hNavigation ) )
  758. {
  759. POINT ptMy = pt;
  760. UINT hitFlags;
  761. HNAVITEM hItem;
  762. MapWindowPoints( HWND_DESKTOP, hWndHit, &ptMy, 1 );
  763. hItem = NavCtrlI_HitTest( hNavigation, &ptMy, &hitFlags );
  764. if ( !hItem )
  765. {
  766. HNAVITEM hItemLast;
  767. hItemLast = NavCtrlI_GetLastVisible( hNavigation );
  768. if ( hItemLast )
  769. {
  770. RECT ri;
  771. if ( NavItemI_GetRect( hItemLast, &ri, FALSE ) && ri.bottom < ptMy.y )
  772. {
  773. HNAVITEM hMovingParent, hLastParent;
  774. hMovingParent = NavItemI_GetParent( m_query_moving_item );
  775. while ( NULL != ( hLastParent = NavItemI_GetParent( hItemLast ) ) && hLastParent != hMovingParent ) hItemLast = hLastParent;
  776. if ( hMovingParent == hLastParent )
  777. {
  778. hItem = hItemLast;
  779. hitFlags = NAVHT_ONITEM_I;
  780. }
  781. }
  782. }
  783. }
  784. if ( ( NAVHT_ONITEMINDENT_I | NAVHT_ONITEMRIGHT_I | NAVHT_ONITEM_I | NAVHT_ONITEMBUTTON_I ) & hitFlags )
  785. {
  786. HNAVITEM tempItem;
  787. Navigation_DropHelper( hwndDlg, hWndHit, hItem, hitFlags, ptMy );
  788. if ( ML_TYPE_UNKNOWN == m_query_moving_type )
  789. {
  790. SetCursor( LoadCursor( NULL, IDC_NO ) );
  791. return;
  792. }
  793. tempItem = hItem;
  794. while ( tempItem && tempItem != m_query_moving_item ) tempItem = NavItemI_GetParent( tempItem );
  795. if ( tempItem == m_query_moving_item )
  796. hItem = m_query_moving_item;
  797. if ( hItem )
  798. {
  799. BOOL hitBelow;
  800. if ( NavItemI_GetParent( hItem ) != NavItemI_GetParent( m_query_moving_item ) )
  801. {
  802. // TODO: I think regular drag-n-drop goes here?
  803. //SetCursor(LoadCursor(NULL, MAKEINTRESOURCE(IDC_NO)));
  804. CancelNavigationMove();
  805. m_query_moving_lastdest = NULL;
  806. mlDropItemStruct dropItem;
  807. ZeroMemory( &dropItem, sizeof( mlDropItemStruct ) );
  808. dropItem.p = pt;
  809. dropItem.type = m_query_moving_type;
  810. OnMediaLibraryIPC( hwndDlg, (WPARAM)&dropItem, ML_IPC_HANDLEDRAG );
  811. //handleDragDropMove(hwndDlg, m_query_moving_type, pt, 1);
  812. //goto outside_window;
  813. return;
  814. }
  815. if ( g_treedrag_lastSel )
  816. {
  817. NavItemI_SetState( g_treedrag_lastSel, 0, NIS_DROPHILITED_I );
  818. g_treedrag_lastSel = NULL;
  819. }
  820. NavItemI_GetRect( hItem, &rc, FALSE );
  821. hitBelow = ( ptMy.y > ( rc.bottom - ( rc.bottom - rc.top ) / 2 ) );
  822. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_ARROW ) ) );
  823. m_query_moving_lastdest = hItem;
  824. if ( m_query_moving_dragplace != hItem || m_query_moving_dragplaceisbelow != hitBelow )
  825. {
  826. m_query_moving_dragplace = hItem;
  827. m_query_moving_dragplaceisbelow = hitBelow;
  828. ImageList_DragShowNolock( FALSE );
  829. NavCtrlI_SetInsertMark( hNavigation, hItem, hitBelow );
  830. NavCtrlI_Update( hNavigation );
  831. ImageList_DragShowNolock( TRUE );
  832. }
  833. }
  834. }
  835. }
  836. else
  837. {
  838. int type = ML_TYPE_TREEITEM;
  839. bool canDrag;
  840. CancelNavigationMove();
  841. canDrag = ( m_query_moving_item &&
  842. ( plugin_SendMessage( ML_MSG_TREE_ONDRAG, NavItemI_GetId( m_query_moving_item ), (INT_PTR)&pt, (INT_PTR)&type ) < 0 ) );
  843. if ( !canDrag )
  844. {
  845. mlDropItemStruct dropItem;
  846. ZeroMemory( &dropItem, sizeof( mlDropItemStruct ) );
  847. dropItem.p = pt;
  848. dropItem.type = type;
  849. OnMediaLibraryIPC( hwndDlg, (WPARAM)&dropItem, ML_IPC_HANDLEDRAG );
  850. //pluginHandleIpcMessage(hwndDlg, ML_IPC_HANDLEDRAG, (WPARAM)&m);
  851. //SetCursor(dropItem.result > 0 ? hDragNDropCursor : LoadCursor(NULL, IDC_NO));
  852. //SetCursor(LoadCursor(NULL, IDC_NO));
  853. }
  854. m_query_moving_dragplace = NULL;
  855. m_query_moving_lastdest = NULL;
  856. }
  857. }
  858. static void OnLButtonUp( HWND hwndDlg, POINT pt, UINT flags )
  859. {
  860. HWND hwndHit;
  861. if ( !m_query_moving ) return;
  862. SetCursor( LoadCursor( NULL, MAKEINTRESOURCE( IDC_ARROW ) ) );
  863. ImageList_DragLeave( hwndDlg );
  864. ImageList_EndDrag();
  865. if ( m_nav_dragitem_imagelist )
  866. {
  867. ImageList_Destroy( m_nav_dragitem_imagelist );
  868. m_nav_dragitem_imagelist = NULL;
  869. }
  870. MapWindowPoints( hwndDlg, HWND_DESKTOP, &pt, 1 );
  871. hwndHit = WindowFromPoint( pt );
  872. if ( ML_TYPE_UNKNOWN != m_query_moving_type && hwndHit && m_query_moving_item )
  873. {
  874. if ( m_query_moving_dragplace )
  875. {
  876. //move item in the tree
  877. if ( ML_TYPE_TREEITEM == m_query_moving_type && m_query_moving_item != m_query_moving_lastdest )
  878. {
  879. WORD orderOld;
  880. orderOld = NavItemI_GetOrder( m_query_moving_item );
  881. if ( NavItemI_Move( m_query_moving_item, m_query_moving_lastdest, m_query_moving_dragplaceisbelow ) )
  882. {
  883. plugin_SendMessage( ML_MSG_NAVIGATION_ONMOVE, (INT_PTR)m_query_moving_item, orderOld, NavItemI_GetOrder( m_query_moving_item ) );
  884. }
  885. }
  886. else
  887. {
  888. HNAVITEM whereinsert;
  889. whereinsert = m_query_moving_lastdest;
  890. if ( !m_query_moving_dragplaceisbelow )
  891. {
  892. BOOL fTest;
  893. fTest = ( whereinsert == m_query_moving_item );
  894. whereinsert = NavItemI_GetPrevious( whereinsert );
  895. if ( !whereinsert && !fTest )
  896. whereinsert = NavItemI_GetParent( m_query_moving_lastdest );
  897. }
  898. if ( whereinsert && m_query_moving_item != whereinsert )
  899. plugin_SendMessage( ML_MSG_TREE_ONDROP, NavItemI_GetId( m_query_moving_item ), (INT_PTR)&pt, NavItemI_GetId( whereinsert ) );
  900. }
  901. }
  902. else
  903. plugin_SendMessage( ML_MSG_TREE_ONDROP, NavItemI_GetId( m_query_moving_item ), (INT_PTR)&pt, 0 );
  904. }
  905. m_query_moving = 0;
  906. if ( g_treedrag_lastSel )
  907. {
  908. NavItemI_SetState( g_treedrag_lastSel, 0, NIS_DROPHILITED_I );
  909. g_treedrag_lastSel = NULL;
  910. }
  911. if ( m_query_moving_dragplace )
  912. CancelNavigationMove();
  913. ReleaseCapture();
  914. }
  915. void listbuild( wchar_t **buf, int &buf_size, int &buf_pos, const wchar_t *tbuf )
  916. {
  917. if ( !*buf )
  918. {
  919. *buf = (wchar_t *)calloc( 4096, sizeof( wchar_t ) );
  920. if ( *buf )
  921. {
  922. buf_size = 4096;
  923. buf_pos = 0;
  924. }
  925. else
  926. {
  927. buf_size = buf_pos = 0;
  928. }
  929. }
  930. int newsize = buf_pos + lstrlenW( tbuf ) + 1;
  931. if ( newsize < buf_size )
  932. {
  933. size_t old_buf_size = buf_size;
  934. buf_size = newsize + 4096;
  935. wchar_t *data = (wchar_t *)realloc( *buf, ( buf_size + 1 ) * sizeof( wchar_t ) );
  936. if ( data )
  937. {
  938. *buf = data;
  939. }
  940. else
  941. {
  942. data = (wchar_t *)malloc( ( buf_size + 1 ) * sizeof( wchar_t ) );
  943. if ( data )
  944. {
  945. memcpy( data, *buf, sizeof( wchar_t ) * old_buf_size );
  946. free( *buf );
  947. *buf = data;
  948. }
  949. else
  950. buf_size = old_buf_size;
  951. }
  952. }
  953. StringCchCopyW( *buf + buf_pos, buf_size, tbuf );
  954. buf_pos = newsize;
  955. }
  956. /*wchar_t * getSelectedList()
  957. {
  958. wchar_t* path=NULL;
  959. int buf_pos=0, buf_size=0;
  960. int download=-1;
  961. while (GetDownload(download))
  962. {
  963. if(listContents[download]->f)
  964. listbuild(&path,buf_size,buf_pos,listContents[download]->f->path);
  965. }
  966. if(path) path[buf_pos] = 0;
  967. return path;
  968. }*/
  969. static void OnDragDrop( HWND hwndDlg, HDROP hdrop )
  970. {
  971. UINT hitFlags = NAVHT_NOWHERE_I;
  972. POINT pt = { 0 };
  973. DragQueryPoint( hdrop, &pt );
  974. HNAVITEM hItemHit = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
  975. if ( hItemHit )
  976. {
  977. if ( plugin_SendMessage( ML_MSG_TREE_ONDROPTARGET, NavItemI_GetId( hItemHit ), ML_TYPE_FILENAMESW, NULL ) > 0 )
  978. {
  979. wchar_t temp[ MAX_PATH ] = { 0 };
  980. int y = DragQueryFileW( hdrop, 0xffffffff, temp, 1024 );
  981. if ( y > 0 )
  982. {
  983. wchar_t *paths = NULL;
  984. int buf_pos = 0, buf_size = 0;
  985. for ( int x = 0; x < y; x++ )
  986. {
  987. if ( DragQueryFileW( hdrop, x, temp, MAX_PATH ) )
  988. {
  989. listbuild( &paths, buf_size, buf_pos, temp );
  990. }
  991. }
  992. if ( paths )
  993. {
  994. paths[ buf_pos ] = 0;
  995. plugin_SendMessage( ML_MSG_TREE_ONDROPTARGET, NavItemI_GetId( hItemHit ), ML_TYPE_FILENAMESW, (INT_PTR)paths );
  996. if ( IsWindow( m_curview_hwnd ) )
  997. SendMessage( m_curview_hwnd, WM_APP + 1, 0, 0 ); //update current view
  998. free( paths );
  999. }
  1000. }
  1001. DragFinish( hdrop );
  1002. }
  1003. }
  1004. }
  1005. static void MlView_ShowWindow( HWND hwnd, BOOL fShow, UINT nStatus )
  1006. {
  1007. if ( SW_PARENTOPENING == nStatus )
  1008. {
  1009. BOOL fStored = ( 0 != g_config->ReadInt( L"visible", 1 ) );
  1010. if ( fShow != fStored )
  1011. {
  1012. PostMessageW( hwnd, WMML_SHOWCONTAINER, ( 0 == fStored ) ? SW_HIDE : SW_SHOWNA, 0 );
  1013. return;
  1014. }
  1015. }
  1016. ShowWindow( hwnd, ( FALSE != fShow ) ? SW_SHOWNA : SW_HIDE );
  1017. if ( 0 == nStatus )
  1018. {
  1019. if ( NULL != g_config )
  1020. g_config->WriteInt( L"visible", ( FALSE != fShow ) );
  1021. UINT menuFlags = ( FALSE != fShow ) ? MF_CHECKED : MF_UNCHECKED;
  1022. menuFlags |= MF_BYCOMMAND;
  1023. INT szMenu[] = { 0, 4, };
  1024. for ( INT i = 0; i < ARRAYSIZE( szMenu ); i++ )
  1025. {
  1026. HMENU hMenu = (HMENU)SendMessage( plugin.hwndParent, WM_WA_IPC, szMenu[ i ], IPC_GET_HMENU );
  1027. if ( NULL != hMenu )
  1028. CheckMenuItem( hMenu, WA_MENUITEM_ID, menuFlags );
  1029. }
  1030. MLVisibleChanged( FALSE != fShow );
  1031. if ( FALSE != fShow )
  1032. {
  1033. SendMessageW( g_ownerwnd, 0x0127/*WM_CHANGEUISTATE*/, MAKEWPARAM( 1/*UIS_SET*/, 3/*(UISF_HIDEACCEL | UISF_HIDEFOCUS)*/ ), 0L );
  1034. HWND hRoot = GetAncestor( g_ownerwnd, GA_ROOT );
  1035. if ( NULL != hRoot )
  1036. SetForegroundWindow( hRoot );
  1037. }
  1038. }
  1039. }
  1040. static LRESULT MlView_OnContainerNotify( HWND hwnd, NMHDR *pnmh )
  1041. {
  1042. switch ( pnmh->code )
  1043. {
  1044. case EWN_SHOWWINDOW:
  1045. MlView_ShowWindow( hwnd, ( (EMBEDSHOW *)pnmh )->fShow, ( (EMBEDSHOW *)pnmh )->nStatus );
  1046. break;
  1047. }
  1048. return 0;
  1049. }
  1050. static LRESULT MlView_OnNotify( HWND hwnd, INT controlId, NMHDR *pnmh )
  1051. {
  1052. if ( pnmh->hwndFrom == g_ownerwnd )
  1053. {
  1054. return MlView_OnContainerNotify( hwnd, pnmh );
  1055. }
  1056. return 0;
  1057. }
  1058. static LRESULT MlView_OnContextMenu( HWND hwnd, HWND hOwner, POINTS pts )
  1059. {
  1060. HWND hNav = NavCtrlI_GetHWND( hNavigation );
  1061. if ( NULL != hNav && hOwner == hNav )
  1062. {
  1063. HNAVITEM hItem;
  1064. POINT pt;
  1065. POINTSTOPOINT( pt, pts );
  1066. if ( -1 == pt.x || -1 == pt.y )
  1067. {
  1068. hItem = NavCtrlI_GetSelection( hNavigation );
  1069. if ( NULL != hItem )
  1070. {
  1071. RECT itemRect;
  1072. if ( NavItemI_GetRect( hItem, &itemRect, FALSE ) )
  1073. {
  1074. pt.x = itemRect.left + 1;
  1075. pt.y = itemRect.top + 1;
  1076. MapWindowPoints( hNav, HWND_DESKTOP, &pt, 1 );
  1077. }
  1078. }
  1079. }
  1080. else
  1081. {
  1082. UINT hitFlags;
  1083. MapWindowPoints( HWND_DESKTOP, hNav, &pt, 1 );
  1084. hItem = NavCtrlI_HitTest( hNavigation, &pt, &hitFlags );
  1085. pt.x = pts.x;
  1086. pt.y = pts.y;
  1087. }
  1088. if ( NULL == hItem ) return 0;
  1089. UINT itemState = NavItemI_GetState( hItem, NIS_DROPHILITED_I | NIS_SELECTED_I );
  1090. if ( 0 == ( ( NIS_DROPHILITED_I | NIS_SELECTED_I ) & itemState ) )
  1091. NavItemI_SetState( hItem, NIS_DROPHILITED_I, NIS_DROPHILITED_I );
  1092. INT_PTR result = plugin_SendMessage( ML_MSG_NAVIGATION_CONTEXTMENU,
  1093. (INT_PTR)hItem,
  1094. (INT_PTR)hNav,
  1095. MAKELONG( pt.x, pt.y ) );
  1096. if ( 0 == ( ( NIS_DROPHILITED_I | NIS_SELECTED_I ) & itemState ) )
  1097. NavItemI_SetState( hItem, 0, NIS_DROPHILITED_I );
  1098. return ( 0 != result );
  1099. }
  1100. return 0;
  1101. }
  1102. static BOOL
  1103. MlView_OnHelp( HWND hwnd, HELPINFO *helpInfo )
  1104. {
  1105. // TODO review this for handling Shift+F1 as view specific help?
  1106. // make sure we're only doing it for the expect help actions
  1107. // i.e. not Ctrl+F1 which opens the global about dialog
  1108. if ( ( GetAsyncKeyState( VK_CONTROL ) & 0x8000 ) )
  1109. return FALSE;
  1110. // for view specific handling, we use Shift+F1
  1111. if ( NULL != helpInfo && HELPINFO_WINDOW == helpInfo->iContextType && ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) )
  1112. {
  1113. HWND navigationWindow;
  1114. navigationWindow = NavCtrlI_GetHWND( hNavigation );
  1115. if ( navigationWindow == helpInfo->hItemHandle )
  1116. {
  1117. HNAVITEM selectedItem;
  1118. selectedItem = NavCtrlI_GetSelection( hNavigation );
  1119. if ( NULL != selectedItem && 0 != plugin_SendMessage( ML_MSG_NAVIGATION_HELP, (INT_PTR)selectedItem, (INT_PTR)navigationWindow, MAKELONG( helpInfo->MousePos.x, helpInfo->MousePos.y ) ) )
  1120. {
  1121. return TRUE;
  1122. }
  1123. return TRUE;
  1124. }
  1125. }
  1126. // otherwise we treat it as a generic help request
  1127. return MediaLibrary_OpenHelpUrl( MEDIALIBRARY_HELP_URL );
  1128. }
  1129. INT_PTR CALLBACK dialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam )
  1130. {
  1131. switch ( uMsg )
  1132. {
  1133. case WM_MOUSEMOVE:
  1134. case WM_LBUTTONUP:
  1135. {
  1136. POINT pt = { GET_X_LPARAM( lParam ),GET_Y_LPARAM( lParam ) };
  1137. if ( WM_MOUSEMOVE == uMsg )
  1138. OnMouseMove( hwndDlg, pt, (UINT)wParam );
  1139. else if ( WM_LBUTTONUP == uMsg )
  1140. OnLButtonUp( hwndDlg, pt, (UINT)wParam );
  1141. }
  1142. return TRUE;
  1143. case WM_COMMAND:
  1144. switch ( LOWORD( wParam ) )
  1145. {
  1146. case IDC_BTN_LIB: if ( BN_CLICKED == HIWORD( wParam ) ) OnBtnLibraryClick( (HWND)lParam ); break;
  1147. case IDM_LIBRARY_CONFIG: OpenMediaLibraryPreferences(); break;
  1148. case IDM_LIBRARY_HELP: MediaLibrary_OpenHelpUrl( MEDIALIBRARY_HELP_URL ); break;
  1149. case ID_TOGGLE_LIBRARY:
  1150. if ( 0 == GetProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP ) )
  1151. {
  1152. toggleVisible( 0 );
  1153. SetProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP, (HANDLE)(INT_PTR)1 );
  1154. SetTimer( hwndDlg, TIMER_UNBLOCKACCELTOGGLE_ID, TIMER_UNBLOCKACCELTOGGLE_DELAY, NULL );
  1155. }
  1156. break;
  1157. case ID_WINDOW_CLOSE:
  1158. if ( IsVisible() )
  1159. toggleVisible( 0 );
  1160. break;
  1161. case ID_SHOW_RATINGTWEAK:
  1162. if ( !IsWindow( hwndTweak ) )
  1163. hwndTweak = MLRatingColumnI_TweakDialog( hwndDlg, ratingGlobalStyle, RatingTweak_OnApplyChanges, TRUE );
  1164. else SetWindowPos( hwndTweak, HWND_TOP, 0, 0, 0, 0, SWP_NOSIZE | SWP_NOMOVE | SWP_SHOWWINDOW );
  1165. break;
  1166. case ID_GO_TO_VIEW_SEARCHBAR:
  1167. SendMessage( m_curview_hwnd, WM_ML_CHILDIPC, 0, ML_CHILDIPC_GO_TO_SEARCHBAR );
  1168. break;
  1169. case ID_REFRESH_SEARCH:
  1170. SendMessage( m_curview_hwnd, WM_ML_CHILDIPC, 0, ML_CHILDIPC_REFRESH_SEARCH );
  1171. break;
  1172. case ID_NEW_PLAYLIST:
  1173. {
  1174. // only process if not in an edit control
  1175. // (as shift+insert is a legacy OS paste shortcut)
  1176. wchar_t szClass[ 32 ] = { 0 };
  1177. HWND hFocus = GetFocus();
  1178. if ( GetClassNameW( hFocus, szClass, sizeof( szClass ) / sizeof( szClass[ 0 ] ) ) &&
  1179. CSTR_EQUAL != CompareStringW( CSTR_INVARIANT, NORM_IGNORECASE, szClass, -1, WC_EDITW, -1 ) )
  1180. {
  1181. #define ID_MLFILE_NEWPLAYLIST 40359
  1182. SendMessageW( plugin.hwndParent, WM_COMMAND, MAKEWPARAM( ID_MLFILE_NEWPLAYLIST, 0 ), 0 );
  1183. }
  1184. else SendMessageW( hFocus, WM_PASTE, 0, 0L );
  1185. }
  1186. break;
  1187. case ID_SHOW_HELP:
  1188. // do nothing, just need to still F1 from Winamp
  1189. break;
  1190. }
  1191. break;
  1192. case WM_NOTIFY:
  1193. {
  1194. LRESULT result;
  1195. result = 0;
  1196. if ( !NavCtrlI_ProcessNotifications( hNavigation, (LPNMHDR)lParam, &result ) )
  1197. result = MlView_OnNotify( hwndDlg, (INT)wParam, (NMHDR *)lParam );
  1198. SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONGX86)(LONG_PTR)result );
  1199. return TRUE;
  1200. }
  1201. case WM_CAPTURECHANGED:
  1202. {
  1203. POINT pt = { MAXLONG,MAXLONG };
  1204. OnLButtonUp( hwndDlg, pt, 0 );
  1205. break;
  1206. }
  1207. case WM_DROPFILES: OnDragDrop( hwndDlg, (HDROP)wParam ); break;
  1208. case WM_INITMENUPOPUP: OnInitMenuPopUp( (HMENU)wParam ); return TRUE;
  1209. case WM_DISPLAYCHANGE: OnDisplayChange( hwndDlg, (UINT)wParam, LOWORD( lParam ), HIWORD( lParam ) ); return TRUE;
  1210. case WM_INITDIALOG: return OnInitDialog( hwndDlg );
  1211. case WM_DESTROY: OnDestroy( hwndDlg ); break;
  1212. case WM_WINDOWPOSCHANGED: OnWindowPosChanged( hwndDlg, (WINDOWPOS *)lParam ); return TRUE;
  1213. case WM_CLOSE: OnClose( hwndDlg ); break;
  1214. case WM_GETMINMAXINFO: OnGetMaxMinInfo( (LPMINMAXINFO)lParam ); return TRUE;
  1215. case WM_TIMER: OnTimer( hwndDlg, (UINT_PTR)wParam ); return TRUE;
  1216. case WM_ML_IPC:
  1217. return OnMediaLibraryIPC( hwndDlg, wParam, lParam );
  1218. case WM_USER + 0x200: SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, TRUE ); return TRUE;
  1219. case WM_USER + 0x201: g_rgnUpdate = (HRGN)lParam; return TRUE;// parent supports region updates. lParam is a HRGN to set HRGN coordinate mapped to parent client area (this message sent prior to WM_WINDOWPOSCHANGED.
  1220. case WM_SHOWWINDOW:
  1221. {
  1222. if ( wParam ) PostMessage( hwndDlg, WM_USER + 31, wParam, 0 );
  1223. else OnShowWindow( hwndDlg, (BOOL)wParam );
  1224. return TRUE;
  1225. }
  1226. case WM_USER + 30:
  1227. {
  1228. SetWindowRedraw( hwndDlg, FALSE );
  1229. DestroyWindow( m_curview_hwnd );
  1230. SetWindowRedraw( hwndDlg, TRUE );
  1231. CreateCurrentView( hwndDlg );
  1232. break;
  1233. }
  1234. case WM_USER + 31:
  1235. // double-pump this to work around slower plugins loading up
  1236. if ( !lParam )
  1237. PostMessage( hwndDlg, WM_USER + 31, wParam, 1 );
  1238. else
  1239. {
  1240. OnShowWindow( hwndDlg, (BOOL)wParam );
  1241. NavItemI_EnsureVisible( NavCtrlI_GetSelection( hNavigation ) );
  1242. }
  1243. break;
  1244. case WM_CONTEXTMENU: MSGRESULT( hwndDlg, MlView_OnContextMenu( hwndDlg, (HWND)wParam, MAKEPOINTS( lParam ) ) );
  1245. case WM_HELP: MSGRESULT( hwndDlg, MlView_OnHelp( hwndDlg, (HELPINFO *)lParam ) );
  1246. case WMML_SHOWCONTAINER: ShowWindow( g_ownerwnd, (INT)wParam ); return TRUE;
  1247. }
  1248. return FALSE;
  1249. }
  1250. void OnInitMenuPopUp( HMENU menu )
  1251. {
  1252. if ( main_sendtomenu || !main_sendto_hmenu || menu != main_sendto_hmenu )
  1253. return;
  1254. main_sendtomenu = new SendToMenu();
  1255. main_sendtomenu->buildmenu( menu, main_sendto_mode, 0 );
  1256. }
  1257. void OnDisplayChange( HWND hwndDlg, UINT imgDepth, UINT hRes, UINT vRes )
  1258. {
  1259. ResetColors( TRUE ); // must be first
  1260. MlStockObjects_Reset();
  1261. ratingGlobalStyle = g_config->ReadInt( L"rating_style", RATING_DEFAULT_STYLE );
  1262. MLRatingColumnI_Update();
  1263. if ( IsWindow( m_curview_hwnd ) )
  1264. {
  1265. RECT rc;
  1266. GetClientRect( m_curview_hwnd, &rc );
  1267. RedrawWindow( m_curview_hwnd, &rc, NULL, RDW_INVALIDATE | RDW_ERASE | RDW_ALLCHILDREN | RDW_ERASENOW/* | RDW_UPDATENOW*/ );
  1268. MLSkinnedWnd_SkinChanged( m_curview_hwnd, TRUE, TRUE );
  1269. SendNotifyMessageW( m_curview_hwnd, WM_DISPLAYCHANGE, imgDepth, MAKELPARAM( hRes, vRes ) );
  1270. }
  1271. NavCtrlI_UpdateLook( hNavigation );
  1272. MLSkinnedWnd_SkinChanged( GetDlgItem( hwndDlg, IDC_BTN_LIB ), TRUE, TRUE );
  1273. MLSkinnedWnd_SkinChanged( GetDlgItem( hwndDlg, IDC_VDELIM ), TRUE, TRUE );
  1274. MLSkinnedWnd_SkinChanged( GetDlgItem( hwndDlg, IDC_NO_VIEW ), TRUE, TRUE );
  1275. LayoutWindows( hwndDlg, divider_pos, TRUE );
  1276. }
  1277. #include "mldwm.h"
  1278. int OnInitDialog( HWND hwndDlg )
  1279. {
  1280. firstShow = TRUE;
  1281. MlStockObjects_Init();
  1282. if ( S_OK == MlDwm_LoadLibrary() )
  1283. {
  1284. DWMNCRENDERINGPOLICY ncrp = DWMNCRP_DISABLED;
  1285. BOOL allow = FALSE;
  1286. MlDwm_SetWindowAttribute( GetParent( hwndDlg ), DWMWA_NCRENDERING_POLICY, &ncrp, sizeof( ncrp ) );
  1287. MlDwm_SetWindowAttribute( GetParent( hwndDlg ), DWMWA_ALLOW_NCPAINT, &allow, sizeof( allow ) );
  1288. }
  1289. MLSkinWindow2( hwndDlg, hwndDlg, SKINNEDWND_TYPE_DIALOG, SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS );
  1290. HWND hctrl = GetDlgItem( hwndDlg, IDC_BTN_LIB );
  1291. MLSkinWindow2( hwndDlg, hctrl, SKINNEDWND_TYPE_BUTTON, SWS_USESKINFONT | SWS_USESKINCOLORS | SWS_USESKINCURSORS );
  1292. hctrl = GetDlgItem( hwndDlg, IDC_VDELIM );
  1293. MLSkinWindow2( hwndDlg, hctrl, SKINNEDWND_TYPE_DIVIDER, SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWDIV_VERT );
  1294. MLSkinnedDivider_SetCallback( hctrl, OnDividerMoved, NULL );
  1295. hctrl = GetDlgItem( hwndDlg, IDC_NO_VIEW );
  1296. MLSkinWindow2( hwndDlg, hctrl, SKINNEDWND_TYPE_STATIC, SWS_USESKINCOLORS | SWS_USESKINCURSORS | SWDIV_VERT );
  1297. if ( !hmlifMngr ) // Initialize Image Filter manager
  1298. {
  1299. hmlifMngr = MLImageFilterI_CreateManager( 8, 4 );
  1300. if ( hmlifMngr )
  1301. {
  1302. RegisterImageFilters( hmlifMngr );
  1303. SkinnedButton::RegisterImageFilter( hmlifMngr );
  1304. }
  1305. }
  1306. if ( !hNavigation )
  1307. {
  1308. hNavigation = NavCtrlI_Create( hwndDlg );
  1309. if ( hNavigation )
  1310. {
  1311. if ( !hmlilNavigation ) hmlilNavigation = CreateNavigationImages( hmlifMngr );
  1312. NavCtrlI_SetConfig( hNavigation, g_config );
  1313. NavCtrlI_SetImageList( hNavigation, hmlilNavigation );
  1314. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_Selected, CALLBACK_ONSELECTED_I );
  1315. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_Click, CALLBACK_ONCLICK_I );
  1316. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_KeyDown, CALLBACK_ONKEYDOWN_I );
  1317. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_BeginDrag, CALLBACK_ONBEGINDRAG_I );
  1318. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_GetImageIndex, CALLBACK_ONGETIMAGEINDEX_I );
  1319. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_BeginTitleEdit, CALLBACK_ONBEGINTITLEEDIT_I );
  1320. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_EndTitleEdit, CALLBACK_ONENDTITLEEDIT_I );
  1321. NavCtrlI_RegisterCallback( hNavigation, OnNavItem_Delete, CALLBACK_ONITEMDELETE_I );
  1322. NavCtrlI_RegisterCallback( hNavigation, OnNavItem_CustomDraw, CALLBACK_ONITEMDRAW_I );
  1323. NavCtrlI_RegisterCallback( hNavigation, OnNavItem_SetCursor, CALLBACK_ONSETCURSOR_I );
  1324. NavCtrlI_RegisterCallback( hNavigation, OnNavItem_HitTest, CALLBACK_ONHITTEST_I );
  1325. NavCtrlI_RegisterCallback( hNavigation, OnNavCtrl_Destroy, CALLBACK_ONDESTROY_I );
  1326. hctrl = NavCtrlI_GetHWND( hNavigation );
  1327. SetWindowLongPtr( hctrl, GWLP_ID, IDC_NAVIGATION );
  1328. SetWindowLongPtr( hctrl, GWL_STYLE, GetWindowLongPtr( hctrl, GWL_STYLE ) | WS_GROUP );
  1329. }
  1330. }
  1331. if ( hNavigation )
  1332. SetWindowPos( GetDlgItem( hwndDlg, IDC_BTN_LIB ), NavCtrlI_GetHWND( hNavigation ), 0, 0, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOMOVE );
  1333. divider_pos = g_config->ReadInt( L"ldivpos", 135 );
  1334. if ( !hmlilRating )
  1335. {
  1336. hmlilRating = MLImageListI_Create( 44, 12, MLILC_COLOR24_I, 1, 1, 4, hmlifMngr );
  1337. if ( hmlilRating )
  1338. {
  1339. MLIMAGESOURCE_I is = { 0 };
  1340. is.hInst = plugin.hDllInstance;
  1341. is.lpszName = MAKEINTRESOURCEW( IDB_RATING );
  1342. is.type = SRC_TYPE_PNG_I;
  1343. MLImageListI_Add( hmlilRating, &is, MLIF_FILTER1_UID, 0 );
  1344. }
  1345. }
  1346. ratingGlobalStyle = g_config->ReadInt( L"rating_style", RATING_DEFAULT_STYLE );
  1347. MLRatingColumnI_Initialize();
  1348. #ifdef CLOUD
  1349. if ( !hmlilCloud )
  1350. {
  1351. hmlilCloud = MLImageListI_Create( 16, 16, MLILC_COLOR24_I, 1, 1, 4, hmlifMngr );
  1352. if ( hmlilCloud )
  1353. {
  1354. MLIMAGESOURCE_I is = { 0 };
  1355. is.hInst = plugin.hDllInstance;
  1356. is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_IS_IN );
  1357. is.type = SRC_TYPE_PNG_I;
  1358. MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
  1359. is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_PARTIAL );
  1360. MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
  1361. is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_UNAVAIL );
  1362. MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
  1363. is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_UPLOAD );
  1364. MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
  1365. is.lpszName = MAKEINTRESOURCEW( IDB_CLOUD_UPLOADING );
  1366. MLImageListI_Add( hmlilCloud, &is, MLIF_FILTER1_UID, 0 );
  1367. }
  1368. }
  1369. MLCloudColumnI_Initialize();
  1370. #endif
  1371. OnDisplayChange( hwndDlg, 0, 0, 0 );
  1372. HACCEL hAccel = WASABI_API_LOADACCELERATORSW( IDR_ACCELERATOR_GLOBAL );
  1373. if ( hAccel )
  1374. WASABI_API_APP->app_addAccelerators( hwndDlg, &hAccel, 1, TRANSLATE_MODE_GLOBAL );
  1375. hAccel = WASABI_API_LOADACCELERATORSW( IDR_ACCELERATOR_MAIN );
  1376. if ( hAccel )
  1377. WASABI_API_APP->app_addAccelerators( hwndDlg, &hAccel, 1, TRANSLATE_MODE_CHILD );
  1378. return TRUE;
  1379. }
  1380. static void OnDestroy( HWND hwndDlg )
  1381. {
  1382. HNAVITEM hItem = NavCtrlI_GetSelection( hNavigation );
  1383. if ( hItem )
  1384. {
  1385. wchar_t name[ 1024 ] = { 0 };
  1386. if ( NavItemI_GetFullName( hItem, name, 1024 ) )
  1387. g_config->WriteString( "last_view", AutoChar( name, CP_UTF8 ) );
  1388. }
  1389. g_config->WriteInt( L"ldivpos", divider_pos );
  1390. NavCtrlI_Destroy( hNavigation );
  1391. hNavigation = NULL;
  1392. MLImageListI_Destroy( hmlilNavigation );
  1393. hmlilNavigation = NULL;
  1394. MLImageFilterI_DestroyManager( hmlifMngr );
  1395. hmlifMngr = NULL;
  1396. MLImageListI_Destroy( hmlilRating );
  1397. hmlilRating = NULL;
  1398. MLImageListI_Destroy( hmlilCloud );
  1399. hmlilCloud = NULL;
  1400. RemoveProp( hwndDlg, BLOCK_ACCELTOGGLE_PROP );
  1401. MlStockObjects_Free();
  1402. }
  1403. static void OnClose( HWND hwndDlg )
  1404. {
  1405. toggleVisible( 1 );
  1406. }
  1407. static void OnShowWindow( HWND hwndDlg, BOOL fShow )
  1408. {
  1409. if ( firstShow && fShow )
  1410. {
  1411. firstShow = FALSE;
  1412. MLVisibleChanged( TRUE );
  1413. // setting things to a more user friendly default than just the Local Media view
  1414. char *lastTitleA = g_config->ReadString( "last_view", "Local Media/Audio" );
  1415. HNAVITEM hDefItem = NULL;
  1416. if ( lastTitleA && *lastTitleA )
  1417. {
  1418. wchar_t textW[ 2048 ] = { 0 };
  1419. if ( MultiByteToWideCharSZ( CP_UTF8, 0, lastTitleA, -1, textW, 2048 ) )
  1420. hDefItem = NavCtrlI_FindItemByFullName( hNavigation, LOCALE_INVARIANT, NICF_INVARIANT_I | NICF_DISPLAY_I | NICF_IGNORECASE_I, textW, -1, TRUE );
  1421. }
  1422. if ( !hDefItem )
  1423. hDefItem = NavCtrlI_GetRoot( hNavigation );
  1424. NavItemI_Select( hDefItem );
  1425. NavCtrlI_Show( hNavigation, SW_SHOWNA );
  1426. }
  1427. }
  1428. LRESULT OnMediaLibraryIPC( HWND hwndDlg, WPARAM wParam, LPARAM lParam )
  1429. {
  1430. SetWindowLongPtr( hwndDlg, DWLP_MSGRESULT, (LONGX86)(LONG_PTR)pluginHandleIpcMessage( hwndDlg, (INT)lParam, (INT_PTR)wParam ) );
  1431. return TRUE;
  1432. }
  1433. void OnGetMaxMinInfo( MINMAXINFO *info )
  1434. {
  1435. info->ptMinTrackSize.x = 300;
  1436. info->ptMinTrackSize.y = 200;
  1437. }
  1438. void OnBtnLibraryClick( HWND hwndBtn )
  1439. {
  1440. RECT r;
  1441. GetWindowRect( hwndBtn, &r );
  1442. SendMessageW( hwndBtn, BM_SETSTATE, TRUE, 0L );
  1443. MediaLibrary_TrackPopup( GetSubMenu( g_context_menus, 0 ),
  1444. TPM_RIGHTBUTTON | TPM_LEFTBUTTON | TPM_BOTTOMALIGN | TPM_LEFTALIGN | TPM_VERNEGANIMATION,
  1445. r.left, r.top,
  1446. GetParent( hwndBtn ) );
  1447. SendMessageW( hwndBtn, BM_SETSTATE, FALSE, 0L );
  1448. UpdateWindow( hwndBtn );
  1449. Sleep( 100 );
  1450. MSG msg;
  1451. while ( PeekMessageW( &msg, NULL, WM_KEYFIRST, WM_KEYLAST, PM_REMOVE ) ); //eat return
  1452. }