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.

377 lines
8.4 KiB

  1. /* icon.c - Handles Icon + Caption objects.
  2. */
  3. #include "packager.h"
  4. #include <shellapi.h>
  5. // #include <shlapip.h>
  6. static LPIC IconCreate(VOID);
  7. void GetDisplayName(LPSTR szName, LPCSTR szPath);
  8. /* IconClone() -
  9. *
  10. * Clones an appearance pane icon.
  11. */
  12. LPIC
  13. IconClone(
  14. LPIC lpic
  15. )
  16. {
  17. LPIC lpicNew;
  18. if (lpicNew = IconCreate())
  19. {
  20. // Get the icon
  21. StringCchCopy(lpicNew->szIconPath, ARRAYSIZE(lpicNew->szIconPath), lpic->szIconPath);
  22. lpicNew->iDlgIcon = lpic->iDlgIcon;
  23. GetCurrentIcon(lpicNew);
  24. // Get the icon text
  25. StringCchCopy(lpicNew->szIconText, ARRAYSIZE(lpicNew->szIconText), lpic->szIconText);
  26. }
  27. return lpicNew;
  28. }
  29. /* IconCreate() -
  30. */
  31. static LPIC
  32. IconCreate(
  33. VOID
  34. )
  35. {
  36. HANDLE hdata = NULL;
  37. LPIC lpic = NULL;
  38. if (!(hdata = GlobalAlloc(GMEM_MOVEABLE, sizeof(IC)))
  39. || !(lpic = (LPIC)GlobalLock(hdata)))
  40. goto errRtn;
  41. // Store the data in the window itself
  42. lpic->hdata = hdata;
  43. lpic->hDlgIcon = NULL;
  44. lpic->iDlgIcon = 0;
  45. *lpic->szIconPath = 0;
  46. *lpic->szIconText = 0;
  47. return lpic;
  48. errRtn:
  49. ErrorMessage(E_FAILED_TO_CREATE_CHILD_WINDOW);
  50. if (lpic)
  51. GlobalUnlock(hdata);
  52. if (hdata)
  53. GlobalFree(hdata);
  54. return NULL;
  55. }
  56. /* IconCreateFromFile() -
  57. *
  58. * Allows an appearance pane icon to be created automatically if
  59. * a file is dropped, imported, or pasted into the packager.
  60. */
  61. LPIC
  62. IconCreateFromFile(
  63. LPSTR lpstrFile
  64. )
  65. {
  66. LPIC lpic;
  67. if (lpic = IconCreate())
  68. {
  69. // Get the icon
  70. StringCchCopy(lpic->szIconPath, ARRAYSIZE(lpic->szIconPath), lpstrFile);
  71. lpic->iDlgIcon = 0;
  72. if (*(lpic->szIconPath))
  73. GetCurrentIcon(lpic);
  74. // Get the icon text
  75. GetDisplayName(lpic->szIconText, lpstrFile);
  76. }
  77. return lpic;
  78. }
  79. /* IconCreateFromObject() -
  80. *
  81. * Allows an appearance pane icon to be created automatically if an
  82. * OLE object is dropped into the appearance pane.
  83. */
  84. LPIC
  85. IconCreateFromObject(
  86. LPOLEOBJECT lpObject
  87. )
  88. {
  89. DWORD otObject;
  90. HANDLE hdata;
  91. LPIC lpic = NULL;
  92. LPSTR lpdata;
  93. OleQueryType(lpObject, &otObject);
  94. if ((otObject == OT_LINK
  95. && Error(OleGetData(lpObject, gcfLink, &hdata)))
  96. || (otObject == OT_EMBEDDED
  97. && Error(OleGetData(lpObject, gcfOwnerLink, &hdata))))
  98. hdata = NULL;
  99. if (hdata && (lpdata = GlobalLock(hdata)))
  100. {
  101. if (lpic = IconCreate())
  102. {
  103. // Get the icon
  104. RegGetExeName(lpic->szIconPath, lpdata, CBPATHMAX);
  105. lpic->iDlgIcon = 0;
  106. GetCurrentIcon(lpic);
  107. // Get the icon text
  108. switch (otObject)
  109. {
  110. case OT_LINK:
  111. while (*lpdata++)
  112. ;
  113. StringCchCopy(lpic->szIconText, ARRAYSIZE(lpic->szIconText), lpdata);
  114. Normalize(lpic->szIconText);
  115. break;
  116. case OT_EMBEDDED:
  117. RegGetClassId(lpic->szIconText, ARRAYSIZE(lpic->szIconText), lpdata);
  118. break;
  119. }
  120. GlobalUnlock(hdata);
  121. }
  122. }
  123. return lpic;
  124. }
  125. /* IconDelete() - Used to clear the appearance pane of icon stuff.
  126. */
  127. VOID
  128. IconDelete(
  129. LPIC lpic
  130. )
  131. {
  132. HANDLE hdata;
  133. if (!lpic)
  134. return;
  135. if (lpic->hDlgIcon)
  136. DestroyIcon(lpic->hDlgIcon);
  137. GlobalUnlock(hdata = lpic->hdata);
  138. GlobalFree(hdata);
  139. }
  140. /* IconDraw() - Used to draw the icon and its caption.
  141. */
  142. VOID
  143. IconDraw(
  144. LPIC lpic,
  145. HDC hdc,
  146. LPRECT lprc,
  147. BOOL fFocus,
  148. INT cxImage,
  149. INT cyImage
  150. )
  151. {
  152. BOOL fMF;
  153. HFONT hfont = NULL;
  154. RECT rcText;
  155. DWORD dwLayout;
  156. hfont = SelectObject(hdc, ghfontTitle);
  157. if (!(fMF = (cxImage && cyImage)))
  158. {
  159. // Figure out how large the text region will be
  160. if (*(lpic->szIconText))
  161. {
  162. SetRect(&rcText, 0, 0, gcxArrange - 1, gcyArrange - 1);
  163. DrawText(hdc, lpic->szIconText, -1, &rcText,
  164. DT_CALCRECT | DT_WORDBREAK | DT_NOPREFIX | DT_SINGLELINE);
  165. }
  166. else
  167. {
  168. SetRect(&rcText, 0, 0, 0, 0);
  169. }
  170. // Figure out the image dimensions
  171. cxImage = (gcxIcon > rcText.right) ? gcxIcon : rcText.right;
  172. cyImage = gcyIcon + rcText.bottom;
  173. }
  174. // Draw the icon
  175. if (lpic->hDlgIcon)
  176. {
  177. // Do not mirror the Icon.
  178. dwLayout = GetLayout(hdc);
  179. if ((dwLayout != GDI_ERROR) && (dwLayout & LAYOUT_RTL)) {
  180. SetLayout(hdc, dwLayout | LAYOUT_BITMAPORIENTATIONPRESERVED);
  181. }
  182. DrawIcon(hdc, (lprc->left + lprc->right - gcxIcon) / 2,
  183. (lprc->top + lprc->bottom - cyImage) / 2, lpic->hDlgIcon);
  184. if ((dwLayout != GDI_ERROR) && (dwLayout & LAYOUT_RTL)) {
  185. SetLayout(hdc, dwLayout);
  186. }
  187. }
  188. // Draw the icon text
  189. if (*(lpic->szIconText))
  190. {
  191. if (fMF)
  192. {
  193. SetBkMode(hdc, TRANSPARENT);
  194. SetTextAlign(hdc, TA_CENTER);
  195. TextOut(hdc, cxImage / 2, gcyIcon + 1, lpic->szIconText,
  196. lstrlen(lpic->szIconText));
  197. }
  198. else
  199. {
  200. OffsetRect(&rcText, (lprc->left + lprc->right - cxImage) / 2,
  201. (lprc->top + lprc->bottom - cyImage) / 2 + gcyIcon);
  202. DrawText(hdc, lpic->szIconText, -1, &rcText,
  203. DT_CENTER | DT_WORDBREAK | DT_NOPREFIX | DT_SINGLELINE);
  204. }
  205. }
  206. if (hfont)
  207. SelectObject(hdc, hfont);
  208. if (fFocus && cxImage && cyImage)
  209. {
  210. RECT rcFocus;
  211. SetRect(&rcFocus, (lprc->left + lprc->right - cxImage) / 2, (lprc->top +
  212. lprc->bottom - cyImage) / 2, (lprc->left + lprc->right + cxImage) /
  213. 2, (lprc->top + lprc->bottom + cyImage) / 2);
  214. DrawFocusRect(hdc, &rcFocus);
  215. }
  216. }
  217. /* IconReadFromNative() - Used to retrieve the icon object from memory.
  218. */
  219. LPIC
  220. IconReadFromNative(
  221. LPSTR *lplpstr
  222. )
  223. {
  224. LPIC lpic;
  225. WORD w;
  226. if (lpic = IconCreate())
  227. {
  228. StringCchCopy(lpic->szIconText, ARRAYSIZE(lpic->szIconText), *lplpstr);
  229. *lplpstr += lstrlen(lpic->szIconText) + 1;
  230. StringCchCopy(lpic->szIconPath, ARRAYSIZE(lpic->szIconPath), *lplpstr);
  231. *lplpstr += lstrlen(lpic->szIconPath) + 1;
  232. MemRead(lplpstr, (LPSTR)&w, sizeof(WORD));
  233. lpic->iDlgIcon = (INT)w;
  234. GetCurrentIcon(lpic);
  235. }
  236. return lpic;
  237. }
  238. /* IconWriteToNative() - Used to write the icon object to memory.
  239. */
  240. DWORD
  241. IconWriteToNative(
  242. LPIC lpic,
  243. LPSTR *lplpstr
  244. )
  245. {
  246. DWORD cBytes;
  247. WORD w;
  248. if (lplpstr)
  249. {
  250. // Now, write out the icon text and the icon
  251. cBytes = lstrlen(lpic->szIconText) + 1;
  252. MemWrite(lplpstr, (LPSTR)lpic->szIconText, cBytes);
  253. cBytes = lstrlen(lpic->szIconPath) + 1;
  254. MemWrite(lplpstr, (LPSTR)lpic->szIconPath, cBytes);
  255. w = (WORD)lpic->iDlgIcon;
  256. MemWrite(lplpstr, (LPSTR)&w, sizeof(WORD));
  257. }
  258. return (lstrlen(lpic->szIconText) + 1 + lstrlen(lpic->szIconPath) + 1 +
  259. sizeof(WORD));
  260. }
  261. VOID
  262. GetCurrentIcon(
  263. LPIC lpic
  264. )
  265. {
  266. WORD wIcon = (WORD)lpic->iDlgIcon;
  267. if (lpic->hDlgIcon)
  268. DestroyIcon(lpic->hDlgIcon);
  269. if (!(lpic->hDlgIcon = ExtractAssociatedIcon(ghInst, lpic->szIconPath,
  270. &wIcon)))
  271. lpic->hDlgIcon = LoadIcon(ghInst, MAKEINTRESOURCE(ID_APPLICATION));
  272. }
  273. //
  274. // get the nice name to show to the user given a filename
  275. //
  276. // FEATURE: we realy should just call the shell!!!
  277. //
  278. void GetDisplayName(LPSTR szName, LPCSTR szPath)
  279. {
  280. WIN32_FIND_DATA fd;
  281. HANDLE h;
  282. BOOL IsLFN;
  283. StringCchCopy(szName, MAX_PATH, szPath); // verified
  284. h = FindFirstFile(szPath, &fd);
  285. if (h != INVALID_HANDLE_VALUE)
  286. {
  287. FindClose(h);
  288. StringCchCopy(szName, MAX_PATH, fd.cFileName);
  289. IsLFN = !(fd.cAlternateFileName[0] == 0 ||
  290. lstrcmp(fd.cFileName, fd.cAlternateFileName) == 0);
  291. if (!IsLFN)
  292. {
  293. AnsiLower(szName);
  294. AnsiUpperBuff(szName, 1);
  295. }
  296. }
  297. else
  298. {
  299. Normalize(szName); // strip path part
  300. }
  301. }