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

Windows Kernel

Development Platform:

Visual C++

  1. /*
  2.  * misc - misc stuff
  3.  */
  4. #include "tweakui.h"
  5. #pragma BEGIN_CONST_DATA
  6. #pragma END_CONST_DATA
  7. /*****************************************************************************
  8.  *
  9.  *  Misc_NextPx
  10.  *
  11.  *  Allocate another slot in the growable X array, returning its index.
  12.  *  The slot is not eaten, however.
  13.  *
  14.  *  The array may move as a result of this call; the caller promises
  15.  *  not to use the resulting pointer after the next alloc call.
  16.  *
  17.  *****************************************************************************/
  18. PV PASCAL
  19. Misc_AllocPx(PGXA pgxa)
  20. {
  21.     if (pgxa->cx >= pgxa->cxAlloc) {
  22. PV pv = lReAlloc(pgxa->pv, pgxa->cbx * (pgxa->cxAlloc + 5));
  23. if (pv) {
  24.     pgxa->pv = pv;
  25.     pgxa->cxAlloc += 5;
  26. } else {
  27.     return 0;
  28. }
  29.     }
  30.     return (PBYTE)pgxa->pv + pgxa->cbx * pgxa->cx;
  31. }
  32. /*****************************************************************************
  33.  *
  34.  *  Misc_InitPgxa
  35.  *
  36.  *****************************************************************************/
  37. BOOL PASCAL
  38. Misc_InitPgxa(PGXA pgxa, int cbx)
  39. {
  40.     pgxa->cbx = cbx;
  41.     pgxa->cxAlloc = 5;
  42.     pgxa->cx = 0;
  43.     pgxa->pv = lAlloc(pgxa->cbx * pgxa->cxAlloc);
  44.     return (BOOL)pgxa->pv;
  45. }
  46. /*****************************************************************************
  47.  *
  48.  *  Misc_FreePgxa
  49.  *
  50.  *****************************************************************************/
  51. void PASCAL
  52. Misc_FreePgxa(PGXA pgxa)
  53. {
  54.     if (pgxa->pv) {
  55. lFree(pgxa->pv);
  56.     }
  57. }
  58. /*****************************************************************************
  59.  *
  60.  *  Misc_EnableMenuFromHdlgId
  61.  *
  62.  * Enable or disable a menu item based on a dialog item.
  63.  *
  64.  *****************************************************************************/
  65. void PASCAL
  66. Misc_EnableMenuFromHdlgId(HMENU hmenu, HWND hdlg, UINT idc)
  67. {
  68.     EnableMenuItem(hmenu, idc, MF_BYCOMMAND | (
  69. IsWindowEnabled(GetDlgItem(hdlg, idc)) ? 0 : MFS_GRAYED));
  70. }
  71. /*****************************************************************************
  72.  *
  73.  *  Misc_LV_GetCurSel
  74.  *
  75.  * Return the selection index.
  76.  *
  77.  *****************************************************************************/
  78. int PASCAL
  79. Misc_LV_GetCurSel(HWND hwnd)
  80. {
  81.     return ListView_GetNextItem(hwnd, -1, LVNI_FOCUSED);
  82. }
  83. /*****************************************************************************
  84.  *
  85.  *  Misc_LV_SetCurSel
  86.  *
  87.  * Set the selection index.
  88.  *
  89.  *****************************************************************************/
  90. void PASCAL
  91. Misc_LV_SetCurSel(HWND hwnd, int iIndex)
  92. {
  93.     ListView_SetItemState(hwnd, iIndex, LVIS_FOCUSED | LVIS_SELECTED,
  94. LVIS_FOCUSED | LVIS_SELECTED);
  95. }
  96. /*****************************************************************************
  97.  *
  98.  *  Misc_LV_EnsureSel
  99.  *
  100.  *  Make sure *something* is selected.  Try to make it iItem.
  101.  *
  102.  *****************************************************************************/
  103. void PASCAL
  104. Misc_LV_EnsureSel(HWND hwnd, int iItem)
  105. {
  106.     int iItemMax = ListView_GetItemCount(hwnd) - 1;
  107.     if (iItem > iItemMax) {
  108. iItem = iItemMax;
  109.     }
  110.     Misc_LV_SetCurSel(hwnd, iItem);
  111. }
  112. /*****************************************************************************
  113.  *
  114.  *  Misc_LV_GetItemInfo
  115.  *
  116.  *  Grab some info out of an item.
  117.  *
  118.  *  The incoming LV_ITEM should have any fields initialized which are
  119.  *  required by the mask.  (E.g., the state mask.)
  120.  *
  121.  *****************************************************************************/
  122. void PASCAL
  123. Misc_LV_GetItemInfo(HWND hwnd, LV_ITEM FAR *plvi, int iItem, UINT mask)
  124. {
  125.     plvi->iItem = iItem;
  126.     plvi->iSubItem = 0;
  127.     plvi->mask = mask;
  128.     ListView_GetItem(hwnd, plvi);
  129. }
  130. /*****************************************************************************
  131.  *
  132.  *  Misc_LV_GetParam
  133.  *
  134.  * Convert an iItem into the associated parameter.
  135.  *
  136.  *****************************************************************************/
  137. LPARAM PASCAL
  138. Misc_LV_GetParam(HWND hwnd, int iItem)
  139. {
  140.     LV_ITEM lvi;
  141.     Misc_LV_GetItemInfo(hwnd, &lvi, iItem, LVIF_PARAM);
  142.     return lvi.lParam;
  143. }
  144. /*****************************************************************************
  145.  *
  146.  *  Misc_LV_HitTest
  147.  *
  148.  * Perform a hit-test on the listview.  The LPARAM parameter is
  149.  * the screen coordinates of the message.
  150.  *
  151.  *****************************************************************************/
  152. void PASCAL
  153. Misc_LV_HitTest(HWND hwnd, LV_HITTESTINFO FAR *phti, LPARAM lpPos)
  154. {
  155.     phti->pt.x = (signed short)LOWORD(lpPos);
  156.     phti->pt.y = (signed short)HIWORD(lpPos);
  157.     MapWindowPoints(HWND_DESKTOP, hwnd, &phti->pt, 1);
  158.     
  159.     ListView_HitTest(hwnd, phti);
  160. }
  161. /*****************************************************************************
  162.  *
  163.  *  Misc_Trim
  164.  *
  165.  * Trim leading and trailing spaces from a string.  Returns a pointer
  166.  * to the first non-space character, and slaps a '' on top of the
  167.  * last trailing space.
  168.  *
  169.  *****************************************************************************/
  170. LPTSTR PASCAL
  171. Misc_Trim(LPTSTR ptsz)
  172. {
  173.     int ctch;
  174.     for ( ; (unsigned)(*ptsz - 1) <= ' '; ptsz++);
  175.     for (ctch = lstrlen(ptsz); ctch && (unsigned)ptsz[ctch-1] <= ' '; ctch--);
  176.     if (ctch) {
  177. ptsz[ctch] = '';
  178.     }
  179.     return ptsz;
  180. }
  181. /*****************************************************************************
  182.  *
  183.  *  Misc_SetDrbSize
  184.  *
  185.  * Set the size of the buffer in a DRB.
  186.  *
  187.  *****************************************************************************/
  188. typedef struct DRB { /* dynamically resizable buffer */
  189.     PV pv; /* Actual buffer */
  190.     UINT cb; /* Size of buffer in bytes */
  191. } DRB, *PDRB;
  192. void PASCAL
  193. Misc_SetDrbSize(PDRB pdrb, UINT cb)
  194. {
  195.     if (pdrb->pv) {
  196. LocalFree(pdrb->pv);
  197. pdrb->pv = 0;
  198. pdrb->cb = 0;
  199.     }
  200.     if (cb) {
  201. pdrb->pv = LocalAlloc(LMEM_FIXED, cb);
  202. if (pdrb->pv) {
  203.     pdrb->cb = cb;
  204. }
  205.     }
  206. }
  207. /*****************************************************************************
  208.  *
  209.  *  Misc_EnsureDrb
  210.  *
  211.  * Make sure that the DRB can handle at least cb bytes.
  212.  *
  213.  * Round up to 4K boundary for convenience.
  214.  *
  215.  *****************************************************************************/
  216. BOOL PASCAL
  217. Misc_EnsureDrb(PDRB pdrb, UINT cb)
  218. {
  219.     if (cb <= pdrb->cb) {
  220.     } else {
  221. Misc_SetDrbSize(pdrb, (cb + 1023) & ~1023);
  222.     }
  223.     return (BOOL)pdrb->pv;
  224. }
  225. /*****************************************************************************
  226.  *
  227.  *  Misc_CopyRegWorker
  228.  *
  229.  *  Copy a registry tree from one point to another.
  230.  *
  231.  *  Since this is a recursive routine, don't allocate lots of goo off the
  232.  *  stack.
  233.  *
  234.  *****************************************************************************/
  235. typedef struct RCI { /* registry copy info */
  236.     DRB drb; /* Data being copied */
  237.     TCH tszKey[ctchKeyMax]; /* Key name buffer */
  238. } RCI, *PRCI;
  239. BOOL PASCAL
  240. Misc_CopyRegWorker(PRCI prci, HKEY hkSrcRoot, PCTSTR ptszSrc,
  241.       HKEY hkDstRoot, PCTSTR ptszDst)
  242. {
  243.     HKEY hkSrc, hkDst;
  244.     BOOL fRc;
  245.     if (_RegOpenKey(hkSrcRoot, ptszSrc, &hkSrc) == 0) {
  246. if (RegCreateKey(hkDstRoot, ptszDst, &hkDst) == 0) {
  247.     int i;
  248.     /*
  249.      * The first loop copies the values.
  250.      */
  251.     for (i = 0; ; i++) {
  252. DWORD ctch = cA(prci->tszKey), cb = 0, dwType;
  253. switch (RegEnumValue(hkSrc, i, prci->tszKey, &ctch, 0,
  254.      &dwType, 0, &cb)) {
  255. case ERROR_NO_MORE_ITEMS: goto valuesdone;
  256. /*
  257.  *  We can get an ERROR_SUCCESS if the value length is 0.
  258.  */
  259. case ERROR_SUCCESS:
  260. case ERROR_MORE_DATA:
  261.     if (Misc_EnsureDrb(&prci->drb, cb)) {
  262. DWORD dwType;
  263. if (RegQueryValueEx(hkSrc, prci->tszKey, 0, &dwType,
  264.             prci->drb.pv, &cb) == 0 &&
  265.     RegSetValueEx(hkDst, prci->tszKey, 0, dwType,
  266.   prci->drb.pv, cb) == 0) {
  267. } else {
  268.     fRc = 0; goto stopkey;
  269. }
  270.     } else {
  271. fRc = 0; goto stopkey;
  272.     }
  273.     break;
  274. default:
  275.     fRc = 0; goto stopkey;
  276. }
  277.     }
  278.     valuesdone:;
  279.     /*
  280.      * The second loop recurses on each subkey.
  281.      */
  282.     for (i = 0; ; i++) {
  283. switch (RegEnumKey(hkSrc, i, prci->tszKey, cA(prci->tszKey))) {
  284. case ERROR_NO_MORE_ITEMS: goto keysdone;
  285. /*
  286.  *  We can get an ERROR_SUCCESS if the subkey length is 0.
  287.  *  (Thought that might be illegal for other reasons, but
  288.  *  we'll go along with it anyway.)
  289.  */
  290. case ERROR_SUCCESS:
  291. case ERROR_MORE_DATA:
  292.     if (Misc_CopyRegWorker(prci, hkSrc, prci->tszKey,
  293.  hkDst, prci->tszKey)) {
  294.     } else {
  295. fRc = 0; goto stopkey;
  296.     }
  297.     break;
  298. default:
  299.     fRc = 0; goto stopkey;
  300. }
  301.     }
  302.     keysdone:;
  303.     stopkey:;
  304.     RegCloseKey(hkDst);
  305. } else {
  306.     fRc = 0;
  307. }
  308. RegCloseKey(hkSrc);
  309.     } else {
  310. fRc = 0;
  311.     }
  312.     return fRc;
  313. }
  314. /*****************************************************************************
  315.  *
  316.  *  Misc_CopyReg
  317.  *
  318.  *  Copy a registry tree from one point to another.
  319.  *
  320.  *****************************************************************************/
  321. BOOL PASCAL
  322. Misc_CopyReg(HKEY hkSrcRoot, PCTSTR ptszSrc, HKEY hkDstRoot, PCTSTR ptszDst)
  323. {
  324.     BOOL fRc;
  325.     RCI rci;
  326.     rci.drb.pv = 0;
  327.     rci.drb.cb = 0;
  328.     fRc = Misc_CopyRegWorker(&rci, hkSrcRoot, ptszSrc, hkDstRoot, ptszDst);
  329.     Misc_SetDrbSize(&rci.drb, 0);
  330.     if (fRc) {
  331.     } else {
  332. /* Clean up partial copy */
  333. RegDeleteTree(hkDstRoot, ptszDst);
  334.     }
  335.     return fRc;
  336. }
  337. /*****************************************************************************
  338.  *
  339.  *  Misc_RenameReg
  340.  *
  341.  *  Rename a registry key by copying it and deleting the original.
  342.  *
  343.  *****************************************************************************/
  344. BOOL PASCAL
  345. Misc_RenameReg(HKEY hkRoot, PCTSTR ptszKey, PCTSTR ptszSrc, PCTSTR ptszDst)
  346. {
  347.     BOOL fRc;
  348.     HKEY hk;
  349.     if (_RegOpenKey(hkRoot, ptszKey, &hk) == 0) {
  350.         if (Misc_CopyReg(hk, ptszSrc, hk, ptszDst)) {
  351.             RegDeleteTree(hk, ptszSrc);
  352.             fRc = TRUE;
  353.         } else {
  354.             fRc = FALSE;
  355.         }
  356.         RegCloseKey(hk);
  357.     } else {
  358.         fRc = FALSE;
  359.     }
  360.     return fRc;
  361. }
  362. /*****************************************************************************
  363.  *
  364.  *  lstrcatnBs
  365.  *
  366.  *  Like lstrcatn, but with a backslash stuck in between.
  367.  *
  368.  *****************************************************************************/
  369. void PASCAL
  370. lstrcatnBs(PTSTR ptszDst, PCTSTR ptszSrc, int ctch)
  371. {
  372.     int ctchDst = lstrlen(ptszDst);
  373.     ptszDst += ctchDst;
  374.     ctch -= ctchDst;
  375.     if (ctch > 1) {
  376. ptszDst[0] = TEXT('\');
  377. lstrcpyn(ptszDst + 1, ptszSrc, ctch - 1);
  378.     }
  379. }
  380. /*****************************************************************************
  381.  *
  382.  *  Misc_GetShellIconSize
  383.  *
  384.  *****************************************************************************/
  385. #pragma BEGIN_CONST_DATA
  386. KL const c_klShellIconSize = { &c_hkCU, c_tszMetrics, c_tszShellIconSize };
  387. #pragma END_CONST_DATA
  388. UINT PASCAL
  389. Misc_GetShellIconSize(void)
  390. {
  391.     return GetIntPkl(GetSystemMetrics(SM_CXICON), &c_klShellIconSize);
  392. }
  393. /*****************************************************************************
  394.  *
  395.  *  Misc_SetShellIconSize
  396.  *
  397.  * Dork the shell icon size and rebuild.
  398.  *
  399.  *****************************************************************************/
  400. void PASCAL
  401. Misc_SetShellIconSize(UINT ui)
  402. {
  403.     SetIntPkl(ui, &c_klShellIconSize);
  404.     SendMessage(HWND_BROADCAST, WM_SETTINGCHANGE, SPI_SETNONCLIENTMETRICS, 0L);
  405. }
  406. /*****************************************************************************
  407.  *
  408.  *  Misc_RebuildIcoCache
  409.  *
  410.  * Force the shell to rebuild its icon cache.
  411.  *
  412.  * Due to the way the shell works, we have to do this by changing
  413.  * the icon sizes, then changing it back.
  414.  *
  415.  *****************************************************************************/
  416. void PASCAL
  417. Misc_RebuildIcoCache(void)
  418. {
  419.     UINT cxIcon = Misc_GetShellIconSize();
  420.     Misc_SetShellIconSize(cxIcon-1);
  421.     Misc_SetShellIconSize(cxIcon);
  422.     Explorer_HackPtui();
  423. }