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.

523 lines
15 KiB

  1. /******************************************************************************
  2. winx.cpp
  3. Windows utility procedures
  4. Copyright (C) Microsoft Corporation, 1997 - 1998
  5. All rights reserved
  6. Notes:
  7. THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
  8. KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
  9. IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR FITNESS FOR A PARTICULAR
  10. PURPOSE.
  11. ******************************************************************************/
  12. #include "stillvue.h"
  13. #include <math.h> // pow
  14. // WINERROR.H - GetLastError errors
  15. STRINGTABLE StWinerror[] =
  16. {
  17. ERROR_SUCCESS, "ERROR_SUCCESS",0,
  18. ERROR_FILE_NOT_FOUND, "ERROR_FILE_NOT_FOUND",0,
  19. ERROR_PATH_NOT_FOUND, "ERROR_PATH_NOT_FOUND",0,
  20. ERROR_INVALID_FUNCTION, "ERROR_INVALID_FUNCTION",0,
  21. ERROR_ACCESS_DENIED, "ERROR_ACCESS_DENIED",0,
  22. ERROR_INVALID_HANDLE, "ERROR_INVALID_HANDLE",0,
  23. ERROR_INVALID_PARAMETER, "ERROR_INVALID_PARAMETER",0,
  24. ERROR_CALL_NOT_IMPLEMENTED, "ERROR_CALL_NOT_IMPLEMENTED",0,
  25. ERROR_ALREADY_EXISTS, "ERROR_ALREADY_EXISTS",0,
  26. ERROR_INVALID_FLAGS, "ERROR_INVALID_FLAGS",0,
  27. ERROR_INVALID_CATEGORY, "ERROR_INVALID_CATEGORY",0,
  28. RPC_S_SERVER_UNAVAILABLE, "RPC_S_SERVER_UNAVAILABLE",0,
  29. 0, "See WINERROR.H",-1
  30. };
  31. /******************************************************************************
  32. ULONG atox(LPSTR lpHex)
  33. Convert string to hexadecimal value.
  34. ******************************************************************************/
  35. ULONG atox(LPSTR lpHex)
  36. {
  37. char *p;
  38. int x;
  39. double y;
  40. ULONG z,ulHex = 0l;
  41. for (p = lpHex,x = 0;p[x];x++)
  42. ;
  43. for (x--,y = 0.0;lpHex <= (p + x);x--,y++)
  44. {
  45. z = (ULONG) pow(16.0,y);
  46. if ((p[x] >= '0')&&(p[x] <= '9'))
  47. ulHex += ((p[x] - '0') * z);
  48. if ((p[x] >= 'A')&&(p[x] <= 'F'))
  49. ulHex += ((p[x] - 'A' + 10) * z);
  50. if ((p[x] >= 'a')&&(p[x] <= 'f'))
  51. ulHex += ((p[x] - 'a' + 10) * z);
  52. }
  53. return (ulHex);
  54. }
  55. #ifdef _DEBUG
  56. /******************************************************************************
  57. void DisplayDebug(LPSTR sz,...)
  58. Output text to debugger.
  59. ******************************************************************************/
  60. void DisplayDebug(LPSTR sz,...)
  61. {
  62. char Buffer[512];
  63. va_list list;
  64. va_start(list,sz);
  65. vsprintf(Buffer,sz,list);
  66. OutputDebugString(Buffer);
  67. OutputDebugString("\n");
  68. return;
  69. }
  70. #else
  71. /******************************************************************************
  72. void DisplayDebug(LPSTR sz,...)
  73. Output text to debugger - nonfunctional retail version..
  74. ******************************************************************************/
  75. void DisplayDebug(LPSTR sz,...)
  76. {
  77. return;
  78. }
  79. #endif
  80. /******************************************************************************
  81. BOOL ErrorMsg(HWND, LPSTR, LPSTR, BOOL)
  82. Display an error message and send WM_QUIT if error is fatal.
  83. Parameters: handle to current window,
  84. long pointer to string with error message,
  85. long pointer to string with message box caption,
  86. error (Fatal if TRUE)
  87. Shut down app if bFatal is TRUE, continue if FALSE.
  88. ******************************************************************************/
  89. BOOL ErrorMsg(HWND hWnd, LPSTR lpzMsg, LPSTR lpzCaption, BOOL bFatal)
  90. {
  91. MessageBox(hWnd, lpzMsg, lpzCaption, MB_ICONEXCLAMATION | MB_OK);
  92. if (bFatal)
  93. PostMessage (hWnd, WM_QUIT, 0, 0L);
  94. return (bFatal);
  95. }
  96. /******************************************************************************
  97. fDialog(id,hwnd,fpfn)
  98. Description:
  99. This function displays a dialog box and returns the exit code.
  100. the function passed will have a proc instance made for it.
  101. Parameters:
  102. id resource id of dialog to display
  103. hwnd parent window of dialog
  104. fpfn dialog message function
  105. Returns:
  106. exit code of dialog (what was passed to EndDialog)
  107. ******************************************************************************/
  108. BOOL fDialog(int id,HWND hWnd,FARPROC fPfn)
  109. {
  110. BOOL f;
  111. HINSTANCE hInst;
  112. hInst = (HINSTANCE) GetWindowLong(hWnd,GWL_HINSTANCE);
  113. fPfn = MakeProcInstance(fPfn,hInst);
  114. f = DialogBox(hInst,MAKEINTRESOURCE(id),hWnd,(DLGPROC)fPfn);
  115. FreeProcInstance(fPfn);
  116. return (f);
  117. }
  118. /******************************************************************************
  119. void FormatHex(unsigned char *szSource, char *szDest)
  120. take first 16 bytes from szSource,
  121. format into a hex dump string,
  122. then copy the string into szDest
  123. szDest must have room for at least 66 bytes
  124. sample code fragment showing use:
  125. char szOut[128], // output string
  126. // print header
  127. sprintf(szOut,
  128. "Offset --------------------- hex --------------------- ---- ascii -----");
  129. puts(szOut);
  130. // dump 512 bytes (32 lines, 16 bytes per line)
  131. for (i = 0; i < 32; i++)
  132. {
  133. // get next 16 bytes
  134. _fmemcpy(szDbgMsg,fpSector + (i*16),16);
  135. // get current offset into data block
  136. sprintf(szOut,"%03xh(%03d) ",i*16,i*16);
  137. // append debug string after data block offset message
  138. FormatHex(szDbgMsg, szOut + strlen(szOut));
  139. puts(szOut);
  140. }
  141. ******************************************************************************/
  142. void FormatHex(unsigned char *szSource, char *szDest)
  143. {
  144. unsigned short j;
  145. sprintf(szDest,
  146. "%02x %02x %02x %02x %02x %02x %02x %02x:"\
  147. "%02x %02x %02x %02x %02x %02x %02x %02x ",
  148. szSource[0],
  149. szSource[1],
  150. szSource[2],
  151. szSource[3],
  152. szSource[4],
  153. szSource[5],
  154. szSource[6],
  155. szSource[7],
  156. szSource[8],
  157. szSource[9],
  158. szSource[10],
  159. szSource[11],
  160. szSource[12],
  161. szSource[13],
  162. szSource[14],
  163. szSource[15]);
  164. // replace bytes with undesirable Sprintf side effects with SPACE
  165. for (j = 0; j < 16; j++)
  166. {
  167. if ((0x00 == szSource[j]) ||
  168. (0x07 == szSource[j]) ||
  169. (0x09 == szSource[j]) ||
  170. (0x0a == szSource[j]) ||
  171. (0x0d == szSource[j]) ||
  172. (0x1a == szSource[j]))
  173. szSource[j] = 0x20;
  174. }
  175. sprintf(szDest + strlen(szDest),
  176. "%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c%c",
  177. szSource[0],
  178. szSource[1],
  179. szSource[2],
  180. szSource[3],
  181. szSource[4],
  182. szSource[5],
  183. szSource[6],
  184. szSource[7],
  185. szSource[8],
  186. szSource[9],
  187. szSource[10],
  188. szSource[11],
  189. szSource[12],
  190. szSource[13],
  191. szSource[14],
  192. szSource[15]);
  193. return;
  194. }
  195. /******************************************************************************
  196. BOOL GetFinalWindow(HANDLE, LPRECT, LPSTR, LPSTR)
  197. Retrieve the last window size & location from a private INI
  198. Parameters: handle to current instance,
  199. long pointer to a rectangle with window size/shape,
  200. string with INI filename,
  201. string with Section name
  202. Returns: success/failure (never fails)
  203. Get display size in pixels and private INI saved width and height.
  204. Default width (for no previous INI) is 1/3 display width.
  205. Default height (for no previous INI) is 1/3 display height.
  206. If saved size or postion would put part or all the window
  207. off the desktop, first change the position then the size until
  208. the window is completely on the desktop.
  209. ******************************************************************************/
  210. BOOL GetFinalWindow (HANDLE hInst,
  211. LPRECT lprRect,
  212. LPSTR lpzINI,
  213. LPSTR lpzSection)
  214. {
  215. int x, nDisplayWidth, nDisplayHeight;
  216. RECT rect;
  217. nDisplayWidth = GetSystemMetrics(SM_CXSCREEN);
  218. nDisplayHeight = GetSystemMetrics(SM_CYSCREEN);
  219. rect.left = GetPrivateProfileInt(lpzSection, "Left",
  220. (nDisplayWidth/10) * 7,lpzINI);
  221. rect.top = GetPrivateProfileInt(lpzSection, "Top",
  222. (nDisplayHeight/10) * 8,lpzINI);
  223. rect.right = GetPrivateProfileInt(lpzSection, "Right",
  224. nDisplayWidth,lpzINI);
  225. rect.bottom = GetPrivateProfileInt(lpzSection, "Bottom",
  226. nDisplayHeight,lpzINI);
  227. /*/////////////////////////////////////////////////////////////////////////////
  228. if window hangs off top or left of display, change location to
  229. edge of display and preserve size.
  230. /////////////////////////////////////////////////////////////////////////////*/
  231. if (rect.top < 0)
  232. {
  233. rect.bottom += rect.top * -1;
  234. rect.top = 0;
  235. }
  236. if (rect.left < 0)
  237. {
  238. rect.right += rect.left * -1;
  239. rect.left = 0;
  240. }
  241. /*/////////////////////////////////////////////////////////////////////////////
  242. if window hangs off bottom or right of display, change location
  243. to bring it back onscreen. If window dimension is greater than
  244. display, reduce to size of display.
  245. /////////////////////////////////////////////////////////////////////////////*/
  246. if (rect.bottom > nDisplayHeight)
  247. {
  248. if (rect.bottom > nDisplayHeight * 2)
  249. {
  250. rect.top = 0;
  251. rect.bottom = nDisplayHeight;
  252. }
  253. else
  254. {
  255. x = rect.bottom - nDisplayHeight;
  256. rect.bottom -= x;
  257. rect.top -= x;
  258. }
  259. }
  260. if (rect.right > nDisplayWidth)
  261. {
  262. if (rect.right > nDisplayWidth * 2)
  263. {
  264. rect.left = 0;
  265. rect.right = nDisplayWidth;
  266. }
  267. else
  268. {
  269. x = rect.right - nDisplayWidth;
  270. rect.right -= x;
  271. rect.left -= x;
  272. }
  273. }
  274. /*/////////////////////////////////////////////////////////////////////////////
  275. GetWindowRect() returns a rect where right and bottom are absolute
  276. (measured from 0,0 of display). However, CreateWindow requires
  277. right and bottom to be relative (measured from 0,0 of the window
  278. to be created). SaveFinalWindow saves an absolute rect, and
  279. GetFinalRect converts these to relative measurements.
  280. /////////////////////////////////////////////////////////////////////////////*/
  281. SetRect(lprRect,
  282. rect.left,
  283. rect.top,
  284. rect.right - rect.left,
  285. rect.bottom - rect.top);
  286. return (TRUE);
  287. }
  288. /******************************************************************************
  289. BOOL LastError(BOOL)
  290. Calls GetLastError and displays result in a nice string
  291. Parameters: bNewOnly == TRUE if you only want changed error displayed
  292. Returns: TRUE if it found an error, else FALSE
  293. ******************************************************************************/
  294. BOOL LastError(BOOL bNewOnly)
  295. {
  296. static DWORD dwLast = 0;
  297. DWORD dwError;
  298. if (dwError = GetLastError())
  299. {
  300. // if user asked for only new errors
  301. if (bNewOnly)
  302. {
  303. // not a new error
  304. if (dwLast == dwError)
  305. return FALSE;
  306. // new error, save it
  307. dwLast = dwError;
  308. }
  309. DisplayOutput("*GetLastError %xh %d \"%s\"",
  310. dwError,dwError,StrFromTable(dwError,StWinerror));
  311. return (TRUE);
  312. }
  313. return (FALSE);
  314. }
  315. /******************************************************************************
  316. int NextToken(char *pDest,char *pSrc)
  317. Return next token from a command line string.
  318. ******************************************************************************/
  319. int NextToken(char *pDest,char *pSrc)
  320. {
  321. char *pA,*pB;
  322. int x;
  323. // point pArg to start of token in string pSrc
  324. for (pA = pSrc;*pA && isspace((int) *pA);pA++)
  325. ;
  326. // find end of token in string pSrc
  327. for (pB = pA;((*pB) && (! isspace((int) *pB)));pB++)
  328. ;
  329. // count of chars to next token or end of string
  330. x = (min((pB - pA),(int) strlen(pSrc))) + 1;
  331. // pszDest now contains the arg
  332. lstrcpyn(pDest,pA,x);
  333. // return sizeof token
  334. return (x);
  335. }
  336. /******************************************************************************
  337. BOOL SaveFinalWindow(HANDLE, HWND, LPSTR, LPSTR)
  338. Save the current window size & location to a private INI
  339. Parameters: handle to current instance,
  340. handle to current window,
  341. string with INI filename,
  342. string with Section name
  343. Returns: success/failure (fails if window is MIN or MAX)
  344. ******************************************************************************/
  345. BOOL SaveFinalWindow (HANDLE hInst,
  346. HWND hWnd,
  347. LPSTR lpzINI,
  348. LPSTR lpzSection)
  349. {
  350. PSTR pszValue;
  351. RECT rectWnd, rectINI;
  352. // if the window is minimized OR maximised, don't save anything
  353. if (IsIconic(hWnd) || IsZoomed(hWnd))
  354. return (FALSE);
  355. GetWindowRect (hWnd, &rectWnd);
  356. // get INI data. If there isn't any, we'll get the default and
  357. // save the current Window data.
  358. rectINI.left = GetPrivateProfileInt(lpzSection, "Left", 0, lpzINI);
  359. rectINI.top = GetPrivateProfileInt(lpzSection, "Top", 0, lpzINI);
  360. rectINI.right = GetPrivateProfileInt(lpzSection, "Right", 0, lpzINI);
  361. rectINI.bottom = GetPrivateProfileInt(lpzSection, "Bottom", 0, lpzINI);
  362. // if current window is same as in INI, don't change INI
  363. if ( rectINI.left == rectWnd.left &&
  364. rectINI.top == rectWnd.top &&
  365. rectINI.right == rectWnd.right &&
  366. rectINI.bottom == rectWnd.bottom)
  367. return (TRUE);
  368. // EXIT if we can't local alloc our string stuffer
  369. if ((pszValue = (PSTR) LocalAlloc(LPTR, 80)) == NULL)
  370. return (FALSE);
  371. // it's different, so save
  372. sprintf(pszValue, "%d", rectWnd.left);
  373. WritePrivateProfileString(lpzSection, "Left", pszValue, lpzINI);
  374. sprintf(pszValue, "%d", rectWnd.top);
  375. WritePrivateProfileString(lpzSection, "Top", pszValue, lpzINI);
  376. sprintf(pszValue, "%d", rectWnd.right);
  377. WritePrivateProfileString(lpzSection, "Right", pszValue, lpzINI);
  378. sprintf(pszValue, "%d", rectWnd.bottom);
  379. WritePrivateProfileString(lpzSection, "Bottom", pszValue, lpzINI);
  380. LocalFree((HANDLE) pszValue);
  381. return (TRUE);
  382. }
  383. /******************************************************************************
  384. char * StrFromTable(long number,PSTRINGTABLE pstrTable)
  385. Return string associated with a value from a string table.
  386. ******************************************************************************/
  387. char * StrFromTable(long number,PSTRINGTABLE pstrTable)
  388. {
  389. for (;pstrTable->end != -1;pstrTable++)
  390. {
  391. if (number == pstrTable->number)
  392. break;
  393. }
  394. return (pstrTable->szString);
  395. }
  396. /******************************************************************************
  397. BOOL Wait32(DWORD)
  398. wait DWORD milliseconds, then return
  399. ******************************************************************************/
  400. BOOL Wait32(DWORD dwTime)
  401. {
  402. DWORD dwNewTime,
  403. dwOldTime;
  404. // wait dwTime, then exit
  405. dwOldTime = GetCurrentTime();
  406. while (TRUE)
  407. {
  408. dwNewTime = GetCurrentTime();
  409. if (dwNewTime > dwOldTime + dwTime)
  410. break;
  411. }
  412. return (0);
  413. }