pickicon.c
Upload User: xhy777
Upload Date: 2007-02-14
Package Size: 24088k
Code Size: 10k
Category:

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * pickicon - Icon picker
  3.  */
  4. #include "tweakui.h"
  5. /*
  6.  *  Instance info for the dialog.
  7.  */
  8. typedef struct PIDI { /* PickIcon dialog instance */
  9.     LPTSTR ptszIconPath; /* Which file? */
  10.     UINT ctchIconPath;
  11.     int iIconIndex; /* Which icon number? */
  12.     int *piIconIndex;
  13.     TCH tszCurFile[MAX_PATH]; /* The path in the list box */
  14. } PIDI, *PPIDI;
  15. #define cxIcon GetSystemMetrics(SM_CXICON)
  16. #define cyIcon GetSystemMetrics(SM_CYICON)
  17. /*****************************************************************************
  18.  *
  19.  *  PickIcon_ppidiHdlg
  20.  *
  21.  * Extract the PPIDI from an hdlg.
  22.  *
  23.  *****************************************************************************/
  24. #define PickIcon_ppidiHdlg(hdlg) ((PPIDI)GetWindowLong(hdlg, DWL_USER))
  25. /*****************************************************************************
  26.  *
  27.  *  PickIcon_OnMeasureItem
  28.  *
  29.  * Tell USER the size of each item.
  30.  *
  31.  *****************************************************************************/
  32. void PASCAL
  33. PickIcon_OnMeasureItem(HWND hdlg, LPMEASUREITEMSTRUCT lpmi, PPIDI ppidi)
  34. {
  35.     lpmi->itemWidth = cxIcon + 12;
  36.     lpmi->itemHeight = cyIcon + 4;
  37. }
  38. /*****************************************************************************
  39.  *
  40.  *  PickIcon_OnDrawItem
  41.  *
  42.  * Draw an icon.
  43.  *
  44.  *****************************************************************************/
  45. void PASCAL
  46. PickIcon_OnDrawItem(HWND hdlg, LPDRAWITEMSTRUCT lpdi, PPIDI ppidi)
  47. {
  48.     SetBkColor(lpdi->hDC, GetSysColor((lpdi->itemState & ODS_SELECTED) ?
  49. COLOR_HIGHLIGHT : COLOR_WINDOW));
  50.     /* repaint the selection state */
  51.     ExtTextOut(lpdi->hDC, 0, 0, ETO_OPAQUE, &lpdi->rcItem, NULL, 0, NULL);
  52.     /* draw the icon centered in the rectangle */
  53.     if ((int)lpdi->itemID >= 0) {
  54. DrawIcon(lpdi->hDC,
  55. (lpdi->rcItem.left + lpdi->rcItem.right - cxIcon) / 2,
  56. (lpdi->rcItem.bottom + lpdi->rcItem.top - cyIcon) / 2,
  57. (HICON)lpdi->itemData);
  58.     }
  59.     /* if it has the focus, draw the focus */
  60.     if (lpdi->itemState & ODS_FOCUS) {
  61. DrawFocusRect(lpdi->hDC, &lpdi->rcItem);
  62.     }
  63. }
  64. /*****************************************************************************
  65.  *
  66.  *  PickIcon_OnDeleteItem
  67.  *
  68.  * USER is nuking an item.  Clean it up.
  69.  *
  70.  *****************************************************************************/
  71. #define PickIcon_OnDeleteItem(hdlg, lpdi, ppidi) 
  72.     DestroyIcon((HICON)(lpdi)->itemData)
  73. /*****************************************************************************
  74.  *
  75.  *  PickIcon_FillIconList
  76.  *
  77.  * Fill in all the icons.  If the user picks a bad place, we leave
  78.  * garbage in the path (so he can edit the name) and leave the list
  79.  * box blank.
  80.  *
  81.  *****************************************************************************/
  82. void PickIcon_FillIconList(HWND hdlg, PPIDI ppidi)
  83. {
  84.     HCURSOR hcurOld = SetCursor(LoadCursor(NULL, IDC_WAIT));
  85.     HWND hwnd = GetDlgItem(hdlg, IDC_PICKICON);
  86.     ListBox_SetColumnWidth(hwnd, cxIcon + 12);
  87.     ListBox_ResetContent(hwnd);
  88.     GetDlgItemText(hdlg, IDC_PICKPATH,
  89.    ppidi->tszCurFile, cA(ppidi->tszCurFile));
  90.     if (SearchPath(0, ppidi->tszCurFile, 0, cA(ppidi->tszCurFile),
  91.    ppidi->tszCurFile, 0)) {
  92. int cIcons;
  93. SetDlgItemText(hdlg, IDC_PICKPATH, ppidi->tszCurFile);
  94. cIcons = ExtractIconEx(ppidi->tszCurFile, 0, 0, 0, 0);
  95. if (cIcons) {
  96.     HICON *rgIcons = (HICON *)LocalAlloc(LPTR, cIcons * sizeof(HICON));
  97.     if (rgIcons) {
  98. cIcons = (int)ExtractIconEx(ppidi->tszCurFile, 0,
  99.     rgIcons, NULL, cIcons);
  100. if (cIcons) {
  101.     int iicon;
  102.     SendMessage(hwnd, WM_SETREDRAW, 0, 0);
  103.     for (iicon = 0; iicon < cIcons; iicon++) {
  104. ListBox_AddString(hwnd, rgIcons[iicon]);
  105.     }
  106.     if (ListBox_SetCurSel(hwnd, ppidi->iIconIndex) == LB_ERR) {
  107. ListBox_SetCurSel(hwnd, 0);
  108.     }
  109.     SendMessage(hwnd, WM_SETREDRAW, 1, 0);
  110. } else { /* Mysteriously unable to extract */
  111. }
  112. LocalFree((HLOCAL)rgIcons);
  113.     } else { /* Not enough memory to load icons */
  114.     }
  115. } else { /* No icons in the file */
  116. }
  117.     } else { /* File not found */
  118.     }
  119.     InvalidateRect(hwnd, 0, 1);
  120.     SetCursor(hcurOld);
  121. }
  122. /*****************************************************************************
  123.  *
  124.  *  PickIcon_OnInitDialog
  125.  *
  126.  * Dialog init.  Populate the list box with what we came in with.
  127.  *
  128.  *****************************************************************************/
  129. void PASCAL
  130. PickIcon_OnInitDialog(HWND hdlg, PPIDI ppidi)
  131. {
  132.     SetWindowLong(hdlg, DWL_USER, (LPARAM)ppidi);
  133.     SetDlgItemText(hdlg, IDC_PICKPATH, 
  134.    lstrcpyn(ppidi->tszCurFile,
  135.     ppidi->ptszIconPath, cA(ppidi->tszCurFile)));
  136.     SendDlgItemMessage(hdlg, IDC_PICKPATH, EM_LIMITTEXT,
  137.        ppidi->ctchIconPath, 0);
  138.     PickIcon_FillIconList(hdlg, ppidi);
  139. }
  140. /*****************************************************************************
  141.  *
  142.  *  PickIcon_OnBrowse
  143.  *
  144.  *****************************************************************************/
  145. void PASCAL
  146. PickIcon_OnBrowse(HWND hdlg, PPIDI ppidi)
  147. {
  148.     DWORD dw;
  149.     COFN cofn;
  150.     InitOpenFileName(hdlg, &cofn, IDS_ICONFILES, ppidi->tszCurFile);
  151.     dw = GetFileAttributes(ppidi->tszCurFile);
  152.     if (dw == 0xFFFFFFFF || (dw & FILE_ATTRIBUTE_DIRECTORY)) {
  153. cofn.tsz[0] = '';
  154.     }
  155.     if (GetOpenFileName(&cofn.ofn)) {
  156.         SetDlgItemText(hdlg, IDC_PICKPATH, cofn.tsz);
  157.         SendMessage(hdlg, DM_SETDEFID, IDOK, 0);
  158. PickIcon_FillIconList(hdlg, ppidi);
  159.     }
  160. }
  161. /*****************************************************************************
  162.  *
  163.  *  PickIcon_NameChange
  164.  *
  165.  *  Determine whether the thing in the edit control doesn't match the
  166.  *  thing whose icons we are showing.
  167.  *
  168.  *****************************************************************************/
  169. BOOL PASCAL
  170. PickIcon_NameChange(HWND hdlg, PPIDI ppidi)
  171. {
  172.     TCH tszBuffer[MAX_PATH];
  173.     GetDlgItemText(hdlg, IDC_PICKPATH, tszBuffer, cA(tszBuffer));
  174.     return lstrcmpi(tszBuffer, ppidi->tszCurFile);
  175. }
  176. /*****************************************************************************
  177.  *
  178.  *  PickIcon_OnOk
  179.  *
  180.  * If the name has changed, treat this as a "Okay, now reload
  181.  * the icons" rather than "Okay, I'm finished".
  182.  *
  183.  *****************************************************************************/
  184. void PASCAL
  185. PickIcon_OnOk(HWND hdlg, PPIDI ppidi)
  186. {
  187.     if (PickIcon_NameChange(hdlg, ppidi)) {
  188. PickIcon_FillIconList(hdlg, ppidi);
  189.     } else {
  190. int iIconIndex = (int)SendDlgItemMessage(hdlg, IDC_PICKICON,
  191. LB_GETCURSEL, 0, 0L);
  192. if (iIconIndex >= 0) { /* We have an icon */
  193.     *ppidi->piIconIndex = iIconIndex;
  194.     lstrcpyn(ppidi->ptszIconPath, ppidi->tszCurFile,
  195.      ppidi->ctchIconPath);
  196.     EndDialog(hdlg, 1);
  197. } else { /* No icon, act like cancel */
  198.     EndDialog(hdlg, 0);
  199. }
  200.     }
  201. }
  202. /*****************************************************************************
  203.  *
  204.  *  PickIcon_OnCommand
  205.  *
  206.  *****************************************************************************/
  207. void PASCAL
  208. PickIcon_OnCommand(HWND hdlg, int id, UINT codeNotify, PPIDI ppidi)
  209. {
  210.     switch (id) {
  211.     case IDOK: PickIcon_OnOk(hdlg, ppidi); break;
  212.     case IDCANCEL: EndDialog(hdlg, 0); break;
  213.     case IDC_PICKBROWSE: PickIcon_OnBrowse(hdlg, ppidi); break;
  214.     /*
  215.      * When the name changes, remove the selection highlight.
  216.      */
  217.     case IDC_PICKPATH:
  218. if (PickIcon_NameChange(hdlg, ppidi)) {
  219.     SendDlgItemMessage(hdlg, IDC_PICKICON, LB_SETCURSEL, (WPARAM)-1, 0);
  220. }
  221. break;
  222.     case IDC_PICKICON:
  223. if (PickIcon_NameChange(hdlg, ppidi)) {
  224.     PickIcon_FillIconList(hdlg, ppidi);
  225. } else if (codeNotify == LBN_DBLCLK) {
  226.     PickIcon_OnOk(hdlg, ppidi);
  227. }
  228. break;
  229.     }
  230. }
  231. /*****************************************************************************
  232.  *
  233.  *  PickIcon_DlgProc
  234.  *
  235.  * Dialog procedure.
  236.  *
  237.  *****************************************************************************/
  238. /*
  239.  * The HANDLE_WM_* macros weren't designed to be used from a dialog
  240.  * proc, so we need to handle the messages manually.  (But carefully.)
  241.  */
  242. BOOL EXPORT
  243. PickIcon_DlgProc(HWND hdlg, UINT wm, WPARAM wParam, LPARAM lParam)
  244. {
  245.     PPIDI ppidi = PickIcon_ppidiHdlg(hdlg);
  246.     switch (wm) {
  247.     case WM_INITDIALOG: PickIcon_OnInitDialog(hdlg, (PPIDI)lParam); break;
  248.     case WM_COMMAND:
  249. PickIcon_OnCommand(hdlg, (int)GET_WM_COMMAND_ID(wParam, lParam),
  250.  (UINT)GET_WM_COMMAND_CMD(wParam, lParam),
  251.  ppidi);
  252. break;
  253.     case WM_DRAWITEM:
  254. PickIcon_OnDrawItem(hdlg, (LPDRAWITEMSTRUCT)lParam, ppidi);
  255. break;
  256.     case WM_MEASUREITEM:
  257. PickIcon_OnMeasureItem(hdlg, (LPMEASUREITEMSTRUCT)lParam, ppidi);
  258. break;
  259.     case WM_DELETEITEM:
  260. PickIcon_OnDeleteItem(hdlg, (LPDELETEITEMSTRUCT)lParam, ppidi);
  261. break;
  262.     default: return 0; /* Unhandled */
  263.     }
  264.     return 1; /* Handled */
  265. }
  266. /*****************************************************************************
  267.  *
  268.  *  PickIconDlg
  269.  *
  270.  * Ask the user to pick an icon.
  271.  *
  272.  * hwnd - owner window
  273.  * ptszIconPath - (in) default icon file
  274.  *       (out) chosen icon file
  275.  * ctchIconPath - size of ptszIconPath buffer
  276.  * piIconIndex - (in) default icon index
  277.  *       (out) index of chosen icon
  278.  *
  279.  * If the dialog box is cancelled, then no values are changed.
  280.  *
  281.  *****************************************************************************/
  282. int PASCAL
  283. PickIcon(HWND hwnd, LPTSTR ptszIconPath, UINT ctchIconPath, int *piIconIndex)
  284. {
  285.     PIDI pidi;
  286.     pidi.ptszIconPath = ptszIconPath;
  287.     pidi.ctchIconPath = ctchIconPath;
  288.     pidi.piIconIndex = piIconIndex;
  289.     pidi.iIconIndex = *piIconIndex;
  290.     return DialogBoxParam(hinstCur, MAKEINTRESOURCE(IDD_PICKICON), hwnd,
  291.   PickIcon_DlgProc, (LPARAM)&pidi);
  292. }