Options.cpp 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611
  1. /** (c) Nullsoft, Inc. C O N F I D E N T I A L
  2. ** Filename:
  3. ** Project:
  4. ** Description:
  5. ** Author:
  6. ** Created:
  7. **/
  8. #include "Main.h"
  9. #include "resource.h"
  10. #include <malloc.h>
  11. #include "gen.h"
  12. #include "Options.h"
  13. #include <vector>
  14. #include "./api.h"
  15. //#define DO_COLORS
  16. std::vector<prefsDlgRec*> g_piprefsdlgs;
  17. HWND prefs_hwnd = NULL;
  18. intptr_t prefs_last_page;
  19. RECT prefs_rect = {-1, -1}, alt3_rect = {-1, -1}, ctrle_rect = {-1, -1},
  20. about_rect = {-1, -1}, loc_rect = {-1, -1}, time_rect = {-1, -1},
  21. load_rect = {-1, -1}, editinfo_rect = {-1, -1};
  22. static intptr_t pluginids;
  23. static HANDLE lp_v = NULL;
  24. static HANDLE _additem(HWND hwnd, HANDLE h, wchar_t *str, int children, intptr_t data)
  25. {
  26. HANDLE h2;
  27. TV_INSERTSTRUCTW is = {(HTREEITEM)h, TVI_LAST, {TVIF_PARAM | TVIF_TEXT | TVIF_CHILDREN, 0, 0, 0, str, (int)wcslen(str), 0, 0, children ? 1 : 0, data}};
  28. h2 = (HTREEITEM)SendMessageW(hwnd, TVM_INSERTITEMW, 0, (LPARAM)&is);
  29. if (prefs_last_page == data) lp_v = h2;
  30. return h2;
  31. }
  32. static HANDLE _additem(HWND hwnd, HANDLE h, char *str, int children, intptr_t data)
  33. {
  34. HANDLE h2;
  35. TV_INSERTSTRUCTA is = {(HTREEITEM)h, TVI_LAST, {TVIF_PARAM | TVIF_TEXT | TVIF_CHILDREN, 0, 0, 0, str, (int)strlen(str), 0, 0, children ? 1 : 0, data}};
  36. h2 = TreeView_InsertItem(hwnd, &is);
  37. if (prefs_last_page == data) lp_v = h2;
  38. return h2;
  39. }
  40. void do_help(HWND hwnd, UINT id, HWND hTooltipWnd)
  41. {
  42. RECT r;
  43. POINT p;
  44. GetWindowRect(GetDlgItem(hwnd, id), &r);
  45. GetCursorPos(&p);
  46. if (p.x >= r.left && p.x < r.right && p.y >= r.top && p.y < r.bottom)
  47. {}
  48. else
  49. {
  50. r.left += r.right;
  51. r.left /= 2;
  52. r.top += r.bottom;
  53. r.top /= 2;
  54. SetCursorPos(r.left, r.top);
  55. }
  56. SendMessageW(hTooltipWnd, TTM_SETDELAYTIME, TTDT_INITIAL, 0);
  57. SendMessageW(hTooltipWnd, TTM_SETDELAYTIME, TTDT_RESHOW, 0);
  58. }
  59. //////////////////////////
  60. // TAB PROCEDURES
  61. //////////////////////////
  62. int g_taskbar_dirty;
  63. // vis 2tab procedure
  64. static HANDLE insertRootDialog(HWND hwnd, intptr_t which, HANDLE h, intptr_t* pids)
  65. {
  66. for ( prefsDlgRec *p : g_piprefsdlgs )
  67. {
  68. if (which == p->where)
  69. {
  70. HANDLE h2;
  71. if (p->next == PREFS_UNICODE) // unicode
  72. h2 = _additem(hwnd, h, (wchar_t*)(p->name), 1, p->_id = (p->where < 0 ? (- 1 * p->where) : p->where));
  73. else // local code page
  74. h2 = _additem(hwnd, h, p->name, 1, p->_id = (p->where < 0 ? (-1 * p->where) : p->where));
  75. return h2;
  76. }
  77. }
  78. return INVALID_HANDLE_VALUE;
  79. }
  80. // vis 2tab procedure
  81. static bool insertDialogs(HWND hwnd, intptr_t which, HANDLE h, intptr_t *pids)
  82. {
  83. bool ret = false;
  84. for ( prefsDlgRec *p : g_piprefsdlgs )
  85. {
  86. if (which == p->where)
  87. {
  88. size_t j;
  89. for (j = 0; j != g_piprefsdlgs.size(); j++)
  90. {
  91. if (g_piprefsdlgs[j]->where == (intptr_t)p)
  92. {
  93. break;
  94. }
  95. }
  96. if ((intptr_t)p == prefs_last_page)
  97. prefs_last_page = *pids;
  98. HANDLE h2;
  99. if (p->next == PREFS_UNICODE) // unicode
  100. h2 = _additem(hwnd, h, (wchar_t *)(p->name), j != g_piprefsdlgs.size(), p->_id = (*pids)++);
  101. else // local code page
  102. h2 = _additem(hwnd, h, p->name, j!=g_piprefsdlgs.size(), p->_id = (*pids)++);
  103. ret = true;
  104. if (j != g_piprefsdlgs.size() && insertDialogs(hwnd, (intptr_t)p, h2, pids))
  105. SendMessageW(hwnd, TVM_EXPAND, TVE_EXPAND, (LPARAM)h2);
  106. }
  107. }
  108. return ret;
  109. }
  110. static HTREEITEM dofindByParam(intptr_t param, HWND treeview, HTREEITEM Tree)
  111. {
  112. HTREEITEM f=TreeView_GetChild(treeview,Tree);
  113. do
  114. {
  115. TVITEM tvi={TVIF_HANDLE|TVIF_PARAM|TVIF_CHILDREN,f,};
  116. TreeView_GetItem(treeview,&tvi);
  117. if (tvi.lParam==param) return tvi.hItem;
  118. if (tvi.cChildren)
  119. {
  120. HTREEITEM s=dofindByParam(param,treeview,tvi.hItem);
  121. if (s) return s;
  122. }
  123. } while (NULL != (f=TreeView_GetNextItem(treeview,f,TVGN_NEXT)));
  124. return NULL;
  125. }
  126. void prefs_liveDlgAdd(prefsDlgRec * p)
  127. {
  128. if(!IsWindow(prefs_hwnd)) return;
  129. HWND htree = GetDlgItem(prefs_hwnd, IDC_TREE1);
  130. HTREEITEM parent = NULL;
  131. switch(p->where)
  132. {
  133. case -1: parent = TVI_ROOT; break;
  134. case 0: parent = dofindByParam(0,htree,NULL); break;
  135. case 1: parent = dofindByParam(30,htree,NULL); break;
  136. case 2: parent = dofindByParam(40,htree,NULL); break;
  137. case 6: parent = dofindByParam(6, htree, NULL); break;
  138. default:
  139. {
  140. if (p->where < 0)
  141. {
  142. parent = TVI_ROOT;
  143. break;
  144. }
  145. else if (p->where < 65536)
  146. return;
  147. prefsDlgRec * pa = (prefsDlgRec *)p->where;
  148. parent = dofindByParam(pa->_id,htree,NULL);
  149. if(!parent) return;
  150. TVITEM t = {TVIF_CHILDREN,parent,0};
  151. TreeView_GetItem(htree,&t);
  152. if(!t.cChildren)
  153. {
  154. t.cChildren = 1;
  155. TreeView_SetItem(htree,&t);
  156. }
  157. }
  158. }
  159. if (!parent) return;
  160. if (p->next == PREFS_UNICODE) // unicode
  161. _additem(htree,parent,(wchar_t *)(p->name), 0, p->_id = pluginids++);
  162. else // local code page
  163. _additem(htree,parent,p->name, 0, p->_id = pluginids++);
  164. SendMessageW(htree, TVM_EXPAND, TVE_EXPAND, (LPARAM)parent);
  165. }
  166. void prefs_liveDlgRemove(prefsDlgRec * p)
  167. {
  168. if(!IsWindow(prefs_hwnd)) return;
  169. HWND htree = GetDlgItem(prefs_hwnd, IDC_TREE1);
  170. HTREEITEM t = dofindByParam(p->_id,htree,NULL);
  171. if(!t) return;
  172. HTREEITEM tp = TreeView_GetParent(htree, t);
  173. TreeView_DeleteItem(htree,t);
  174. if (!TreeView_GetChild(htree, tp))
  175. {
  176. // clears the [+]/[-] box if no children
  177. TVITEM t2 = {TVIF_CHILDREN,tp,0};
  178. TreeView_GetItem(htree,&t2);
  179. t2.cChildren = 0;
  180. TreeView_SetItem(htree,&t2);
  181. }
  182. }
  183. void prefs_liveDlgUpdate(prefsDlgRec * p)
  184. {
  185. if(!IsWindow(prefs_hwnd)) return;
  186. HWND htree = GetDlgItem(prefs_hwnd, IDC_TREE1);
  187. HTREEITEM t = dofindByParam(p->_id,htree,NULL);
  188. if(!t) return;
  189. if (p->next == PREFS_UNICODE)
  190. {
  191. TVITEMW tvi = {TVIF_TEXT,t,0};
  192. tvi.pszText = (wchar_t *)p->name;
  193. tvi.cchTextMax = (int)wcslen(tvi.pszText);
  194. SendMessageW(htree,TVM_SETITEMW,0,(LPARAM)&tvi);
  195. }
  196. else
  197. {
  198. TVITEMA tvi = {TVIF_TEXT,t,0};
  199. tvi.pszText = (char *)p->name;
  200. tvi.cchTextMax = (int)strlen(tvi.pszText);
  201. SendMessageW(htree,TVM_SETITEMA,0,(LPARAM)&tvi);
  202. }
  203. }
  204. HWND _dosetsel(HWND hwndDlg, HWND subwnd, int* last_page, multiPage* pages, int numpages)
  205. {
  206. HWND tabwnd=GetDlgItem(hwndDlg,IDC_TAB1);
  207. int sel=TabCtrl_GetCurSel(tabwnd);
  208. if (sel >= 0 && (sel != *last_page || !subwnd))
  209. {
  210. *last_page = sel;
  211. if (IsWindow(subwnd)) DestroyWindow(subwnd);
  212. subwnd=0;
  213. if (sel < numpages)
  214. {
  215. int t=0;
  216. WNDPROC p;
  217. t = pages[sel].id;
  218. p = pages[sel].proc;
  219. if (t) subwnd = LPCreateDialogW(t, hwndDlg, p);
  220. }
  221. if (IsWindow(subwnd))
  222. {
  223. RECT r;
  224. GetClientRect(tabwnd,&r);
  225. TabCtrl_AdjustRect(tabwnd,FALSE,&r);
  226. SetWindowPos(subwnd,HWND_TOP,r.left,r.top,r.right-r.left,r.bottom-r.top,SWP_NOACTIVATE);
  227. ShowWindow(subwnd,SW_SHOWNA);
  228. }
  229. if (IsWinXPTheme())
  230. {
  231. DoWinXPStyle(tabwnd);
  232. DoWinXPStyle(subwnd);
  233. }
  234. }
  235. return subwnd;
  236. }
  237. //////////////////////////
  238. // OUTER PROCEDURE
  239. //////////////////////////
  240. static LRESULT CALLBACK OuterProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
  241. {
  242. static HWND cur_wnd;
  243. static HWND prevActiveWindow = NULL;
  244. switch (uMsg)
  245. {
  246. #ifdef DO_COLORS
  247. case WM_CTLCOLORBTN:
  248. if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDOK))
  249. {
  250. // SetTextColor(wParam,RGB(0,199,0));
  251. return (LRESULT)GetStockObject(WHITE_BRUSH);
  252. }
  253. break;
  254. case WM_CTLCOLOREDIT:
  255. if (lParam == (LPARAM)GetDlgItem(hwndDlg, IDC_TREE1))
  256. {
  257. return (LRESULT)GetStockObject(BLACK_BRUSH);
  258. }
  259. break;
  260. case WM_CTLCOLORDLG:
  261. return (LRESULT)GetStockObject(DKGRAY_BRUSH);
  262. #endif
  263. case WM_USER + 32:
  264. if (cur_wnd) return SendMessageW(cur_wnd, uMsg, wParam, lParam);
  265. return 0;
  266. case WM_USER + 33:
  267. // use this to check a specified control on the dialog page (5.59+)
  268. CheckDlgButton(cur_wnd, wParam, (lParam ? 1: 0));
  269. return 0;
  270. case WM_INITDIALOG:
  271. {
  272. // this is a bit of a hack to help gen_nopro.dll
  273. if (!IsWindow((HWND)wParam)) prefs_last_page = 35;
  274. if (g_safeMode) SetWindowTextW(hwndDlg, getStringW(IDS_PREFS_SAFE_MODE, NULL, 0));
  275. prefs_hwnd = hwndDlg;
  276. pluginids = 60;
  277. HWND hwnd = GetDlgItem(hwndDlg, IDC_TREE1);
  278. HANDLE h;
  279. lp_v = NULL;
  280. h = _additem(hwnd, TVI_ROOT, getStringW(IDS_PREFS_SETUP, NULL, 0), 1, 0);
  281. _additem(hwnd, h, getStringW(IDS_PREFS_FT, NULL, 0), 0, 1);
  282. _additem(hwnd, h, getStringW(IDS_PREFS_SHUFFLE, NULL, 0), 0, 23);
  283. _additem(hwnd, h, getStringW(IDS_PREFS_TITLES, NULL, 0), 0, 21);
  284. _additem(hwnd, h, getStringW(IDS_PREFS_PLAYBACK, NULL, 0), 0, 42);
  285. //_additem(hwnd, h, getStringW(IDS_STATIONINFOCAPTION, NULL, 0), 0, 41);
  286. //insertDialogs(hwnd,4,h,&pluginids);
  287. //SendMessageW(hwnd,TVM_EXPAND,TVE_EXPAND,(long)h);
  288. //h=_additem(hwnd,TVI_ROOT,getStringW(IDS_PREFS_OPTIONS,NULL,0),1,20);
  289. if (g_has_video_plugin || (g_no_video_loaded == 1)) _additem(hwnd, h, getStringW(IDS_PREFS_VIDEO, NULL, 0), 0, 24);
  290. _additem(hwnd, h, getStringW(IDS_LOCALIZATION, NULL, 0), 0, 25);
  291. insertDialogs(hwnd, 0, h, &pluginids);
  292. SendMessageW(hwnd, TVM_EXPAND, TVE_EXPAND, (LPARAM)h);
  293. //media library
  294. h = insertRootDialog(hwnd, -6, TVI_ROOT, &pluginids);
  295. insertDialogs(hwnd, 6, h, &pluginids);
  296. SendMessageW(hwnd, TVM_EXPAND, TVE_EXPAND, (LPARAM)h);
  297. insertDialogs(hwnd, -1, TVI_ROOT, &pluginids); // test
  298. h = _additem(hwnd, TVI_ROOT, getStringW(IDS_PREFS_SKIN, NULL, 0), 1, 40);
  299. _additem(hwnd, h, getStringW(IDS_PREFS_CLASSICSKIN, NULL, 0), 0, 22);
  300. insertDialogs(hwnd, 2, h, &pluginids);
  301. SendMessageW(hwnd, TVM_EXPAND, TVE_EXPAND, (LPARAM)h);
  302. h = _additem(hwnd, TVI_ROOT, getStringW(IDS_PREFS_PLUG, NULL, 0), 1, 30);
  303. _additem(hwnd, h, getStringW(IDS_PREFS_PLUG_IN, NULL, 0), 0, 31);
  304. _additem(hwnd, h, getStringW(IDS_PREFS_PLUG_OUT, NULL, 0), 0, 32);
  305. if (!g_safeMode)
  306. {
  307. _additem(hwnd, h, getStringW(IDS_PREFS_PLUG_VIS, NULL, 0), 0, 33);
  308. _additem(hwnd, h, getStringW(IDS_PREFS_PLUG_DSP, NULL, 0), 0, 34);
  309. }
  310. _additem(hwnd, h, getStringW(IDS_PREFS_PLUG_GEN, NULL, 0), 0, 35);
  311. insertDialogs(hwnd, 1, h, &pluginids);
  312. insertDialogs(hwnd, -2, TVI_ROOT, &pluginids); // used to force gen_crasher to the bottom (below plug-ins)
  313. SendMessageW(hwnd, TVM_EXPAND, TVE_EXPAND, (LPARAM)h);
  314. //h=_additem(hwnd,TVI_ROOT,getStringW(IDS_PREFS_BOOK,NULL,0),1,50);
  315. //insertDialogs(hwnd,3,h,&pluginids);
  316. //SendMessageW(hwnd,TVM_EXPAND,TVE_EXPAND,(long)h);
  317. SendMessageW(hwnd, TVM_SELECTITEM, TVGN_CARET, (LPARAM)lp_v);
  318. PostMessageW(hwnd, TVM_SELECTITEM, TVGN_FIRSTVISIBLE, (LPARAM)lp_v);
  319. DirectMouseWheel_EnableConvertToMouseWheel(hwnd, TRUE);
  320. #ifdef DO_COLORS
  321. SendMessageW(hwnd, TVM_SETBKCOLOR, 0, RGB(0, 0, 0));
  322. SendMessageW(hwnd, TVM_SETTEXTCOLOR, 0, RGB(0, 220, 0));
  323. #endif
  324. }
  325. if (NULL != WASABI_API_APP)
  326. WASABI_API_APP->app_registerGlobalWindow(hwndDlg);
  327. prevActiveWindow = GetActiveWindow();
  328. if (NULL != prevActiveWindow &&
  329. hMainWindow != GetAncestor(prevActiveWindow, GA_ROOTOWNER))
  330. {
  331. prevActiveWindow = NULL;
  332. }
  333. return TRUE;
  334. case WM_COMMAND:
  335. switch (LOWORD(wParam))
  336. {
  337. case IDCANCEL:
  338. case IDOK:
  339. DestroyWindow(hwndDlg);
  340. return FALSE;
  341. }
  342. break;
  343. case WM_NOTIFY:
  344. {
  345. NM_TREEVIEW *p;
  346. p = (NM_TREEVIEW *)lParam;
  347. if (p->hdr.code == TVN_SELCHANGEDW)
  348. {
  349. HANDLE hTreeItem = TreeView_GetSelection(GetDlgItem(hwndDlg, IDC_TREE1));
  350. TV_ITEM i = {TVIF_HANDLE, (HTREEITEM)hTreeItem, 0, 0, 0, 0, 0};
  351. TreeView_GetItem(GetDlgItem(hwndDlg, IDC_TREE1), &i);
  352. if (i.lParam >= 1024)
  353. {}
  354. else if (i.lParam >= 256)
  355. {}
  356. else
  357. {
  358. int id = -1;
  359. DLGPROC proc = NULL;
  360. HINSTANCE hinst = NULL;
  361. prefs_last_page = i.lParam;
  362. LPARAM param = 0;
  363. switch (i.lParam)
  364. {
  365. case 0: id = IDD_NEWSETUP; proc = SetupProc; break; // general
  366. case 1: id = (!IsWin8() ? IDD_NEWFTYPES : IDD_WIN8_FTYPES); proc = FtypeProc; break; // filetypes
  367. // case 2: id=IDD_NEWAGENT; proc=AgentProc; break;
  368. case 21: id = IDD_NEWTITLE; proc = TitleProc; break;
  369. case 22: id = IDD_PREFS_CLASSICSKIN; proc = classicSkinProc; break;
  370. case 23: id = IDD_NEWSHUFFLEOPTS; proc = PlaybackOptionsProc; break; // playlist
  371. case 24: id = IDD_NEWVIDEOOPTS; proc = VideoProc; break;
  372. case 25: id = IDD_NEWLANG; proc = LangProc; break;
  373. case 30: id = IDD_NEWPLUG; proc = PlugProc; break;
  374. case 31: id = IDD_NEWINPUT; proc = InputProc; break;
  375. case 32: id = IDD_NEWOUTPUT; proc = OutputProc; break;
  376. case 33: id = IDD_NEWVIS; proc = VisProc; break;
  377. case 34: id = IDD_NEWDSP; proc = DspProc; break;
  378. case 35: id = IDD_NEWGEN; proc = GenProc; break;
  379. case 40: id = IDD_NEWSKIN; proc = SkinProc; break;
  380. // case 41: id = IDD_STATIONINFO; proc = StationInfoProc; break;
  381. case 42: id = IDD_PREFS_CLASSICSKIN; proc = PlaybackProc; break;
  382. // case 50: id=IDD_NEWBOOKMARKS; proc = BookProc; break;
  383. default:
  384. {
  385. size_t m;
  386. for (m = 0; m != g_piprefsdlgs.size(); m++)
  387. {
  388. if (g_piprefsdlgs[m]->_id == i.lParam)
  389. break;
  390. }
  391. if (m != g_piprefsdlgs.size())
  392. {
  393. id = g_piprefsdlgs[m]->dlgID;
  394. hinst = g_piprefsdlgs[m]->hInst;
  395. proc = (DLGPROC)g_piprefsdlgs[m]->proc;
  396. param = (LPARAM)g_piprefsdlgs[m];
  397. }
  398. }
  399. }
  400. if (IsWindow(cur_wnd))
  401. {
  402. DestroyWindow(cur_wnd);
  403. cur_wnd = 0;
  404. }
  405. if (id != -1)
  406. {
  407. RECT r;
  408. if (!hinst) cur_wnd = LPCreateDialogW(id, hwndDlg, (WNDPROC)proc);
  409. else cur_wnd = CreateDialogParamW(hinst, MAKEINTRESOURCEW(id), hwndDlg, proc, param);
  410. extern int prev_wlz_ex_state;
  411. if (!IsWindow(cur_wnd) && prev_wlz_ex_state)
  412. {
  413. // will attempt to find a in-dll version of the resource
  414. // if the version from the language pack was not loaded
  415. wchar_t filename[MAX_PATH] = {0};
  416. if (GetModuleFileNameW(hinst, filename, MAX_PATH))
  417. {
  418. PathRemoveExtensionW(filename);
  419. PathAddExtensionW(filename, L".dll");
  420. wchar_t *f = scanstr_backW(filename, L"\\/", filename);
  421. if (f && *f)
  422. {
  423. if (*f == '\\' || *f == '/') f = CharNextW(f);
  424. }
  425. if (f && *f)
  426. {
  427. HINSTANCE fallback = GetModuleHandleW(f);
  428. if (fallback != GetModuleHandle(NULL))
  429. {
  430. cur_wnd = CreateDialogParamW(fallback, MAKEINTRESOURCEW(id), hwndDlg, proc, param);
  431. }
  432. }
  433. }
  434. }
  435. // if we get here then show a non-localised fallback page
  436. if (!IsWindow(cur_wnd))
  437. {
  438. cur_wnd = CreateDialogW(hMainInstance, MAKEINTRESOURCEW(IDD_PREFS_FAIL), hwndDlg, 0);
  439. }
  440. GetWindowRect(GetDlgItem(hwndDlg, IDC_RECT), &r);
  441. ScreenToClient(hwndDlg, (LPPOINT)&r);
  442. SetWindowPos(cur_wnd, 0, r.left, r.top, 0, 0, SWP_NOACTIVATE | SWP_NOSIZE | SWP_NOZORDER);
  443. ShowWindow(cur_wnd, SW_SHOWNA);
  444. }
  445. }
  446. }
  447. }
  448. break;
  449. case WM_DESTROY:
  450. if (NULL != WASABI_API_APP)
  451. WASABI_API_APP->app_unregisterGlobalWindow(hwndDlg);
  452. {
  453. HWND treeWindow;
  454. treeWindow = GetDlgItem(hwndDlg, IDC_TREE1);
  455. if (NULL != treeWindow)
  456. DirectMouseWheel_EnableConvertToMouseWheel(treeWindow, FALSE);
  457. }
  458. GetWindowRect(hwndDlg, &prefs_rect);
  459. if (cur_wnd) DestroyWindow(cur_wnd);
  460. cur_wnd = 0;
  461. //prefs_hwnd = NULL;
  462. CheckMenuItem(main_menu, WINAMP_OPTIONS_PREFS, MF_UNCHECKED);
  463. PostMessageW(hMainWindow, WM_WA_IPC, 0, IPC_WRITECONFIG);
  464. if (NULL != prevActiveWindow)
  465. {
  466. if (IsWindowVisible(prevActiveWindow) &&
  467. IsWindowEnabled(prevActiveWindow))
  468. {
  469. SetActiveWindow(prevActiveWindow);
  470. }
  471. prevActiveWindow = NULL;
  472. }
  473. break;
  474. case WM_ACTIVATE:
  475. if (NULL != WASABI_API_APP)
  476. {
  477. if (WA_INACTIVE == LOWORD(wParam))
  478. WASABI_API_APP->ActiveDialog_Unregister(hwndDlg);
  479. else
  480. WASABI_API_APP->ActiveDialog_Register(hwndDlg);
  481. }
  482. break;
  483. }
  484. return FALSE;
  485. }
  486. HTREEITEM FindParameter(HWND treeHWND, HTREEITEM node, int findParameter)
  487. {
  488. if (!node)
  489. return 0;
  490. /* first, see if the passed node matches */
  491. TVITEM pv;
  492. pv.mask = TVIF_HANDLE | TVIF_PARAM;
  493. pv.hItem = node;
  494. if (TreeView_GetItem(treeHWND, &pv)
  495. && pv.lParam == findParameter)
  496. return node;
  497. /* now do breadth-first search */
  498. HTREEITEM found = NULL;
  499. /* search next sibling */
  500. found = FindParameter(treeHWND, TreeView_GetNextSibling(treeHWND, node), findParameter);
  501. /* search the first child
  502. * the child's sibling search should help the rest of this node's children ... */
  503. if (!found)
  504. found = FindParameter(treeHWND, TreeView_GetChild(treeHWND, node), findParameter);
  505. return found;
  506. }
  507. void prefs_dialog(int modal)
  508. {
  509. if (IsWindow(prefs_hwnd) && modal)
  510. {
  511. HTREEITEM hti;
  512. HTREEITEM lp_v = NULL;
  513. HWND hwndTV = GetDlgItem(prefs_hwnd, IDC_TREE1);
  514. //CT> update prefs_last_page to the correct value if its a plugin pref
  515. for ( prefsDlgRec *p : g_piprefsdlgs )
  516. {
  517. if ( (intptr_t)p == prefs_last_page )
  518. {
  519. prefs_last_page = p->_id;
  520. break;
  521. }
  522. }
  523. //hti=TreeView_GetFirstVisible(hwndTV);
  524. hti = TreeView_GetRoot(hwndTV);
  525. if (hti)
  526. lp_v = FindParameter(hwndTV, hti, prefs_last_page);
  527. if (lp_v) SendMessageW(hwndTV, TVM_SELECTITEM, TVGN_CARET, (LPARAM)lp_v);
  528. SetForegroundWindow(prefs_hwnd);
  529. return ;
  530. }
  531. if (IsWindow(prefs_hwnd))
  532. {
  533. SendMessageW(prefs_hwnd, WM_COMMAND, IDOK, 0);
  534. return ;
  535. }
  536. CheckMenuItem(main_menu, WINAMP_OPTIONS_PREFS, MF_CHECKED);
  537. prefs_hwnd = (HWND)LPCreateDialogW(IDD_NEWPREFS, DIALOG_PARENT(hMainWindow), OuterProc);
  538. // show prefs window and restore last position as applicable
  539. POINT pt = {prefs_rect.left, prefs_rect.top};
  540. if (!windowOffScreen(prefs_hwnd, pt))
  541. SetWindowPos(prefs_hwnd, HWND_TOP, prefs_rect.left, prefs_rect.top, 0, 0, SWP_NOSIZE | SWP_SHOWWINDOW | SWP_NOSENDCHANGING);
  542. else
  543. ShowWindow(prefs_hwnd, SW_SHOW);
  544. }