Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

1632 lines
44 KiB

  1. #include "shellprv.h"
  2. #include "ids.h"
  3. #include "help.h"
  4. #include "apithk.h"
  5. #include "ascstr.h"
  6. #include "filetype.h"
  7. #include "ftdlg.h"
  8. #include "ftadv.h"
  9. #include "ftaction.h"
  10. const static DWORD cs_rgdwHelpIDsArray[] =
  11. { // Context Help IDs
  12. IDC_NO_HELP_1, NO_HELP,
  13. IDC_FT_EDIT_DOCICON, IDH_FCAB_FT_EDIT_DOCICON,
  14. IDC_FT_EDIT_DESC, IDH_FCAB_FT_EDIT_DESC,
  15. IDC_FT_EDIT_CHANGEICON, IDH_FCAB_FT_EDIT_CHANGEICON,
  16. IDC_FT_EDIT_LV_CMDSTEXT, IDH_FCAB_FT_EDIT_LV_CMDS,
  17. IDC_FT_EDIT_LV_CMDS, IDH_FCAB_FT_EDIT_LV_CMDS,
  18. IDC_FT_EDIT_NEW, IDH_FCAB_FT_EDIT_NEW,
  19. IDC_FT_EDIT_EDIT, IDH_FCAB_FT_EDIT_EDIT,
  20. IDC_FT_EDIT_REMOVE, IDH_FCAB_FT_EDIT_REMOVE,
  21. IDC_FT_EDIT_DEFAULT, IDH_FCAB_FT_EDIT_DEFAULT,
  22. IDC_FT_EDIT_CONFIRM_OPEN, IDH_CONFIRM_OPEN,
  23. IDC_FT_EDIT_SHOWEXT, IDH_FCAB_FT_EDIT_SHOWEXT,
  24. IDC_FT_EDIT_BROWSEINPLACE, IDH_SAME_WINDOW,
  25. 0, 0
  26. };
  27. struct LV_ADDDATA
  28. {
  29. BOOL fDefaultAction;
  30. TCHAR szActionReg[MAX_ACTION];
  31. };
  32. #define ADDDATA_ACTIONREG(plvItem) (((LV_ADDDATA*)((plvItem)->lParam))->szActionReg)
  33. #define ADDDATA_DEFAULTACTION(plvItem) (((LV_ADDDATA*)((plvItem)->lParam))->fDefaultAction)
  34. ///////////////////////////////////////////////////////////////////////////////
  35. ///////////////////////////////////////////////////////////////////////////////
  36. CFTAdvDlg::CFTAdvDlg(LPTSTR pszProgID, LPTSTR pszExt) :
  37. CFTDlg((ULONG_PTR)cs_rgdwHelpIDsArray),
  38. _iDefaultAction(-1), _iLVSel(-1)
  39. {
  40. _szProgID[0] = NULL;
  41. if (pszProgID)
  42. StringCchCopy(_szProgID, ARRAYSIZE(_szProgID), pszProgID);
  43. _szExt[0] = NULL;
  44. if (pszExt && (*pszExt != NULL))
  45. {
  46. StringCchPrintf(_szExt, ARRAYSIZE(_szExt), TEXT(".%s"), pszExt);
  47. }
  48. _hdpaActions = DPA_Create(4);
  49. _hdpaRemovedActions = DPA_Create(1);
  50. }
  51. static int _DeleteLocalAllocCB(void *pItem, void *pData)
  52. {
  53. LocalFree((HLOCAL)pItem);
  54. return 1;
  55. }
  56. CFTAdvDlg::~CFTAdvDlg()
  57. {
  58. if (_hIcon)
  59. DeleteObject(_hIcon);
  60. if (_hfontReg)
  61. DeleteObject(_hfontReg);
  62. if (_hfontBold)
  63. DeleteObject(_hfontBold);
  64. if (_hdpaActions)
  65. DPA_DestroyCallback(_hdpaActions, _DeleteLocalAllocCB, NULL);
  66. if (_hdpaRemovedActions)
  67. DPA_DestroyCallback(_hdpaRemovedActions, _DeleteLocalAllocCB, NULL);
  68. }
  69. ///////////////////////////////////////////////////////////////////////////////
  70. // Logic specific to our problem
  71. LRESULT CFTAdvDlg::OnInitDialog(WPARAM wParam, LPARAM lParam)
  72. {
  73. HRESULT hres = _InitAssocStore();
  74. DECLAREWAITCURSOR;
  75. SetWaitCursor();
  76. if (SUCCEEDED(hres))
  77. {
  78. _InitListView();
  79. _InitDefaultActionFont();
  80. // FTEdit_AreDefaultViewersInstalled ????
  81. if (*_szProgID)
  82. {
  83. _SetDocIcon();
  84. _InitDescription();
  85. _FillListView();
  86. _InitDefaultAction();
  87. _SelectListViewItem(0);
  88. _InitChangeIconButton();
  89. _UpdateCheckBoxes();
  90. }
  91. }
  92. else
  93. EndDialog(_hwnd, -1);
  94. ResetWaitCursor();
  95. // Return TRUE so that system set focus
  96. return TRUE;
  97. }
  98. int CFTAdvDlg::_GetIconIndex()
  99. {
  100. // check under the file progid
  101. int iImageIndex = -1;
  102. IAssocInfo* pAI = NULL;
  103. HRESULT hr = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  104. if (SUCCEEDED(hr))
  105. {
  106. hr = pAI->GetDWORD(AIDWORD_DOCLARGEICON, (DWORD*)&iImageIndex);
  107. pAI->Release();
  108. }
  109. return iImageIndex;
  110. }
  111. HRESULT CFTAdvDlg::_SetDocIcon(int iIndex)
  112. {
  113. HRESULT hres = E_FAIL;
  114. if (-1 == iIndex)
  115. {
  116. iIndex = _GetIconIndex();
  117. }
  118. if (-1 != iIndex)
  119. {
  120. HIMAGELIST hIL = NULL;
  121. Shell_GetImageLists(&hIL, NULL);
  122. if (_hIcon)
  123. {
  124. DeleteObject(_hIcon);
  125. _hIcon = NULL;
  126. }
  127. if (hIL)
  128. {
  129. _hIcon = ImageList_ExtractIcon(g_hinst, hIL, iIndex);
  130. _hIcon = (HICON)CopyImage(_hIcon, IMAGE_ICON, 32, 32, LR_COPYDELETEORG);
  131. HICON hiOld = (HICON)SendDlgItemMessage(_hwnd, IDC_FT_EDIT_DOCICON, STM_SETIMAGE, IMAGE_ICON,
  132. (LPARAM)_hIcon);
  133. if (hiOld)
  134. DestroyIcon(hiOld);
  135. }
  136. }
  137. return hres;
  138. }
  139. LRESULT CFTAdvDlg::OnListViewSelItem(int iItem, LPARAM lParam)
  140. {
  141. _UpdateActionButtons();
  142. return TRUE;
  143. }
  144. LRESULT CFTAdvDlg::OnMeasureItem(WPARAM wParam, LPARAM lParam)
  145. {
  146. TEXTMETRIC tm = {0};
  147. RECT rect;
  148. LPMEASUREITEMSTRUCT lpmis = (LPMEASUREITEMSTRUCT)lParam;
  149. HDC hdc = GetDC(NULL);
  150. HFONT hfontOld = (HFONT)SelectObject(hdc, _hfontBold);
  151. GetTextMetrics(hdc, &tm);
  152. GetClientRect(_GetLVHWND(), &rect);
  153. lpmis->itemWidth = rect.right;
  154. lpmis->itemHeight = tm.tmHeight;
  155. SelectObject(hdc, hfontOld);
  156. ReleaseDC(NULL, hdc);
  157. return TRUE;
  158. }
  159. LRESULT CFTAdvDlg::OnDrawItem(WPARAM wParam, LPARAM lParam)
  160. {
  161. LPDRAWITEMSTRUCT lpDIS = (LPDRAWITEMSTRUCT)lParam;
  162. LRESULT lRet = FALSE;
  163. if (ODT_LISTVIEW == lpDIS->CtlType)
  164. {
  165. HWND hwndLV = _GetLVHWND();
  166. LVITEM lvItem = {0};
  167. HFONT hfontOld = NULL;
  168. BOOL fSel = FALSE;
  169. BOOL fListFocus = FALSE;
  170. TCHAR szAction[MAX_ACTION];
  171. COLORREF crBkgd = 0;
  172. COLORREF crOldText = 0;
  173. lvItem.mask = LVIF_PARAM | LVIF_TEXT | LVIF_STATE;
  174. lvItem.iItem = lpDIS->itemID;
  175. lvItem.stateMask = LVIS_SELECTED|LVIS_FOCUSED;
  176. lvItem.pszText = szAction;
  177. lvItem.cchTextMax = ARRAYSIZE(szAction);
  178. ListView_GetItem(hwndLV, &lvItem);
  179. fSel = (lvItem.state & LVIS_SELECTED);
  180. fListFocus = (GetFocus() == hwndLV);
  181. crBkgd = (fSel ? (fListFocus ? COLOR_HIGHLIGHT : COLOR_3DFACE) : COLOR_WINDOW);
  182. SetBkColor(lpDIS->hDC, GetSysColor(crBkgd));
  183. FillRect(lpDIS->hDC, &lpDIS->rcItem, (HBRUSH)IntToPtr(crBkgd + 1));
  184. crOldText = SetTextColor(lpDIS->hDC,
  185. GetSysColor(fSel ? (fListFocus ? COLOR_HIGHLIGHTTEXT : COLOR_WINDOWTEXT) :
  186. COLOR_WINDOWTEXT));
  187. // Use Bold font for default action
  188. hfontOld = (HFONT)SelectObject(lpDIS->hDC,
  189. _IsDefaultAction(ADDDATA_ACTIONREG(&lvItem)) ? _hfontBold : _hfontReg);
  190. int iOldBkMode = SetBkMode(lpDIS->hDC, OPAQUE);
  191. DrawText(lpDIS->hDC, szAction, lstrlen(szAction), &lpDIS->rcItem, 0);
  192. SetBkMode(lpDIS->hDC, iOldBkMode);
  193. SetTextColor(lpDIS->hDC, crOldText);
  194. SelectObject(lpDIS->hDC, hfontOld);
  195. if(fListFocus && (lvItem.state & LVIS_FOCUSED))
  196. DrawFocusRect(lpDIS->hDC, &lpDIS->rcItem);
  197. lRet = TRUE;
  198. }
  199. return lRet;
  200. }
  201. HRESULT CFTAdvDlg::_InitDefaultActionFont()
  202. {
  203. HFONT hfontDlg = GetWindowFont(_hwnd);
  204. LOGFONT lf = {0};
  205. LOGFONT lfDlg = {0};
  206. GetObject(hfontDlg, sizeof(LOGFONT), &lfDlg);
  207. SystemParametersInfo(SPI_GETICONTITLELOGFONT, sizeof(lf), &lf, FALSE);
  208. // Normal font
  209. lf.lfWeight = FW_NORMAL;
  210. lf.lfHeight = lfDlg.lfHeight;
  211. _hfontReg = CreateFontIndirect(&lf);
  212. // Bold font
  213. lf.lfWeight = FW_BOLD;
  214. _hfontBold = CreateFontIndirect(&lf);
  215. return (_hfontReg && _hfontBold) ? S_OK : E_FAIL;
  216. }
  217. HRESULT CFTAdvDlg::_SelectListViewItem(int i)
  218. {
  219. LVITEM lvItem = {0};
  220. lvItem.iItem = i;
  221. lvItem.mask = LVIF_STATE;
  222. lvItem.stateMask = LVIS_SELECTED | LVIS_FOCUSED;
  223. lvItem.state = LVIS_SELECTED | LVIS_FOCUSED;
  224. ListView_SetItem(_GetLVHWND(), &lvItem);
  225. return S_OK;
  226. }
  227. // pszText and cchTextMax needs to be set
  228. BOOL CFTAdvDlg::_FindActionLVITEM(LPTSTR pszActionReg, LVITEM* plvItem)
  229. {
  230. HWND hwndLV = _GetLVHWND();
  231. int iCount = ListView_GetItemCount(hwndLV);
  232. BOOL fRet = FALSE;
  233. plvItem->mask = LVIF_TEXT | LVIF_PARAM;
  234. for (int i = 0; i < iCount; ++i)
  235. {
  236. plvItem->iItem = i;
  237. if (ListView_GetItem(hwndLV, plvItem))
  238. {
  239. if (!lstrcmpi(pszActionReg, ADDDATA_ACTIONREG(plvItem)))
  240. {
  241. fRet = TRUE;
  242. break;
  243. }
  244. }
  245. }
  246. return fRet;
  247. }
  248. HRESULT CFTAdvDlg::_InitDefaultAction()
  249. {
  250. // Get it from the classstore
  251. IAssocInfo* pAI = NULL;
  252. HRESULT hres = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  253. if (SUCCEEDED(hres))
  254. {
  255. TCHAR szActionReg[MAX_ACTION];
  256. DWORD cchActionReg = ARRAYSIZE(szActionReg);
  257. HWND hwndLV = _GetLVHWND();
  258. int iIndex = -1;
  259. hres = pAI->GetString(AISTR_PROGIDDEFAULTACTION, szActionReg, &cchActionReg);
  260. if (SUCCEEDED(hres))
  261. {
  262. TCHAR szActionLVI[MAX_ACTION];
  263. LVITEM lvItem = {0};
  264. lvItem.pszText = szActionLVI;
  265. lvItem.cchTextMax = ARRAYSIZE(szActionLVI);
  266. if (_FindActionLVITEM(szActionReg, &lvItem))
  267. hres = _SetDefaultAction(lvItem.iItem);
  268. else
  269. hres = S_OK;
  270. }
  271. pAI->Release();
  272. }
  273. return hres;
  274. }
  275. BOOL CFTAdvDlg::_GetDefaultAction(LPTSTR pszActionReg, DWORD cchActionReg)
  276. {
  277. BOOL fRet = FALSE;
  278. HWND hwndLV = _GetLVHWND();
  279. LVITEM lvItem = {0};
  280. int iCount = ListView_GetItemCount(hwndLV);
  281. TCHAR szActionRegLocal[MAX_ACTION];
  282. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  283. lvItem.pszText = szActionRegLocal;
  284. lvItem.cchTextMax = ARRAYSIZE(szActionRegLocal);
  285. for (int i = 0; i < iCount; ++i)
  286. {
  287. lvItem.iItem = i;
  288. if (ListView_GetItem(hwndLV, &lvItem))
  289. {
  290. if (ADDDATA_DEFAULTACTION(&lvItem))
  291. {
  292. if(SUCCEEDED(StringCchCopy(pszActionReg, cchActionReg, ADDDATA_ACTIONREG(&lvItem))))
  293. fRet = TRUE;
  294. else
  295. fRet = FALSE;
  296. break;
  297. }
  298. }
  299. }
  300. return fRet;
  301. }
  302. BOOL CFTAdvDlg::_IsDefaultAction(LPTSTR pszActionReg)
  303. {
  304. BOOL fRet = FALSE;
  305. TCHAR szActionReg[MAX_ACTION];
  306. if (_GetDefaultAction(szActionReg, ARRAYSIZE(szActionReg)))
  307. {
  308. if (!lstrcmpi(szActionReg, pszActionReg))
  309. fRet = TRUE;
  310. }
  311. return fRet;
  312. }
  313. void CFTAdvDlg::_CheckDefaultAction()
  314. {
  315. HWND hwndLV = _GetLVHWND();
  316. // Is there only one elem?
  317. if (1 == ListView_GetItemCount(hwndLV))
  318. {
  319. _SetDefaultActionHelper(0, TRUE);
  320. }
  321. }
  322. HRESULT CFTAdvDlg::_SetDefaultAction(int iIndex)
  323. {
  324. HWND hwndLV = _GetLVHWND();
  325. // Remove previous default if any
  326. if (-1 != _iDefaultAction)
  327. {
  328. _SetDefaultActionHelper(_iDefaultAction, FALSE);
  329. ListView_RedrawItems(hwndLV, _iDefaultAction, _iDefaultAction);
  330. }
  331. // Set new
  332. _iDefaultAction = iIndex;
  333. // iIndex == -1 means no default
  334. if (iIndex >= 0)
  335. {
  336. _SetDefaultActionHelper(_iDefaultAction, TRUE);
  337. ListView_RedrawItems(hwndLV, _iDefaultAction, _iDefaultAction);
  338. }
  339. return S_OK;
  340. }
  341. void CFTAdvDlg::_SetDefaultActionHelper(int iIndex, BOOL fDefault)
  342. {
  343. HWND hwndLV = _GetLVHWND();
  344. LVITEM lvItem = {0};
  345. lvItem.mask = LVIF_PARAM;
  346. lvItem.iItem = iIndex;
  347. _iDefaultAction = -1;
  348. if (ListView_GetItem(hwndLV, &lvItem))
  349. {
  350. ADDDATA_DEFAULTACTION(&lvItem) = fDefault;
  351. _iDefaultAction = iIndex;
  352. }
  353. }
  354. HRESULT CFTAdvDlg::_InitListView()
  355. {
  356. LVCOLUMN lvColumn = {0};
  357. HWND hwndLV = _GetLVHWND();
  358. RECT rc = {0};
  359. {
  360. // What's this?
  361. // We need to handle the WM_MEASUREITEM message from the listview. This msg
  362. // is sent before we receive the WM_INITDIALOG and thus before we connect the
  363. // this C++ obj to the HWND. By changing the style here we receive the msg
  364. // after the C++ obj and the HWND are connected.
  365. LONG lStyle = GetWindowLong(hwndLV, GWL_STYLE);
  366. lStyle &= ~LVS_LIST;
  367. SetWindowLong(hwndLV, GWL_STYLE, lStyle | LVS_REPORT);
  368. }
  369. //
  370. // Set the columns
  371. //
  372. GetClientRect(hwndLV, &rc);
  373. lvColumn.mask = LVCF_SUBITEM|LVCF_WIDTH;
  374. lvColumn.cx = rc.right - GetSystemMetrics(SM_CXBORDER);
  375. lvColumn.iSubItem = 0;
  376. ListView_InsertColumn(hwndLV, 0, &lvColumn);
  377. return S_OK;
  378. }
  379. HRESULT CFTAdvDlg::_UpdateActionButtons()
  380. {
  381. HRESULT hres = E_FAIL;
  382. TCHAR szAction[MAX_ACTION];
  383. BOOL bRet = FALSE;
  384. LVITEM lvItem = {0};
  385. lvItem.pszText = szAction;
  386. lvItem.cchTextMax = ARRAYSIZE(szAction);
  387. bRet = _GetListViewSelectedItem(LVIF_TEXT | LVIF_PARAM, 0, &lvItem);
  388. // If we don't have a selected item Or we don't have any text for that item.
  389. if (!bRet || !(*(lvItem.pszText)))
  390. {
  391. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_EDIT), FALSE);
  392. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_REMOVE), FALSE);
  393. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_DEFAULT), TRUE);
  394. hres = S_OK;
  395. }
  396. else
  397. {
  398. if (_IsNewPROGIDACTION(lvItem.pszText))
  399. {
  400. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_EDIT), TRUE);
  401. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_REMOVE), TRUE);
  402. hres = S_OK;
  403. }
  404. else
  405. {
  406. IAssocInfo* pAI = NULL;
  407. hres = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  408. if (SUCCEEDED(hres))
  409. {
  410. DWORD dwAttributes;
  411. HWND hwndLV = _GetLVHWND();
  412. // REARCHITECT: This code should be in ftassoc.cpp, and we should have
  413. // more AIBOOL_ flags for this
  414. hres = pAI->GetDWORD(AIDWORD_PROGIDEDITFLAGS, &dwAttributes);
  415. if (FAILED(hres))
  416. {
  417. // It failed, probably there is no EditFlags value for this progID, let's
  418. // set some default value for dwAttributes
  419. dwAttributes = 0;
  420. }
  421. // REARCHITECT (end)
  422. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_EDIT),
  423. !((dwAttributes & FTA_NoEditVerb) &&
  424. !(dwAttributes & FTAV_UserDefVerb)));
  425. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_REMOVE),
  426. !((dwAttributes & FTA_NoRemoveVerb) &&
  427. !(dwAttributes & FTAV_UserDefVerb)));
  428. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_DEFAULT),
  429. !(dwAttributes & FTA_NoEditDflt));
  430. // Enable the default button only if the action is not already
  431. // the default action
  432. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_DEFAULT),
  433. !_IsDefaultAction(ADDDATA_ACTIONREG(&lvItem)));
  434. pAI->Release();
  435. }
  436. }
  437. }
  438. return hres;
  439. }
  440. HRESULT CFTAdvDlg::_UpdateCheckBoxes()
  441. {
  442. BOOL fBool;
  443. IAssocInfo* pAI = NULL;
  444. HRESULT hres = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  445. if (SUCCEEDED(hres))
  446. {
  447. hres = pAI->GetBOOL(AIBOOL_CONFIRMOPEN, &fBool);
  448. if (SUCCEEDED(hres))
  449. CheckDlgButton(_hwnd, IDC_FT_EDIT_CONFIRM_OPEN, !fBool);
  450. hres = pAI->GetBOOL(AIBOOL_ALWAYSSHOWEXT, &fBool);
  451. if (SUCCEEDED(hres))
  452. CheckDlgButton(_hwnd, IDC_FT_EDIT_SHOWEXT, fBool);
  453. hres = pAI->GetBOOL(AIBOOL_BROWSEINPLACEENABLED, &fBool);
  454. if (SUCCEEDED(hres))
  455. {
  456. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_BROWSEINPLACE), fBool);
  457. if (fBool)
  458. {
  459. hres = pAI->GetBOOL(AIBOOL_BROWSEINPLACE, &fBool);
  460. if (SUCCEEDED(hres))
  461. CheckDlgButton(_hwnd, IDC_FT_EDIT_BROWSEINPLACE, fBool);
  462. }
  463. else
  464. CheckDlgButton(_hwnd, IDC_FT_EDIT_BROWSEINPLACE, FALSE);
  465. }
  466. pAI->Release();
  467. }
  468. return hres;
  469. }
  470. HRESULT CFTAdvDlg::_InitChangeIconButton()
  471. {
  472. HRESULT hres = E_FAIL;
  473. BOOL fChangeIcon = TRUE;
  474. IAssocInfo* pAI = NULL;
  475. hres = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  476. if (SUCCEEDED(hres))
  477. {
  478. hres = pAI->GetBOOL(AIBOOL_EDITDOCICON, &fChangeIcon);
  479. if (SUCCEEDED(hres))
  480. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_CHANGEICON), fChangeIcon);
  481. pAI->Release();
  482. }
  483. return hres;
  484. }
  485. HRESULT CFTAdvDlg::_InitDescription()
  486. {
  487. HRESULT hres = E_FAIL;
  488. BOOL fEditDescr = TRUE;
  489. IAssocInfo* pAI = NULL;
  490. hres = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  491. if (SUCCEEDED(hres))
  492. {
  493. TCHAR szProgIDDescr[MAX_PROGIDDESCR];
  494. DWORD cchProgIDDescr = ARRAYSIZE(szProgIDDescr);
  495. hres = pAI->GetString(AISTR_PROGIDDESCR, szProgIDDescr, &cchProgIDDescr);
  496. if (SUCCEEDED(hres))
  497. SetDlgItemText(_hwnd, IDC_FT_EDIT_DESC, szProgIDDescr);
  498. hres = pAI->GetBOOL(AIBOOL_EDITDESCR, &fEditDescr);
  499. EnableWindow(GetDlgItem(_hwnd, IDC_FT_EDIT_DESC), fEditDescr);
  500. pAI->Release();
  501. Edit_LimitText(GetDlgItem(_hwnd, IDC_FT_EDIT_DESC), MAX_PROGIDDESCR - 1);
  502. }
  503. return hres;
  504. }
  505. HRESULT CFTAdvDlg::_FillListView()
  506. {
  507. HRESULT hres = E_FAIL;
  508. IEnumAssocInfo* pEnum = NULL;
  509. hres = _pAssocStore->EnumAssocInfo(ASENUM_ACTION, _szProgID, AIINIT_PROGID, &pEnum);
  510. if (SUCCEEDED(hres))
  511. {
  512. int iItem = 0;
  513. IAssocInfo* pAI = NULL;
  514. while (S_OK == pEnum->Next(&pAI))
  515. {
  516. TCHAR szActionReg[MAX_ACTION];
  517. DWORD cchActionReg = ARRAYSIZE(szActionReg);
  518. hres = pAI->GetString(AISTR_ACTION, szActionReg, &cchActionReg);
  519. if (SUCCEEDED(hres))
  520. {
  521. TCHAR szActionFN[MAX_ACTION];
  522. DWORD cchActionFN = ARRAYSIZE(szActionFN);
  523. hres = pAI->GetString(AISTR_ACTIONFRIENDLY, szActionFN, &cchActionFN);
  524. if (SUCCEEDED(hres))
  525. {
  526. if (S_FALSE == hres)
  527. {
  528. hres = StringCchCopy(szActionFN, ARRAYSIZE(szActionFN), szActionReg);
  529. }
  530. if (SUCCEEDED(hres) && -1 != _InsertListViewItem(iItem, szActionReg, szActionFN))
  531. {
  532. ++iItem;
  533. }
  534. }
  535. }
  536. pAI->Release();
  537. }
  538. pEnum->Release();
  539. }
  540. return hres;
  541. }
  542. LRESULT CFTAdvDlg::OnChangeIcon(WORD wNotif)
  543. {
  544. IAssocInfo* pAI;
  545. HRESULT hr = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  546. if (SUCCEEDED(hr))
  547. {
  548. DWORD cchIconLoc = ARRAYSIZE(_szOldIconLoc);
  549. hr = pAI->GetString(AISTR_ICONLOCATION, _szOldIconLoc, &cchIconLoc);
  550. pAI->Release();
  551. _iOldIcon = PathParseIconLocation(_szOldIconLoc);
  552. }
  553. if (FAILED(hr))
  554. {
  555. hr = StringCchCopy(_szOldIconLoc, ARRAYSIZE(_szOldIconLoc), TEXT("shell32.dll"));
  556. if(SUCCEEDED(hr))
  557. {
  558. _iOldIcon = -(IDI_SYSFILE);
  559. }
  560. }
  561. if (SUCCEEDED(hr))
  562. {
  563. // setup the in params
  564. int iIcon = _iOldIcon;
  565. hr = StringCchCopy(_szIconLoc, ARRAYSIZE(_szIconLoc), _szOldIconLoc);
  566. if (SUCCEEDED(hr) && PickIconDlg(_hwnd, _szIconLoc, ARRAYSIZE(_szIconLoc), &iIcon))
  567. {
  568. _SetDocIcon(Shell_GetCachedImageIndex(_szIconLoc, iIcon, 0));
  569. // Format the _szIconLoc
  570. int iLen = lstrlen(_szIconLoc);
  571. hr = StringCchPrintf(_szIconLoc + iLen, ARRAYSIZE(_szIconLoc) - iLen, TEXT(",%d"), iIcon);
  572. }
  573. else
  574. {
  575. _szIconLoc[0] = 0;
  576. }
  577. }
  578. return FALSE;
  579. }
  580. // Return value:
  581. // TRUE: Check succeeded, everything is OK
  582. // FALSE: Check failed
  583. BOOL CFTAdvDlg::_CheckForDuplicateNewAction(LPTSTR pszActionReg, LPTSTR pszActionFN)
  584. {
  585. // we just go through the listview content
  586. HWND hwndLV = _GetLVHWND();
  587. int cItem = ListView_GetItemCount(hwndLV);
  588. BOOL fRet = TRUE;
  589. for (int i = 0; (i < cItem) && fRet; ++i)
  590. {
  591. TCHAR szActionFN[MAX_ACTION];
  592. LVITEM lvItem = {0};
  593. lvItem.mask = LVIF_PARAM | LVIF_TEXT;
  594. lvItem.iItem = i;
  595. lvItem.pszText = szActionFN;
  596. lvItem.cchTextMax = ARRAYSIZE(szActionFN);
  597. ListView_GetItem(hwndLV, &lvItem);
  598. if (!lstrcmpi(lvItem.pszText, pszActionFN))
  599. {
  600. fRet = FALSE;
  601. }
  602. else
  603. {
  604. if (!lstrcmpi(ADDDATA_ACTIONREG(&lvItem), pszActionReg))
  605. {
  606. fRet = FALSE;
  607. }
  608. }
  609. }
  610. return fRet;
  611. }
  612. // Return value:
  613. // TRUE: Check succeeded, everything is OK
  614. // FALSE: Check failed
  615. BOOL CFTAdvDlg::_CheckForDuplicateEditAction(LPTSTR pszActionRegOriginal, LPTSTR pszActionReg,
  616. LPTSTR pszActionFNOriginal, LPTSTR pszActionFN)
  617. {
  618. // we just go through the listview content
  619. HWND hwndLV = _GetLVHWND();
  620. int cItem = ListView_GetItemCount(hwndLV);
  621. BOOL fRet = TRUE;
  622. for (int i = 0; (i < cItem) && fRet; ++i)
  623. {
  624. TCHAR szActionFN[MAX_ACTION];
  625. LVITEM lvItem = {0};
  626. lvItem.mask = LVIF_PARAM | LVIF_TEXT;
  627. lvItem.iItem = i;
  628. lvItem.pszText = szActionFN;
  629. lvItem.cchTextMax = ARRAYSIZE(szActionFN);
  630. ListView_GetItem(hwndLV, &lvItem);
  631. if (!lstrcmpi(lvItem.pszText, pszActionFN))
  632. {
  633. // they are the same, this can happen if this is the Action we were editing
  634. // and we did not change the action name
  635. // Is this the original one we were editing?
  636. if (lstrcmpi(szActionFN, pszActionFNOriginal))
  637. {
  638. // No, it's not the original, we have a dup
  639. fRet = FALSE;
  640. }
  641. }
  642. else
  643. {
  644. if (!lstrcmpi(ADDDATA_ACTIONREG(&lvItem), pszActionReg))
  645. {
  646. // they are the same, this can happen if this is the Action we were editing
  647. // and we did not change the action name
  648. // Is this the original one we were editing?
  649. if (lstrcmpi(ADDDATA_ACTIONREG(&lvItem), pszActionRegOriginal))
  650. {
  651. // No, it's not the original, we have a dup
  652. fRet = FALSE;
  653. }
  654. }
  655. }
  656. }
  657. return fRet;
  658. }
  659. LRESULT CFTAdvDlg::OnNewButton(WORD wNotif)
  660. {
  661. TCHAR szProgIDDescr[MAX_PROGIDDESCR];
  662. PROGIDACTION pida = {0};
  663. CFTActionDlg* pActionDlg = NULL;
  664. pida.fNew = TRUE;
  665. GetDlgItemText(_hwnd, IDC_FT_EDIT_DESC, szProgIDDescr, ARRAYSIZE(szProgIDDescr));
  666. // FALSE: New (not-Edit)
  667. pActionDlg = new CFTActionDlg(&pida, szProgIDDescr, FALSE);
  668. if (pActionDlg)
  669. {
  670. BOOL fShowAgain;
  671. do
  672. {
  673. fShowAgain = FALSE;
  674. if (IDOK == pActionDlg->DoModal(g_hinst, MAKEINTRESOURCE(DLG_FILETYPEOPTIONSCMD), _hwnd))
  675. {
  676. // Do we have duplicate actions?
  677. if (_CheckForDuplicateNewAction(pida.szActionReg, pida.szAction))
  678. {
  679. // No
  680. HRESULT hres = _AppendPROGIDACTION(&pida);
  681. if (SUCCEEDED(hres))
  682. {
  683. int iItem = _InsertListViewItem(0, pida.szActionReg, pida.szAction);
  684. hres = S_OK;
  685. if (-1 != iItem)
  686. _SelectListViewItem(iItem);
  687. }
  688. }
  689. else
  690. {
  691. // Yes
  692. fShowAgain = TRUE;
  693. pActionDlg->SetShowAgain();
  694. }
  695. }
  696. if (fShowAgain)
  697. {
  698. ShellMessageBox(g_hinst, _hwnd, MAKEINTRESOURCE(IDS_FT_MB_EXISTINGACTION),
  699. MAKEINTRESOURCE(IDS_FT), MB_OK | MB_ICONSTOP, pida.szAction);
  700. }
  701. } while (fShowAgain);
  702. pActionDlg->Release();
  703. }
  704. _CheckDefaultAction();
  705. return FALSE;
  706. }
  707. LRESULT CFTAdvDlg::OnEditButton(WORD wNotif)
  708. {
  709. TCHAR szAction[MAX_ACTION];
  710. HRESULT hres = E_FAIL;
  711. LONG lRes = 0;
  712. LVITEM lvItem = {0};
  713. // lvItem.iSubItem = 0;
  714. lvItem.pszText = szAction;
  715. lvItem.cchTextMax = ARRAYSIZE(szAction);
  716. if (_GetListViewSelectedItem(LVIF_TEXT, 0, &lvItem))
  717. {
  718. TCHAR szProgIDDescr[MAX_PROGIDDESCR];
  719. PROGIDACTION* pPIDA = NULL;
  720. PROGIDACTION pida = {0};
  721. GetDlgItemText(_hwnd, IDC_FT_EDIT_DESC, szProgIDDescr, ARRAYSIZE(szProgIDDescr));
  722. BOOL fNewOrEdit = SUCCEEDED(_GetPROGIDACTION(lvItem.pszText, &pPIDA));
  723. if (!fNewOrEdit)
  724. {
  725. hres = _FillPROGIDACTION(&pida, ADDDATA_ACTIONREG(&lvItem), szAction);
  726. pPIDA = &pida;
  727. }
  728. else
  729. {
  730. hres = S_OK;
  731. }
  732. if (SUCCEEDED(hres))
  733. {
  734. // TRUE: Edit
  735. CFTActionDlg* pActionDlg = new CFTActionDlg(pPIDA, szProgIDDescr, TRUE);
  736. if (pActionDlg)
  737. {
  738. BOOL fShowAgain;
  739. do
  740. {
  741. fShowAgain = FALSE;
  742. if (IDOK == pActionDlg->DoModal(g_hinst, MAKEINTRESOURCE(DLG_FILETYPEOPTIONSCMD), _hwnd))
  743. {
  744. // Do we have duplicate actions?
  745. if (_CheckForDuplicateEditAction(ADDDATA_ACTIONREG(&lvItem), pPIDA->szActionReg,
  746. lvItem.pszText, pPIDA->szAction))
  747. {
  748. // No
  749. if (!fNewOrEdit)
  750. {
  751. hres = _AppendPROGIDACTION(pPIDA);
  752. }
  753. else
  754. {
  755. hres = S_OK;
  756. }
  757. if (SUCCEEDED(hres))
  758. {
  759. // Replace the current item text
  760. hres = StringCchCopy(lvItem.pszText, lvItem.cchTextMax, pPIDA->szAction);
  761. if(SUCCEEDED(hres))
  762. {
  763. ListView_SetItem(_GetLVHWND(), &lvItem);
  764. }
  765. }
  766. }
  767. else
  768. {
  769. // Yes
  770. fShowAgain = TRUE;
  771. pActionDlg->SetShowAgain();
  772. }
  773. }
  774. if (fShowAgain)
  775. {
  776. ShellMessageBox(g_hinst, _hwnd, MAKEINTRESOURCE(IDS_FT_MB_EXISTINGACTION),
  777. MAKEINTRESOURCE(IDS_FT), MB_OK | MB_ICONSTOP, pPIDA->szAction);
  778. }
  779. } while (fShowAgain);
  780. pActionDlg->Release();
  781. }
  782. }
  783. }
  784. return FALSE;
  785. }
  786. LRESULT CFTAdvDlg::OnSetDefault(WORD wNotif)
  787. {
  788. BOOL bRet;
  789. LVITEM lvItem = {0};
  790. // lvItem.iSubItem = 0;
  791. bRet = _GetListViewSelectedItem(0, 0, &lvItem);
  792. if (bRet)
  793. _SetDefaultAction(lvItem.iItem);
  794. else
  795. _SetDefaultAction(-1);
  796. return FALSE;
  797. }
  798. LRESULT CFTAdvDlg::OnRemoveButton(WORD wNotif)
  799. {
  800. TCHAR szExt[MAX_EXT];
  801. HRESULT hres = E_FAIL;
  802. LONG lRes = 0;
  803. LVITEM lvItem = {0};
  804. // lvItem.iSubItem = 0;
  805. lvItem.pszText = szExt;
  806. lvItem.cchTextMax = ARRAYSIZE(szExt);
  807. if (_GetListViewSelectedItem(LVIF_TEXT, 0, &lvItem))
  808. {
  809. if (IDYES == ShellMessageBox(g_hinst, _hwnd, MAKEINTRESOURCE(IDS_FT_MB_REMOVEACTION),
  810. MAKEINTRESOURCE(IDS_FT), MB_YESNO | MB_ICONQUESTION))
  811. {
  812. //
  813. // First take care of data side
  814. //
  815. // Yes. Is this a new Action?
  816. PROGIDACTION* pPIDA = NULL;
  817. if (SUCCEEDED(_GetPROGIDACTION(lvItem.pszText, &pPIDA)) && pPIDA->fNew)
  818. {
  819. // Yes, we'll just remove it from the DPA
  820. hres = _RemovePROGIDACTION(pPIDA);
  821. }
  822. else
  823. {
  824. // No, add its name to the list to delete if user press OK
  825. DWORD cchSize = ARRAYSIZE(ADDDATA_ACTIONREG(&lvItem));
  826. LPTSTR pszActionToRemove = (LPTSTR)LocalAlloc(LPTR,
  827. cchSize * sizeof(TCHAR));
  828. hres = E_OUTOFMEMORY;
  829. if (pszActionToRemove)
  830. {
  831. hres = StringCchCopy(pszActionToRemove, cchSize, ADDDATA_ACTIONREG(&lvItem));
  832. if (SUCCEEDED(hres) && -1 != DPA_AppendPtr(_hdpaRemovedActions, pszActionToRemove))
  833. hres = S_OK;
  834. else
  835. LocalFree((HLOCAL)pszActionToRemove);
  836. }
  837. if (E_OUTOFMEMORY == hres)
  838. {
  839. //Out of memory
  840. ShellMessageBox(g_hinst, _hwnd, MAKEINTRESOURCE(IDS_ERROR +
  841. ERROR_NOT_ENOUGH_MEMORY), MAKEINTRESOURCE(IDS_FT),
  842. MB_OK | MB_ICONSTOP);
  843. }
  844. }
  845. //
  846. // Then update UI, I/A
  847. //
  848. if (SUCCEEDED(hres))
  849. {
  850. HWND hwndLV = _GetLVHWND();
  851. int iCount = ListView_GetItemCount(hwndLV);
  852. int iNextSel = -1;
  853. ListView_DeleteItem(hwndLV, lvItem.iItem);
  854. if (iCount > lvItem.iItem)
  855. iNextSel = lvItem.iItem;
  856. else
  857. if (lvItem.iItem > 0)
  858. iNextSel = lvItem.iItem - 1;
  859. if (-1 != iNextSel)
  860. _SelectListViewItem(iNextSel);
  861. }
  862. }
  863. else
  864. hres = S_FALSE;
  865. }
  866. _CheckDefaultAction();
  867. return FALSE;
  868. }
  869. LRESULT CFTAdvDlg::OnOK(WORD wNotif)
  870. {
  871. BOOL fChecksPassed = FALSE;
  872. // Yes, we need to:
  873. // - remove "removed" items, modify "edited" ones,
  874. // and add "New" ones
  875. // - update checkboxes related stuff
  876. // - set the default action
  877. // - set the icon
  878. // - set the description
  879. {
  880. int n = DPA_GetPtrCount(_hdpaRemovedActions);
  881. if (n)
  882. {
  883. IAssocInfo* pAI;
  884. HRESULT hres = E_FAIL;
  885. for (int i = 0; i < n; ++i)
  886. {
  887. LPTSTR pszActionToRemove = (LPTSTR)DPA_GetPtr(_hdpaRemovedActions, i);
  888. if (pszActionToRemove && *pszActionToRemove)
  889. {
  890. hres = _pAssocStore->GetComplexAssocInfo(_szProgID, AIINIT_PROGID,
  891. pszActionToRemove, AIINIT_ACTION, &pAI);
  892. if (SUCCEEDED(hres))
  893. {
  894. pAI->Delete(AIALL_NONE);
  895. pAI->Release();
  896. }
  897. LocalFree((HLOCAL)pszActionToRemove);
  898. DPA_DeletePtr(_hdpaRemovedActions, i);
  899. }
  900. }
  901. }
  902. }
  903. {
  904. int n = DPA_GetPtrCount(_hdpaActions);
  905. if (n)
  906. {
  907. IAssocInfo* pAI = NULL;
  908. HRESULT hres = E_FAIL;
  909. for (int i = n - 1; i >= 0; --i)
  910. {
  911. PROGIDACTION* pPIDAFromList = (PROGIDACTION*)DPA_GetPtr(_hdpaActions, i);
  912. if (pPIDAFromList)
  913. {
  914. // Is it an Edited one?
  915. if (!pPIDAFromList->fNew)
  916. {
  917. // Yes, remove the old one first
  918. hres = _pAssocStore->GetComplexAssocInfo(_szProgID, AIINIT_PROGID,
  919. pPIDAFromList->szOldActionReg, AIINIT_ACTION, &pAI);
  920. if (SUCCEEDED(hres))
  921. {
  922. pAI->Delete(AIALL_NONE);
  923. pAI->Release();
  924. }
  925. }
  926. // Add new data
  927. hres = _pAssocStore->GetComplexAssocInfo(_szProgID, AIINIT_PROGID,
  928. pPIDAFromList->szActionReg, AIINIT_ACTION, &pAI);
  929. if (SUCCEEDED(hres))
  930. {
  931. hres = pAI->SetData(AIDATA_PROGIDACTION, (PBYTE)pPIDAFromList,
  932. sizeof(*pPIDAFromList));
  933. pAI->Release();
  934. }
  935. // Clean up DPA
  936. _DeletePROGIDACTION(pPIDAFromList);
  937. DPA_DeletePtr(_hdpaActions, i);
  938. }
  939. }
  940. }
  941. }
  942. {
  943. IAssocInfo* pAI = NULL;
  944. HWND hwndLV = _GetLVHWND();
  945. LVFINDINFO lvFindInfo = {0};
  946. int iIndex = -1;
  947. HRESULT hres = _pAssocStore->GetAssocInfo(_szProgID, AIINIT_PROGID, &pAI);
  948. if (SUCCEEDED(hres))
  949. {
  950. TCHAR szActionReg[MAX_ACTION];
  951. hres = pAI->SetBOOL(AIBOOL_CONFIRMOPEN,
  952. !IsDlgButtonChecked(_hwnd, IDC_FT_EDIT_CONFIRM_OPEN));
  953. hres = pAI->SetBOOL(AIBOOL_ALWAYSSHOWEXT,
  954. IsDlgButtonChecked(_hwnd, IDC_FT_EDIT_SHOWEXT));
  955. hres = pAI->SetBOOL(AIBOOL_BROWSEINPLACE,
  956. IsDlgButtonChecked(_hwnd, IDC_FT_EDIT_BROWSEINPLACE));
  957. // Set the default action, if any
  958. if (_GetDefaultAction(szActionReg, ARRAYSIZE(szActionReg)))
  959. {
  960. hres = pAI->SetString(AISTR_PROGIDDEFAULTACTION, szActionReg);
  961. }
  962. else
  963. {
  964. hres = pAI->SetString(AISTR_PROGIDDEFAULTACTION, TEXT(""));
  965. }
  966. // Set the icon, if changed
  967. if (_szIconLoc[0])
  968. {
  969. // Set it in the registry
  970. hres = pAI->SetString(AISTR_ICONLOCATION, _szIconLoc);
  971. if (_szOldIconLoc[0])
  972. {
  973. int iIconIndex = Shell_GetCachedImageIndex(_szOldIconLoc, _iOldIcon, 0);
  974. SHUpdateImage(_szOldIconLoc, _iOldIcon, 0, iIconIndex);
  975. }
  976. }
  977. // Set the description
  978. {
  979. TCHAR szProgIDDescr[MAX_PROGIDDESCR];
  980. GetDlgItemText(_hwnd, IDC_FT_EDIT_DESC, szProgIDDescr,
  981. ARRAYSIZE(szProgIDDescr));
  982. hres = pAI->SetString(AISTR_PROGIDDESCR, szProgIDDescr);
  983. }
  984. pAI->Release();
  985. }
  986. }
  987. EndDialog(_hwnd, IDOK);
  988. return FALSE;
  989. }
  990. LRESULT CFTAdvDlg::OnNotifyListView(UINT uCode, LPNMHDR pNMHDR)
  991. {
  992. HWND hwndLV = _GetLVHWND();
  993. LRESULT lres = FALSE;
  994. switch(uCode)
  995. {
  996. case NM_DBLCLK:
  997. if (IsWindowEnabled(GetDlgItem(_hwnd, IDC_FT_EDIT_EDIT)))
  998. PostMessage(_hwnd, WM_COMMAND, (WPARAM)IDC_FT_EDIT_EDIT, 0);
  999. break;
  1000. //review: do I really need to do this?
  1001. case NM_SETFOCUS:
  1002. case NM_KILLFOCUS:
  1003. // update list view
  1004. ListView_RedrawItems(hwndLV, 0, ListView_GetItemCount(hwndLV));
  1005. UpdateWindow(hwndLV);
  1006. break;
  1007. case LVN_DELETEITEM:
  1008. {
  1009. NMLISTVIEW* pNMLV = (NMLISTVIEW*)pNMHDR;
  1010. if (pNMLV->lParam)
  1011. {
  1012. LocalFree((HLOCAL)(pNMLV->lParam));
  1013. }
  1014. break;
  1015. }
  1016. case LVN_ITEMCHANGED:
  1017. {
  1018. NMLISTVIEW* pNMLV = (NMLISTVIEW*)pNMHDR;
  1019. // Is a new item being selected/unselected?
  1020. if (pNMLV->uChanged & LVIF_STATE)
  1021. {
  1022. // Yes
  1023. OnListViewSelItem(pNMLV->iItem, NULL);
  1024. }
  1025. break;
  1026. }
  1027. }
  1028. return lres;
  1029. }
  1030. LRESULT CFTAdvDlg::OnCancel(WORD wNotif)
  1031. {
  1032. EndDialog(_hwnd, IDCANCEL);
  1033. return FALSE;
  1034. }
  1035. LRESULT CFTAdvDlg::OnDestroy(WPARAM wParam, LPARAM lParam)
  1036. {
  1037. CFTDlg::OnDestroy(wParam, lParam);
  1038. return FALSE;
  1039. }
  1040. BOOL CFTAdvDlg::_GetListViewSelectedItem(UINT uMask, UINT uStateMask, LVITEM* plvItem)
  1041. {
  1042. BOOL fSel = FALSE;
  1043. HWND hwndLV = _GetLVHWND();
  1044. plvItem->mask = uMask | LVIF_STATE | LVIF_PARAM;
  1045. plvItem->stateMask = uStateMask | LVIS_SELECTED;
  1046. // Do we have the selection cached?
  1047. if (-1 != _iLVSel)
  1048. {
  1049. // Yes, make sure it's valid
  1050. plvItem->iItem = _iLVSel;
  1051. ListView_GetItem(hwndLV, plvItem);
  1052. if (plvItem->state & LVIS_SELECTED)
  1053. fSel = TRUE;
  1054. }
  1055. // Cache was wrong
  1056. if (!fSel)
  1057. {
  1058. int iCount = ListView_GetItemCount(hwndLV);
  1059. for (int i=0; (i < iCount) && !fSel; ++i)
  1060. {
  1061. plvItem->iItem = i;
  1062. ListView_GetItem(hwndLV, plvItem);
  1063. if (plvItem->state & LVIS_SELECTED)
  1064. fSel = TRUE;
  1065. }
  1066. if (fSel)
  1067. _iLVSel = i;
  1068. }
  1069. return fSel;
  1070. }
  1071. int CFTAdvDlg::_InsertListViewItem(int iItem, LPTSTR pszActionReg, LPTSTR pszActionFN)
  1072. {
  1073. int iRet = -1;
  1074. HWND hwndLV = _GetLVHWND();
  1075. LVITEM lvItem = {0};
  1076. lvItem.mask = LVIF_TEXT | LVIF_PARAM;
  1077. // Extension
  1078. lvItem.iItem = iItem;
  1079. lvItem.pszText = pszActionFN;
  1080. lvItem.cchTextMax = lstrlen(pszActionFN);
  1081. LV_ADDDATA* plvadddata = (LV_ADDDATA*)LocalAlloc(LPTR, sizeof(LV_ADDDATA));
  1082. if (plvadddata)
  1083. {
  1084. lvItem.lParam = (LPARAM)plvadddata;
  1085. if(SUCCEEDED(StringCchCopy(ADDDATA_ACTIONREG(&lvItem), ARRAYSIZE(ADDDATA_ACTIONREG(&lvItem)), pszActionReg)))
  1086. {
  1087. ADDDATA_DEFAULTACTION(&lvItem) = 0;
  1088. iRet = ListView_InsertItem(hwndLV, &lvItem);
  1089. }
  1090. else
  1091. {
  1092. LocalFree(plvadddata);
  1093. }
  1094. }
  1095. return iRet;
  1096. }
  1097. HWND CFTAdvDlg::_GetLVHWND()
  1098. {
  1099. return GetDlgItem(_hwnd, IDC_FT_EDIT_LV_CMDS);
  1100. }
  1101. void CFTAdvDlg::_DeletePROGIDACTION(PROGIDACTION* pPIDA)
  1102. {
  1103. if (pPIDA)
  1104. LocalFree((HLOCAL)pPIDA);
  1105. }
  1106. HRESULT CFTAdvDlg::_RemovePROGIDACTION(PROGIDACTION* pPIDA)
  1107. {
  1108. HRESULT hres = E_FAIL;
  1109. int n = DPA_GetPtrCount(_hdpaActions);
  1110. for (int i = 0; (i < n) && FAILED(hres); ++i)
  1111. {
  1112. PROGIDACTION* pPIDAFromList = (PROGIDACTION*)DPA_GetPtr(_hdpaActions, i);
  1113. if (pPIDAFromList == pPIDA)
  1114. {
  1115. _DeletePROGIDACTION(pPIDAFromList);
  1116. DPA_DeletePtr(_hdpaActions, i);
  1117. hres = S_OK;
  1118. }
  1119. }
  1120. return hres;
  1121. }
  1122. HRESULT CFTAdvDlg::_CreatePROGIDACTION(PROGIDACTION** ppPIDA)
  1123. {
  1124. HRESULT hres = E_OUTOFMEMORY;
  1125. *ppPIDA = (PROGIDACTION*)LocalAlloc(LPTR, sizeof(PROGIDACTION));
  1126. if (*ppPIDA)
  1127. hres = S_OK;
  1128. return hres;
  1129. }
  1130. HRESULT CFTAdvDlg::_CopyPROGIDACTION(PROGIDACTION* pPIDADest, PROGIDACTION* pPIDASrc)
  1131. {
  1132. memcpy(pPIDADest, pPIDASrc, sizeof(PROGIDACTION));
  1133. return S_OK;
  1134. }
  1135. HRESULT CFTAdvDlg::_GetPROGIDACTION(LPTSTR pszActionFN, PROGIDACTION** ppPIDA)
  1136. {
  1137. HRESULT hres = E_FAIL;
  1138. *ppPIDA = NULL;
  1139. if (pszActionFN && *pszActionFN)
  1140. {
  1141. int n = DPA_GetPtrCount(_hdpaActions);
  1142. for (int i = 0; (i < n) && FAILED(hres); ++i)
  1143. {
  1144. *ppPIDA = (PROGIDACTION*)DPA_GetPtr(_hdpaActions, i);
  1145. if (!StrCmpN((*ppPIDA)->szAction, pszActionFN, ARRAYSIZE((*ppPIDA)->szAction)))
  1146. hres = S_OK;
  1147. }
  1148. }
  1149. if (FAILED(hres))
  1150. *ppPIDA = NULL;
  1151. return hres;
  1152. }
  1153. HRESULT CFTAdvDlg::_AppendPROGIDACTION(PROGIDACTION* pPIDA)
  1154. {
  1155. PROGIDACTION* pPIDANew = NULL;
  1156. HRESULT hres = _CreatePROGIDACTION(&pPIDANew);
  1157. if (SUCCEEDED(hres))
  1158. {
  1159. _CopyPROGIDACTION(pPIDANew, pPIDA);
  1160. if (-1 != DPA_AppendPtr(_hdpaActions, pPIDANew))
  1161. {
  1162. hres = S_OK;
  1163. }
  1164. else
  1165. {
  1166. _DeletePROGIDACTION(pPIDANew);
  1167. hres = E_OUTOFMEMORY;
  1168. }
  1169. }
  1170. if (E_OUTOFMEMORY == hres)
  1171. {
  1172. //Out of memory
  1173. ShellMessageBox(g_hinst, _hwnd, MAKEINTRESOURCE(IDS_ERROR +
  1174. ERROR_NOT_ENOUGH_MEMORY), MAKEINTRESOURCE(IDS_FT),
  1175. MB_OK | MB_ICONSTOP);
  1176. }
  1177. return hres;
  1178. }
  1179. BOOL CFTAdvDlg::_IsNewPROGIDACTION(LPTSTR pszActionFN)
  1180. {
  1181. BOOL fRet = FALSE;
  1182. PROGIDACTION* pPIDA = NULL;
  1183. HRESULT hres = _GetPROGIDACTION(pszActionFN, &pPIDA);
  1184. if (SUCCEEDED(hres))
  1185. if (pPIDA->fNew)
  1186. fRet = TRUE;
  1187. return fRet;
  1188. }
  1189. HRESULT CFTAdvDlg::_FillPROGIDACTION(PROGIDACTION* pPIDA, LPTSTR pszActionReg,
  1190. LPTSTR pszActionFN)
  1191. {
  1192. PROGIDACTION* pPIDAList = NULL;
  1193. HRESULT hres = _GetPROGIDACTION(pszActionFN, &pPIDAList);
  1194. if (SUCCEEDED(hres))
  1195. {
  1196. _CopyPROGIDACTION(pPIDA, pPIDAList);
  1197. }
  1198. else
  1199. {
  1200. IAssocInfo* pAI = NULL;
  1201. hres = _pAssocStore->GetComplexAssocInfo(_szProgID, AIINIT_PROGID,
  1202. pszActionReg, AIINIT_ACTION, &pAI);
  1203. if (SUCCEEDED(hres))
  1204. {
  1205. DWORD cbPIDA = sizeof(*pPIDA);
  1206. hres = pAI->GetData(AIDATA_PROGIDACTION, (PBYTE)pPIDA, &cbPIDA);
  1207. pAI->Release();
  1208. }
  1209. }
  1210. return hres;
  1211. }
  1212. ///////////////////////////////////////////////////////////////////////////////
  1213. // Windows boiler plate code
  1214. LRESULT CFTAdvDlg::OnCommand(WPARAM wParam, LPARAM lParam)
  1215. {
  1216. LRESULT lRes = FALSE;
  1217. switch(GET_WM_COMMAND_ID(wParam, lParam))
  1218. {
  1219. case IDC_FT_EDIT_NEW:
  1220. lRes = OnNewButton(GET_WM_COMMAND_CMD(wParam, lParam));
  1221. break;
  1222. case IDC_FT_EDIT_REMOVE:
  1223. lRes = OnRemoveButton(GET_WM_COMMAND_CMD(wParam, lParam));
  1224. break;
  1225. case IDC_FT_EDIT_EDIT:
  1226. lRes = OnEditButton(GET_WM_COMMAND_CMD(wParam, lParam));
  1227. break;
  1228. case IDC_FT_EDIT_CHANGEICON:
  1229. lRes = OnChangeIcon(GET_WM_COMMAND_CMD(wParam, lParam));
  1230. break;
  1231. case IDC_FT_EDIT_DEFAULT:
  1232. lRes = OnSetDefault(GET_WM_COMMAND_CMD(wParam, lParam));
  1233. break;
  1234. default:
  1235. lRes = CFTDlg::OnCommand(wParam, lParam);
  1236. break;
  1237. }
  1238. return lRes;
  1239. }
  1240. LRESULT CFTAdvDlg::OnNotify(WPARAM wParam, LPARAM lParam)
  1241. {
  1242. LRESULT lRes = FALSE;
  1243. LPNMHDR pNMHDR = (LPNMHDR)lParam;
  1244. UINT_PTR idFrom = pNMHDR->idFrom;
  1245. UINT uCode = pNMHDR->code;
  1246. //GET_WM_COMMAND_CMD
  1247. switch(idFrom)
  1248. {
  1249. case IDC_FT_EDIT_LV_CMDS:
  1250. OnNotifyListView(uCode, pNMHDR);
  1251. lRes = CFTDlg::OnNotify(wParam, lParam);
  1252. break;
  1253. default:
  1254. lRes = CFTDlg::OnNotify(wParam, lParam);
  1255. break;
  1256. }
  1257. return lRes;
  1258. }
  1259. LRESULT CFTAdvDlg::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
  1260. {
  1261. LRESULT lRes = FALSE;
  1262. switch(uMsg)
  1263. {
  1264. case WM_DRAWITEM:
  1265. lRes = OnDrawItem(wParam, lParam);
  1266. break;
  1267. case WM_MEASUREITEM:
  1268. lRes = OnMeasureItem(wParam, lParam);
  1269. break;
  1270. default:
  1271. lRes = CFTDlg::WndProc(uMsg, wParam, lParam);
  1272. break;
  1273. }
  1274. return lRes;
  1275. }