spage_skin.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646
  1. #define APSTUDIO_READONLY_SYMBOLS
  2. #include "main.h"
  3. #include "./spage_skin.h"
  4. #include "./setup_resource.h"
  5. #include "./skininfo.h"
  6. #include "../nu/ns_wc.h"
  7. #include "../nu/AutoWide.h"
  8. #include "./loadimage.h"
  9. #include "./langutil.h"
  10. #include "./setupcommon.h"
  11. typedef struct _SKINLINK
  12. {
  13. LPCWSTR pszName;
  14. LPCWSTR pszTarget;
  15. } SKINLINK;
  16. typedef struct _SKINREC
  17. {
  18. LPWSTR pszName;
  19. LPWSTR pszFileName;
  20. INT nType;
  21. BOOL bLink; // if bLink == TRUE than nType index in links
  22. } SKINREC;
  23. #define CURRENT_SKIN_ID 1
  24. #define SEPARATOR_DATA 0xEFFF
  25. #define LINK_FONT_ITALIC FALSE
  26. #define LINK_FONT_WEIGHT FW_MEDIUM
  27. //#define LINK_TEXT_COLOR RGB(0, 50, 193)
  28. //#define LINK_TEXT_HIGHLITECOLOR RGB(16, 64, 212)
  29. #define PREVIEW_WIDTH 178
  30. #define PREVIEW_HEIGHT 75
  31. static SKINLINK links[] =
  32. {
  33. { MAKEINTRESOURCEW(IDS_SKIN_PROMO1), BENTO_SKIN_NAME },
  34. { MAKEINTRESOURCEW(IDS_SKIN_PROMO2), BIG_BENTO_SKIN_NAME },
  35. { MAKEINTRESOURCEW(IDS_SKIN_CURRENT), MAKEINTRESOURCEW(CURRENT_SKIN_ID) },
  36. };
  37. static wchar_t szClassic[64] = {0, };
  38. #define CLASSIC_NAME() ((!*szClassic) ? getStringW(IDS_CLASSIC_SKIN_NAME, szClassic, sizeof(szClassic)/sizeof(wchar_t)) : szClassic)
  39. static BOOL CALLBACK AddSkinToListBox(ENUMSKIN *pes, LPVOID pUser);
  40. static LRESULT WINAPI ListBoxProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam);
  41. static LPCWSTR ResolveLink(SKINREC *pr);
  42. static INT ListBox_FindSkinFileIndex(HWND hwndLB, LPCWSTR pszSkinPath, BOOL bSearchLinks);
  43. setup_page_skin::setup_page_skin() : ref(1), hwnd(NULL), hfLink(NULL), idxSelected(-1)
  44. {
  45. *szSelectionPath = 0x00;
  46. }
  47. setup_page_skin::~setup_page_skin()
  48. {
  49. }
  50. size_t setup_page_skin::AddRef()
  51. {
  52. return ++ref;
  53. }
  54. size_t setup_page_skin::Release()
  55. {
  56. if (1 == ref)
  57. {
  58. delete(this);
  59. return 0;
  60. }
  61. return --ref;
  62. }
  63. HRESULT setup_page_skin::GetName(bool bShort, const wchar_t **pszName)
  64. {
  65. if (bShort)
  66. {
  67. static wchar_t szShortName[32] = {0};
  68. *pszName = (*szShortName) ? szShortName : getStringW(IDS_PAGE_SKIN, szShortName, sizeof(szShortName)/sizeof(wchar_t));
  69. }
  70. else
  71. {
  72. static wchar_t szLongName[64] = {0};
  73. *pszName = (*szLongName) ? szLongName : getStringW(IDS_PAGE_SKIN_LONG, szLongName, sizeof(szLongName)/sizeof(wchar_t));
  74. }
  75. return S_OK;
  76. }
  77. HRESULT setup_page_skin::Save(HWND hwndText)
  78. {
  79. if (S_FALSE == IsDirty()) return S_OK;
  80. if (!*szSelectionPath) *config_skin = 0x00;
  81. else if (S_OK != StringCchCopyW(config_skin, sizeof(config_skin)/sizeof(wchar_t), szSelectionPath)) return S_FALSE;
  82. _w_sW("skin", config_skin);
  83. if (hwnd)
  84. {
  85. HWND hwndLB = GetDlgItem(hwnd, IDC_LB_SKIN);
  86. INT index = ListBox_FindSkinFileIndex(hwndLB, szSelectionPath, TRUE);
  87. if (LB_ERR == index && *szSelectionPath) index = ListBox_FindSkinFileIndex(hwndLB, NULL, TRUE); // find default embeded skin
  88. SendMessageW(hwndLB, LB_SETCURSEL, (LB_ERR != index) ? index : 0, 0L);
  89. }
  90. return S_OK;//(count) ? S_OK : S_FALSE;
  91. }
  92. static BOOL IsForceBento()
  93. {
  94. wchar_t szVer[128] = {0};
  95. if (GetPrivateProfileIntW(L"WinampReg", L"IsFirstInst", 0, INI_FILE)) return TRUE;
  96. GetPrivateProfileStringW(L"WinampReg", L"WAVer", L"", szVer, 128, INI_FILE);
  97. return (!*szVer || CSTR_LESS_THAN == CompareStringW(MAKELCID(MAKELANGID(LANG_ENGLISH, SUBLANG_ENGLISH_US), SORT_DEFAULT),
  98. NORM_IGNORECASE, szVer, -1, AutoWide(APP_VERSION), -1));
  99. }
  100. HRESULT setup_page_skin::Revert(void)
  101. {
  102. HRESULT hr(S_OK);
  103. if (NULL != config_skin && !IsForceBento()) StringCchCopyW(szSelectionPath, sizeof(szSelectionPath)/sizeof(wchar_t), config_skin);
  104. else StringCchCopyW(szSelectionPath, sizeof(szSelectionPath)/sizeof(wchar_t), L"Bento");
  105. if (hwnd)
  106. {
  107. HWND hwndLB = GetDlgItem(hwnd, IDC_LB_SKIN);
  108. INT index = ListBox_FindSkinFileIndex(hwndLB, szSelectionPath, TRUE);
  109. if (LB_ERR == index && *szSelectionPath) index = ListBox_FindSkinFileIndex(hwndLB, NULL, TRUE); // find default embeded skin
  110. SendMessageW(hwndLB, LB_SETCURSEL, (LB_ERR != index) ? index : 0, 0L);
  111. }
  112. return hr;
  113. }
  114. HRESULT setup_page_skin::IsDirty(void)
  115. {
  116. INT cr;
  117. if (IsForceBento()) return S_OK;
  118. cr = ComparePath(config_skin, szSelectionPath, SKINDIR);
  119. if (!cr) return E_UNEXPECTED;
  120. return (CSTR_EQUAL != cr) ? S_OK : S_FALSE;
  121. }
  122. HRESULT setup_page_skin::Validate(void)
  123. {
  124. return S_OK;
  125. }
  126. HRESULT setup_page_skin::CreateView(HWND hwndParent, HWND *phwnd)
  127. {
  128. *phwnd = WACreateDialogParam(MAKEINTRESOURCEW(IDD_SETUP_PAGE_SKIN), hwndParent, ::DialogProc, (LPARAM)this);
  129. return S_OK;
  130. }
  131. void setup_page_skin::ListBox_OnSelChange(HWND hwndCtrl)
  132. {
  133. SKININFO si = {0};
  134. SKINREC *pr;
  135. WCHAR szText[MAX_PATH*2] = {0};
  136. INT typeID, index;
  137. index = (INT)SendMessageW(hwndCtrl, LB_GETCURSEL, 0, 0L);
  138. if (idxSelected == index) return;
  139. pr = (SKINREC*)SendMessageW(hwndCtrl, LB_GETITEMDATA, index, 0L);
  140. if (pr && LB_ERR != (INT)(INT_PTR)pr && pr->bLink) // resolve link
  141. {
  142. index = ListBox_FindSkinFileIndex(hwndCtrl, ResolveLink(pr), FALSE);
  143. pr = (LB_ERR != index) ? (SKINREC*)SendMessageW(hwndCtrl, LB_GETITEMDATA, index, 0L) : NULL;
  144. }
  145. if (!pr || LB_ERR == (INT)(INT_PTR)pr) { SendMessageW(hwndCtrl, LB_SETCURSEL, idxSelected, 0L); return; }
  146. idxSelected = index;
  147. if (!pr->pszFileName || !*pr->pszFileName) szSelectionPath[0] = 0x00;
  148. else StringCchCopyW(szSelectionPath, sizeof(szSelectionPath)/sizeof(wchar_t), pr->pszFileName);
  149. ZeroMemory(&si, sizeof(SKININFO));
  150. si.cbSize = sizeof(SKININFO);
  151. si.fMask = SIF_PREVIEW;
  152. StringCchCopyW(si.szName, SI_NAMEMAX, pr->pszName);
  153. GetSkinInfo(BuildFullPath(SKINDIR, szSelectionPath, szText, sizeof(szText)/sizeof(wchar_t)), &si);
  154. switch(si.type)
  155. {
  156. case SKIN_TYPE_MODERN: typeID = IDS_MODERN; break;
  157. case SKIN_TYPE_CLASSIC: typeID = IDS_CLASSIC; break;
  158. default: typeID = IDS_UNKNOWN; break;
  159. }
  160. SetDlgItemTextW(hwnd, IDC_EDT_NAME, si.szName);
  161. SetDlgItemTextW(hwnd, IDC_EDT_TYPE, getStringW(typeID, NULL, 0));
  162. SetDlgItemTextW(hwnd, IDC_EDT_AUTHOR, si.szAuthor);
  163. SetDlgItemTextW(hwnd, IDC_EDT_VERSION, si.szVersion);
  164. if (!si.hPreview) si.hPreview = WALoadImage2(L"PNG", MAKEINTRESOURCEW(IDB_PREVIEW_NO), FALSE);
  165. if (si.hPreview)
  166. {
  167. HBRUSH hb = (HBRUSH)SendMessageW(hwnd, WM_CTLCOLORSTATIC, NULL, (LPARAM)GetDlgItem(hwnd, IDC_PIC_PREVIEW));
  168. WABlendOnColor(si.hPreview, RGB(137,145,156));
  169. si.hPreview = WAResizeImage(si.hPreview, PREVIEW_WIDTH, PREVIEW_HEIGHT, hb);
  170. if (!si.hPreview) si.hPreview = WALoadImage2(L"PNG", MAKEINTRESOURCEW(IDB_PREVIEW_NO), FALSE);
  171. }
  172. HBITMAP hPrev = (HBITMAP)SendDlgItemMessageW(hwnd, IDC_PIC_PREVIEW, STM_SETIMAGE, IMAGE_BITMAP, (LPARAM)si.hPreview);
  173. if (hPrev) DeleteObject(hPrev);
  174. }
  175. void setup_page_skin::ListBox_OnItemDelete(DELETEITEMSTRUCT *pdis)
  176. {
  177. SKINREC *pr = (SKINREC*)pdis->itemData;
  178. if (pr)
  179. {
  180. if (pr->pszName) free(pr->pszName);
  181. if (pr->pszFileName) free(pr->pszFileName);
  182. free(pr);
  183. }
  184. }
  185. void setup_page_skin::ListBox_OnDrawItem(DRAWITEMSTRUCT *pdis)
  186. {
  187. RECT ri;
  188. SKINREC *pr = (SKINREC*)pdis->itemData;
  189. static UINT trackFocus = 0x0000FFFF;
  190. if (pdis->itemID == -1) return;
  191. CopyRect(&ri, &pdis->rcItem);
  192. switch(pdis->itemAction)
  193. {
  194. case ODA_FOCUS:
  195. if (0 == (0x0200/*ODS_NOFOCUSRECT*/ & pdis->itemState) && pr)
  196. {
  197. if (LOWORD(trackFocus) != pdis->itemID || HIWORD(trackFocus) != (ODS_FOCUS & pdis->itemState) ? 0x0001: 0x0000)
  198. DrawFocusRect(pdis->hDC, &ri);
  199. trackFocus = pdis->itemID | ((ODS_FOCUS & pdis->itemState) ? 0x00010000 : 0x00000000);
  200. }
  201. else trackFocus = pdis->itemID;
  202. return;
  203. case ODA_SELECT:
  204. if (0 == (ODS_SELECTED & pdis->itemState) && pr)
  205. ExtTextOutW(pdis->hDC, 0, 0, ETO_OPAQUE, &ri, L"", 0, NULL);
  206. break;
  207. }
  208. if ((ODS_SELECTED & pdis->itemState) && pr)
  209. {
  210. COLORREF rgb = SetBkColor(pdis->hDC, GetSysColor(COLOR_HIGHLIGHT));
  211. ExtTextOutW(pdis->hDC, 0, 0, ETO_OPAQUE, &ri, L"", 0, NULL);
  212. SetBkColor(pdis->hDC, rgb);
  213. }
  214. if (pr)
  215. {
  216. if (pr->pszName)
  217. {
  218. HFONT hfOld;
  219. COLORREF rgb(0);
  220. if (pr->bLink)
  221. {
  222. if (!hfLink)
  223. {
  224. LOGFONTW lf = {0};
  225. if (GetObject(GetCurrentObject(pdis->hDC, OBJ_FONT), sizeof(LOGFONTW), &lf))
  226. {
  227. lf.lfItalic = LINK_FONT_ITALIC;
  228. lf.lfWeight = LINK_FONT_WEIGHT;
  229. hfLink = CreateFontIndirectW(&lf);
  230. }
  231. }
  232. hfOld = (HFONT)SelectObject(pdis->hDC, hfLink);
  233. rgb = SetTextColor(pdis->hDC, GetSysColor((ODS_SELECTED & pdis->itemState) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
  234. }
  235. else
  236. {
  237. hfOld = NULL;
  238. rgb = SetTextColor(pdis->hDC, GetSysColor((ODS_SELECTED & pdis->itemState) ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT));
  239. }
  240. ri.left += 2;
  241. COLORREF oldrgb = SetBkColor(pdis->hDC, GetSysColor((ODS_SELECTED & pdis->itemState) ? COLOR_HIGHLIGHT : COLOR_WINDOW));
  242. DrawTextW(pdis->hDC, pr->pszName, -1, &ri, DT_VCENTER | DT_SINGLELINE | DT_NOPREFIX | DT_WORD_ELLIPSIS);
  243. SetBkColor(pdis->hDC, oldrgb);
  244. if (pr->bLink && hfOld) SelectObject(pdis->hDC, hfOld);
  245. SetTextColor(pdis->hDC, rgb);
  246. }
  247. }
  248. else
  249. {
  250. HPEN hPen, hPenOld;
  251. hPen = CreatePen(PS_DOT, 0, GetSysColor(COLOR_WINDOWTEXT));
  252. hPenOld = (HPEN)SelectObject(pdis->hDC, hPen);
  253. MoveToEx(pdis->hDC, ri.left + 1, ri.top + (ri.bottom - ri.top)/2, NULL);
  254. LineTo(pdis->hDC, ri.right - 1, ri.top + (ri.bottom - ri.top)/2);
  255. SelectObject(pdis->hDC, hPenOld);
  256. }
  257. }
  258. INT_PTR setup_page_skin::ListBox_OnItemCompare(COMPAREITEMSTRUCT *pcis)
  259. { SKINREC *pr1, *pr2;
  260. INT cr;
  261. pr1 = (SKINREC*)pcis->itemData1;
  262. pr2 = (SKINREC*)pcis->itemData2;
  263. if (pr1 == pr2) return 0;
  264. if (!pr1) return (pr2->bLink) ? 1 : -1;
  265. if (!pr2) return (pr1->bLink) ? -1 : 1;
  266. if (pr1->bLink) return (pr2->bLink) ? (pcis->itemID1 - pcis->itemID2) : -1;
  267. if (pr2->bLink) return (pr1->bLink) ? (pcis->itemID1 - pcis->itemID2) : 1;
  268. cr = CompareStringW(pcis->dwLocaleId, NORM_IGNORECASE, pr1->pszName, -1, pr2->pszName, -1);
  269. if (CSTR_EQUAL == cr)
  270. {
  271. INT t1, t2;
  272. t1 = (SKIN_FILETYPE_WAL == pr1->nType) ? SKIN_FILETYPE_ZIP : ((SKIN_FILETYPE_ZIP == pr1->nType) ? SKIN_FILETYPE_WAL : pr1->nType);
  273. t2 = (SKIN_FILETYPE_WAL == pr2->nType) ? SKIN_FILETYPE_ZIP : ((SKIN_FILETYPE_ZIP == pr2->nType) ? SKIN_FILETYPE_WAL : pr2->nType);
  274. return t1 - t2;
  275. }
  276. return cr - 2;
  277. }
  278. INT_PTR setup_page_skin::ListBox_OnVKeyToItem(HWND hwndLB, WORD vKey, INT index)
  279. {
  280. switch(vKey)
  281. {
  282. case VK_UP:
  283. case VK_LEFT:
  284. if (NULL == SendMessageW(hwndLB, LB_GETITEMDATA, index - 1, 0L)) return index - 2;
  285. break;
  286. case VK_DOWN:
  287. case VK_RIGHT:
  288. if (NULL == SendMessageW(hwndLB, LB_GETITEMDATA, index + 1, 0L)) return index + 2;
  289. break;
  290. case VK_NEXT:
  291. case VK_PRIOR:
  292. {
  293. RECT rc;
  294. INT page, count;
  295. GetClientRect(hwndLB, &rc);
  296. page = (rc.bottom - rc.top)/(INT)SendMessageW(hwndLB, LB_GETITEMHEIGHT, 0, 0L) - 1;
  297. count = (INT)SendMessageW(hwndLB, LB_GETCOUNT, 0, 0L);
  298. index = (VK_NEXT == vKey) ? min(index + page, count) : max(0, index - page);
  299. if (NULL == SendMessageW(hwndLB, LB_GETITEMDATA, index, 0L)) return index + ((VK_NEXT == vKey) ? 1 : -1);
  300. break;
  301. }
  302. }
  303. return -1;
  304. }
  305. INT_PTR setup_page_skin::ListBox_OnCharToItem(HWND hwndLB, WORD vKey, INT index)
  306. {
  307. return -2;
  308. }
  309. INT_PTR setup_page_skin::OnInitDialog(HWND hwndFocus, LPARAM lParam)
  310. {
  311. HWND hwndLB, hwndGrp;
  312. int count, linksCount(0), index;
  313. wchar_t szBuffer[MAX_PATH] = {0};
  314. idxSelected = -1;
  315. hwndGrp = GetDlgItem(hwnd, IDC_GRP_PREVIEW);
  316. SetWindowLongPtrW(hwndGrp, GWL_STYLE, GetWindowLongPtrW(hwndGrp, GWL_STYLE) | WS_CLIPSIBLINGS);
  317. hwndLB = GetDlgItem(hwnd, IDC_LB_SKIN);
  318. EnumerateSkins(AddSkinToListBox, hwndLB);
  319. count = sizeof(links)/sizeof(SKINLINK);
  320. for (int i = count - 1; i >= 0; i--)
  321. {
  322. SKINREC *pr = (SKINREC*)calloc(1, sizeof(SKINREC));
  323. if (pr)
  324. {
  325. LPCWSTR pszName = links[i].pszName;
  326. if (IS_INTRESOURCE(pszName)) pszName = getStringW((INT)(INT_PTR)pszName, szBuffer, sizeof(szBuffer)/sizeof(wchar_t));
  327. pr->pszName = _wcsdup(pszName);
  328. pr->bLink = TRUE;
  329. pr->nType = i;
  330. if(LB_ERR != ListBox_FindSkinFileIndex(hwndLB, ResolveLink(pr), FALSE) &&
  331. LB_ERR != SendMessageW(hwndLB, LB_INSERTSTRING, 0, (LPARAM)pr))
  332. {
  333. linksCount++;
  334. }
  335. else
  336. {
  337. if (pr)
  338. {
  339. if (pr->pszName) free(pr->pszName);
  340. free(pr);
  341. }
  342. }
  343. }
  344. }
  345. if (linksCount) SendMessageW(hwndLB, LB_INSERTSTRING, linksCount, (LPARAM)NULL);
  346. WNDPROC fnOldProc = (WNDPROC)(LONG_PTR)SetWindowLongPtrW(hwndLB, GWLP_WNDPROC, (LONGX86)(LONG_PTR)ListBoxProc);
  347. if (fnOldProc) SetPropW(hwndLB, L"SKINLB", fnOldProc);
  348. index = ListBox_FindSkinFileIndex(hwndLB, szSelectionPath, TRUE);
  349. if (LB_ERR == index && *szSelectionPath) index = ListBox_FindSkinFileIndex(hwndLB, NULL, TRUE); // find default embeded lang
  350. SendMessageW(hwndLB, LB_SETCURSEL, (LB_ERR != index) ? index : 0, 0L);
  351. PostMessageW(hwnd, WM_COMMAND, MAKEWPARAM(IDC_LB_SKIN, LBN_SELCHANGE), (LPARAM)hwndLB);
  352. return 0;
  353. }
  354. void setup_page_skin::OnDestroy(void)
  355. {
  356. if (hfLink) { DeleteObject(hfLink); hfLink = NULL; }
  357. }
  358. void setup_page_skin::OnCommand(INT nCtrlID, INT nEvntID, HWND hwndCtrl)
  359. {
  360. switch(nCtrlID)
  361. {
  362. case IDC_LB_SKIN:
  363. switch(nEvntID)
  364. {
  365. case LBN_SELCHANGE: ListBox_OnSelChange(hwndCtrl); break;
  366. }
  367. break;
  368. }
  369. }
  370. INT_PTR setup_page_skin::OnColorStatic(HDC hdc, HWND hwndCtrl)
  371. {
  372. INT ctrlID = GetDlgCtrlID(hwndCtrl);
  373. switch(ctrlID)
  374. {
  375. case IDC_LBL_NAME:
  376. case IDC_LBL_TYPE:
  377. case IDC_LBL_AUTHOR:
  378. case IDC_LBL_VERSION:
  379. SetTextColor(hdc, RGB(0, 70, 213));
  380. break;
  381. }
  382. return NULL;
  383. }
  384. INT_PTR setup_page_skin::OnDrawItem(INT nCtrlID, DRAWITEMSTRUCT *pdis)
  385. {
  386. switch(nCtrlID)
  387. {
  388. case IDC_LB_SKIN: ListBox_OnDrawItem(pdis); return TRUE;
  389. }
  390. return 0;
  391. }
  392. INT_PTR setup_page_skin::OnMeasureItem(INT nCtrlID, MEASUREITEMSTRUCT *pmis)
  393. {
  394. switch(nCtrlID)
  395. {
  396. case IDC_LB_SKIN:
  397. return TRUE;
  398. }
  399. return FALSE;
  400. }
  401. INT_PTR setup_page_skin::OnDeleteItem(INT nCtrlID, DELETEITEMSTRUCT *pdis)
  402. {
  403. switch(nCtrlID)
  404. {
  405. case IDC_LB_SKIN: ListBox_OnItemDelete(pdis); return TRUE;
  406. }
  407. return 0;
  408. }
  409. INT_PTR setup_page_skin::OnCompareItem(INT nCtrlID, COMPAREITEMSTRUCT *pcis)
  410. {
  411. switch(nCtrlID)
  412. {
  413. case IDC_LB_SKIN: return ListBox_OnItemCompare(pcis);
  414. }
  415. return 0;
  416. }
  417. INT_PTR setup_page_skin::OnVKeyToItem(WORD vKey, INT index, HWND hwndCtrl)
  418. {
  419. switch(GetDlgCtrlID(hwndCtrl))
  420. {
  421. case IDC_LB_SKIN: return ListBox_OnVKeyToItem(hwndCtrl, vKey, index);
  422. }
  423. return -1;
  424. }
  425. INT_PTR setup_page_skin::OnCharToItem(WORD vKey, INT index, HWND hwndCtrl)
  426. {
  427. switch(GetDlgCtrlID(hwndCtrl))
  428. {
  429. case IDC_LB_SKIN: return ListBox_OnCharToItem(hwndCtrl, vKey, index);
  430. }
  431. return -1;
  432. }
  433. INT_PTR setup_page_skin::PageDlgProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  434. {
  435. switch(uMsg)
  436. {
  437. case WM_INITDIALOG: return OnInitDialog((HWND)wParam, lParam);
  438. case WM_DESTROY: OnDestroy(); break;
  439. case WM_CTLCOLORSTATIC: return OnColorStatic((HDC)wParam, (HWND)lParam);
  440. case WM_DRAWITEM: MSGRESULT(hwnd, OnDrawItem((INT)wParam, (DRAWITEMSTRUCT*)lParam));
  441. case WM_MEASUREITEM: MSGRESULT(hwnd, OnMeasureItem((INT)wParam, (MEASUREITEMSTRUCT*)lParam));
  442. case WM_COMMAND: OnCommand(LOWORD(wParam), HIWORD(wParam), (HWND)lParam); break;
  443. case WM_DELETEITEM: MSGRESULT(hwnd, OnDeleteItem((INT)wParam, (DELETEITEMSTRUCT*)lParam));
  444. case WM_COMPAREITEM: return OnCompareItem((INT)wParam, (COMPAREITEMSTRUCT*)lParam);
  445. case WM_VKEYTOITEM: return OnVKeyToItem(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
  446. case WM_CHARTOITEM: return OnCharToItem(LOWORD(wParam), HIWORD(wParam), (HWND)lParam);
  447. }
  448. return 0;
  449. }
  450. static BOOL CALLBACK AddSkinToListBox(ENUMSKIN *pes, LPVOID pUser)
  451. {
  452. HWND hwndLB = (HWND)pUser;
  453. if (!hwndLB) return FALSE;
  454. SKINREC *pr = (SKINREC*)calloc(1, sizeof(SKINREC));
  455. if (!pr) return FALSE;
  456. pr->nType = pes->nType;
  457. if (pes->pszName) pr->pszName = _wcsdup(pes->pszName);
  458. if (pes->pszFileName) pr->pszFileName = _wcsdup(pes->pszFileName);
  459. if (LB_ERR == SendMessageW(hwndLB, LB_ADDSTRING, 0, (LPARAM)pr))
  460. {
  461. if (pr->pszName) free(pr->pszName);
  462. if (pr->pszFileName) free(pr->pszFileName);
  463. free(pr);
  464. }
  465. return TRUE;
  466. }
  467. static LPCWSTR ResolveLink(SKINREC *pr)
  468. {
  469. if (!pr) return NULL;
  470. if (!pr->bLink) return pr->pszFileName;
  471. if (pr->nType < 0 || pr->nType >= sizeof(links)/sizeof(SKINLINK)) return NULL;
  472. if(CURRENT_SKIN_ID == (INT)(INT_PTR)links[pr->nType].pszTarget) return config_skin;
  473. if (IS_INTRESOURCE(links[pr->nType].pszTarget)) return getStringW((INT)(INT_PTR)links[pr->nType].pszTarget, NULL, 0);
  474. return links[pr->nType].pszTarget;
  475. }
  476. static INT ListBox_FindSkinFileIndex(HWND hwndLB, LPCWSTR pszSkinPath, BOOL bSearchLinks)
  477. {
  478. int index, count;
  479. SKINREC *pr;
  480. LPCWSTR pszFileName;
  481. if (!hwndLB) return LB_ERR;
  482. index = LB_ERR;
  483. count = (INT)SendMessageW(hwndLB, LB_GETCOUNT, 0, 0L);
  484. for (index = 0; index < count; index++)
  485. {
  486. pr = (SKINREC*) SendMessageW(hwndLB, LB_GETITEMDATA, index, 0L);
  487. if (!pr || LB_ERR == (INT)(INT_PTR)pr) continue;
  488. if (pr->bLink)
  489. {
  490. if(bSearchLinks) pszFileName = ResolveLink(pr);
  491. else continue;
  492. }
  493. else pszFileName = pr->pszFileName;
  494. if (!pszSkinPath || !*pszSkinPath)
  495. {
  496. if (!pszFileName || !*pszFileName) break;
  497. }
  498. else
  499. {
  500. if (pszFileName && CSTR_EQUAL == ComparePath(pszSkinPath, pszFileName, SKINDIR)) break;
  501. }
  502. }
  503. return (count == index) ? LB_ERR : index;
  504. }
  505. static INT_PTR WINAPI DialogProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
  506. {
  507. setup_page_skin *pInst = (setup_page_skin*)GetPropW(hwnd, L"SETUPPAGE");
  508. switch(uMsg)
  509. {
  510. case WM_INITDIALOG:
  511. pInst = (setup_page_skin*)lParam;
  512. if (pInst)
  513. {
  514. pInst->hwnd = hwnd;
  515. SetPropW(hwnd, L"SETUPPAGE", pInst);
  516. }
  517. break;
  518. case WM_DESTROY:
  519. if (pInst)
  520. {
  521. pInst->PageDlgProc(uMsg, wParam, lParam);
  522. RemovePropW(hwnd, L"SETUPPAGE");
  523. pInst = NULL;
  524. }
  525. break;
  526. }
  527. return (pInst) ? pInst->PageDlgProc(uMsg, wParam, lParam) : 0;
  528. }
  529. static LRESULT WINAPI ListBoxProc( HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam )
  530. {
  531. WNDPROC fnOldProc = (WNDPROC) GetPropW( hwnd, L"SKINLB" );
  532. if ( !fnOldProc ) return DefWindowProcW( hwnd, uMsg, wParam, lParam );
  533. switch ( uMsg )
  534. {
  535. case WM_DESTROY:
  536. RemovePropW( hwnd, L"SKINLB" );
  537. SetWindowLongPtrW( hwnd, GWLP_WNDPROC, (LONG_PTR) fnOldProc );
  538. break;
  539. case WM_LBUTTONDOWN:
  540. case WM_RBUTTONDOWN:
  541. case WM_LBUTTONDBLCLK:
  542. if ( SendMessageW( hwnd, LB_GETITEMDATA, LOWORD( SendMessageW( hwnd, LB_ITEMFROMPOINT, 0, lParam ) ), 0L ) == NULL )
  543. return 0;
  544. break;
  545. }
  546. return CallWindowProcW( fnOldProc, hwnd, uMsg, wParam, lParam );
  547. }
  548. #ifdef CBCLASS
  549. #undef CBCLASS
  550. #endif
  551. #define CBCLASS setup_page_skin
  552. START_DISPATCH
  553. CB(ADDREF, AddRef)
  554. CB(RELEASE, Release)
  555. CB(API_SETUPPAGE_GET_NAME, GetName)
  556. CB(API_SETUPPAGE_CREATEVIEW, CreateView)
  557. CB(API_SETUPPAGE_SAVE, Save)
  558. CB(API_SETUPPAGE_REVERT, Revert)
  559. CB(API_SETUPPAGE_ISDIRTY, IsDirty)
  560. CB(API_SETUPPAGE_VALIDATE, Validate)
  561. END_DISPATCH
  562. #undef CBCLASS