Source code of Windows XP (NT5)
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.

302 lines
7.0 KiB

  1. /* UTILS.C
  2. Resident Code Segment // Tweak: make non-resident?
  3. NoMem string utility routines
  4. String utility routines
  5. Frosting: Master Theme Selector for Windows '95
  6. Copyright (c) 1994-1999 Microsoft Corporation. All rights reserved.
  7. */
  8. // ---------------------------------------------
  9. // Brief file history:
  10. // Alpha:
  11. // Beta:
  12. // Bug fixes
  13. // ---------
  14. //
  15. // ---------------------------------------------
  16. #include "windows.h"
  17. #include "frost.h"
  18. #include "global.h"
  19. // Local Routines
  20. // Local global vars
  21. TCHAR szNoMem[NUM_NOMEM_STRS][MAX_STRLEN+1];
  22. // InitNoMem
  23. //
  24. // Stores all the no/low memory error messages in the data segment,
  25. // so you're guaranteed to have them when you need them.
  26. //
  27. // Called at init, when we are assured these loads succeed.
  28. //
  29. // Note that this loop shows why the string IDs for the low mem
  30. // messages need to be consecutive and starting with STR_NOT_ENUF,
  31. // as noted in the .H file.
  32. //
  33. void FAR InitNoMem(hinst)
  34. HANDLE hinst;
  35. {
  36. int iter;
  37. for (iter = 0; iter < NUM_NOMEM_STRS; iter++)
  38. LoadString(hinst, STR_NOT_ENUF+iter,
  39. &(szNoMem[iter][0]), MAX_STRLEN);
  40. }
  41. // NoMemMsg
  42. //
  43. // Takes the low memory error string suffix, creates the full string, posts
  44. // a messagebox. We are assured of being able to get a messagebox in low
  45. // memory situations with at least a hand icon.
  46. //
  47. // Note that the second line shows why the string IDs for the low mem
  48. // messages need to be consecutive and starting with STR_NOT_ENUF,
  49. // as noted in the .H file.
  50. //
  51. void FAR NoMemMsg(istr)
  52. int istr;
  53. {
  54. lstrcpy( (LPTSTR)szMsg, (LPCTSTR)&(szNoMem[0][0]) );
  55. lstrcat( (LPTSTR)szMsg, (LPCTSTR)&(szNoMem[istr-STR_NOT_ENUF][0]) );
  56. MessageBox((HWND)hWndApp, (LPCTSTR)szMsg, (LPCTSTR)szAppName,
  57. MB_OK | MB_ICONSTOP | MB_SYSTEMMODAL);
  58. }
  59. /*=============================================================================
  60. FILEFROMPATH returns the filename of given filename which may include path.
  61. Q: International: always same chars for \ and :, or should we do a string
  62. compare with a resource string for each?
  63. Q: International: does lstrlen return chars or bytes to make the first line
  64. work or not?
  65. =============================================================================*/
  66. LPTSTR FAR FileFromPath(lpsz)
  67. LPCTSTR lpsz;
  68. {
  69. LPTSTR lpch;
  70. /* Strip path/drive specification from name if there is one */
  71. lpch = CharPrev((LPCTSTR)lpsz, (LPCTSTR)(lpsz + lstrlen(lpsz)));
  72. while (lpch > lpsz) {
  73. lpch = CharPrev((LPCTSTR)lpsz, (LPCTSTR)lpch);
  74. if (*lpch == TEXT('\\') || *lpch == TEXT(':')) {
  75. lpch = CharNext((LPCTSTR)lpch);
  76. break;
  77. }
  78. }
  79. return(lpch);
  80. } /* end FileFromPath */ // JUST FOR INIT DEBUG
  81. // TruncateExt
  82. //
  83. // Utility routine that removes extension from filename
  84. // See International questions above routine.
  85. //
  86. void FAR TruncateExt(LPCTSTR lpstr)
  87. {
  88. LPTSTR lpch;
  89. // find the dot before the extension, truncate from there if found
  90. lpch = CharPrev((LPCTSTR)lpstr, (LPCTSTR)(lpstr + lstrlen(lpstr)));
  91. while (lpch > lpstr) {
  92. lpch = CharPrev((LPCTSTR)lpstr, (LPCTSTR)lpch);
  93. if (*lpch == TEXT('.')) {
  94. *lpch = 0; // null terminate
  95. break; // you're done now EXIT loop
  96. }
  97. }
  98. }
  99. //
  100. // FindChar
  101. //
  102. // Subset of a substring search. Just looks for first instance of a single
  103. // character in a string.
  104. //
  105. // Returns: pointer into string you passed, or to its null term if not found
  106. //
  107. LPTSTR FAR FindChar(LPTSTR lpszStr, TCHAR chSearch)
  108. {
  109. LPTSTR lpszScan;
  110. for (lpszScan = lpszStr;
  111. *lpszScan && (*lpszScan != chSearch); // ***DEBUG*** char compare in intl?
  112. lpszScan = CharNext(lpszScan))
  113. { }
  114. // cleanup
  115. return (lpszScan); // either points to null term or search char
  116. }
  117. //
  118. // ascii to integer conversion routine
  119. //
  120. // ***DEBUG*** int'l: is this true?
  121. // These don't need to be UNICODE/international ready, since they
  122. // *only* deal with strings from the Registry and our own private
  123. // INI files.
  124. /* CAREFUL!! This atoi just IGNORES non-numerics like decimal points!!! */
  125. /* checks for (>=1) leading negative sign */
  126. int FAR latoi( s )
  127. LPSTR s;
  128. {
  129. int n;
  130. LPSTR pS;
  131. BOOL bSeenNum;
  132. BOOL bNeg;
  133. n=0;
  134. bSeenNum = bNeg = FALSE;
  135. for (pS=s; *pS; pS++) {
  136. if ((*pS >= '0') && (*pS <= '9')) {
  137. bSeenNum = TRUE;
  138. n = n*10 + (*pS - '0');
  139. }
  140. if (!bSeenNum && (*pS == '-')) {
  141. bNeg = TRUE;
  142. }
  143. }
  144. if (bNeg) {
  145. n = -n;
  146. }
  147. return(n);
  148. }
  149. void lreverse( s )
  150. LPSTR s;
  151. {
  152. LPSTR p1, p2;
  153. char c;
  154. p1 = s;
  155. p2 = (LPSTR)(p1+ lstrlenA((LPSTR) p1 ) - 1 );
  156. while( p1 < p2 ) {
  157. c = *p1;
  158. *p1++ = *p2;
  159. *p2-- = c;
  160. }
  161. }
  162. VOID FAR litoa( n, s )
  163. int n;
  164. LPSTR s;
  165. {
  166. LPSTR pS;
  167. BOOL bNeg = FALSE;
  168. if (n < 0) {
  169. n = -n;
  170. bNeg = TRUE;
  171. }
  172. pS = s;
  173. do {
  174. *pS = n % 10 + '0';
  175. pS++;
  176. } while ( (n /= 10) != 0 );
  177. if (bNeg) {
  178. *pS = '-';
  179. pS++;
  180. }
  181. *pS = '\0';
  182. lreverse( s );
  183. }
  184. //
  185. // LongToShortToLong
  186. //
  187. // Can take either as input (?).
  188. // Output string has to be long enough (14 or MAX_PATH)
  189. //
  190. // OK for input and output to be the same string.
  191. //
  192. // Returns: success in finding file
  193. BOOL FAR FilenameToShort(LPTSTR lpszInput, LPTSTR lpszShort)
  194. {
  195. WIN32_FIND_DATA wfdFind;
  196. HANDLE hFind;
  197. // init
  198. hFind = FindFirstFile(lpszInput, (LPWIN32_FIND_DATA)&wfdFind);
  199. if (INVALID_HANDLE_VALUE == hFind) {
  200. *lpszShort = 0; // error null return
  201. return (FALSE); // couldn't find file EXIT
  202. }
  203. // meat
  204. if (wfdFind.cAlternateFileName[0])
  205. lstrcpy(lpszShort, (LPTSTR)wfdFind.cAlternateFileName);
  206. else
  207. // sometimes no alternate given; e.g. if short == long
  208. lstrcpy(lpszShort, (LPTSTR)wfdFind.cFileName);
  209. // cleanup
  210. FindClose(hFind);
  211. Assert(*lpszShort, TEXT("no short filename constructed!\n"))
  212. return (*lpszShort);
  213. }
  214. BOOL FAR FilenameToLong(LPTSTR lpszInput, LPTSTR lpszLong)
  215. {
  216. WIN32_FIND_DATA wfdFind;
  217. HANDLE hFind;
  218. // init
  219. hFind = FindFirstFile(lpszInput, (LPWIN32_FIND_DATA)&wfdFind);
  220. if (INVALID_HANDLE_VALUE == hFind) {
  221. *lpszLong = 0; // error null return
  222. return (FALSE); // couldn't find file EXIT
  223. }
  224. // meat
  225. if (wfdFind.cFileName[0])
  226. lstrcpy(lpszLong, (LPTSTR)wfdFind.cFileName);
  227. else
  228. // sometimes no long name given; e.g. if funny old file
  229. lstrcpy(lpszLong, (LPTSTR)wfdFind.cAlternateFileName);
  230. // cleanup
  231. FindClose(hFind);
  232. Assert(*lpszLong, TEXT("no long filename constructed!\n"))
  233. return (*lpszLong);
  234. }
  235. //
  236. // IsValidThemeFile
  237. //
  238. // Answers the question.
  239. //
  240. BOOL FAR IsValidThemeFile(LPTSTR lpTest)
  241. {
  242. extern TCHAR szFrostSection[], szMagic[], szVerify[];
  243. GetPrivateProfileString((LPTSTR)szFrostSection,
  244. (LPTSTR)szMagic,
  245. (LPTSTR)szNULL,
  246. (LPTSTR)szMsg, MAX_MSGLEN,
  247. (LPTSTR)lpTest);
  248. return (!lstrcmp((LPTSTR)szMsg, (LPTSTR)szVerify));
  249. }