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.

455 lines
17 KiB

  1. /**************************************************************************/
  2. /*** SCICALC Scientific Calculator for Windows 3.00.12 ***/
  3. /*** By Kraig Brockschmidt, Microsoft Co-op, Contractor, 1988-1989 ***/
  4. /*** (c)1989 Microsoft Corporation. All Rights Reserved. ***/
  5. /*** ***/
  6. /*** scistat.c ***/
  7. /*** ***/
  8. /*** Functions contained: ***/
  9. /*** SetStat--Enable/disable the stat box, show or destroy the ***/
  10. /*** modeless dialog box. ***/
  11. /*** StatBoxProc--procedure for the statbox. Handles the RET, LOAD, ***/
  12. /*** CD, and CAD buttons, and handles double-clicks. ***/
  13. /*** StatFunctions--routines for DATA, SUM, AVE, and deviations. ***/
  14. /*** ***/
  15. /*** Functions called: ***/
  16. /*** SetStat ***/
  17. /*** ***/
  18. /*** Last modification Thu 26-Jan-1990 ***/
  19. /*** -by- Amit Chatterjee [amitc] 26-Jan-1990. ***/
  20. /*** Following bug fix was made: ***/
  21. /*** ***/
  22. /*** Bug # 8499. ***/
  23. /*** While fixing numbers in the stat array in memory, instead of using ***/
  24. /*** the following for statement: ***/
  25. /*** for (lIndex=lData; lIndex < lStatNum - 1 ; lIndex++) ***/
  26. /*** the fix was to use: ***/
  27. /*** for (lIndex=lData; lIndex < lStatNum ; lIndex++) ***/
  28. /*** This is because lStatNum has already been decremented to care of ***/
  29. /*** a number being deleted. ***/
  30. /*** This fix will be in build 1.59. ***/
  31. /**************************************************************************/
  32. #include "scicalc.h"
  33. #include "calchelp.h"
  34. #include "unifunc.h"
  35. #define GMEMCHUNK 96L /* Amount of memory to allocate at a time. */
  36. extern HNUMOBJ ghnoNum;
  37. extern HWND hStatBox, hListBox, hEdit;
  38. extern TCHAR szBlank[6], *rgpsz[CSTRINGS];
  39. extern LPTSTR gpszNum;
  40. extern int gcchNum;
  41. extern INT nTempCom;
  42. extern BOOL gbRecord;
  43. extern BOOL FireUpPopupMenu( HWND, HINSTANCE, LPARAM );
  44. GLOBALHANDLE hgMem, hMem; /* Coupla global memory handles. */
  45. BOOL bFocus=TRUE;
  46. LONG lStatNum=0, /* Number of data. */
  47. lReAllocCount; /* Number of data before ReAlloc. */
  48. HNUMOBJ * lphnoStatNum; /* Holding place for stat data. */
  49. /* Initiate or destroy the Statistics Box. */
  50. VOID APIENTRY SetStat (BOOL bOnOff)
  51. {
  52. static int aStatOnlyKeys[] = { IDC_AVE, IDC_B_SUM, IDC_DEV, IDC_DATA };
  53. int i;
  54. if (bOnOff)
  55. {
  56. /* Create. */
  57. lReAllocCount=GMEMCHUNK/sizeof(ghnoNum); /* Set up lReAllocCount. */
  58. /* Start the box. */
  59. hStatBox=CreateDialog(hInst, MAKEINTRESOURCE(IDD_SB), NULL, StatBoxProc);
  60. /* Get a handle on some memory (16 bytes initially. */
  61. if (!(hgMem=GlobalAlloc(GHND, 0L)))
  62. {
  63. StatError();
  64. SendMessage(hStatBox, WM_COMMAND, GET_WM_COMMAND_MPS(ENDBOX, 0, 0));
  65. return;
  66. }
  67. ShowWindow(hStatBox, SW_SHOWNORMAL);
  68. }
  69. else
  70. {
  71. int lIndex;
  72. if ( hStatBox )
  73. {
  74. DestroyWindow(hStatBox);
  75. // Free the numobj's
  76. lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
  77. for( lIndex = 0; lIndex < lStatNum; lIndex++ )
  78. NumObjDestroy( &lphnoStatNum[lIndex] );
  79. GlobalUnlock(hgMem);
  80. lStatNum = 0;
  81. GlobalFree(hgMem); /* Free up the memory. */
  82. hStatBox=0; /* Nullify handle. */
  83. }
  84. }
  85. // set the active state of the Ave, Sum, s, and Dat buttons
  86. for ( i=0; i<ARRAYSIZE(aStatOnlyKeys); i++)
  87. EnableWindow( GetDlgItem(g_hwndDlg, aStatOnlyKeys[i]), bOnOff );
  88. return;
  89. }
  90. /* Windows procedure for the Dialog Statistix Box. */
  91. INT_PTR FAR APIENTRY StatBoxProc (
  92. HWND hStatBox,
  93. UINT iMessage,
  94. WPARAM wParam,
  95. LPARAM lParam)
  96. {
  97. static LONG lData=-1; /* Data index in listbox. */
  98. LONG lIndex; /* Temp index for counting. */
  99. DWORD dwSize; /* Holding place for GlobalSize. */
  100. static DWORD control[] = {
  101. IDC_STATLIST, CALC_SCI_STATISTICS_VALUE,
  102. IDC_CAD, CALC_SCI_CAD,
  103. IDC_CD, CALC_SCI_CD,
  104. IDC_LOAD, CALC_SCI_LOAD,
  105. IDC_FOCUS, CALC_SCI_RET,
  106. IDC_NTEXT, CALC_SCI_NUMBER,
  107. IDC_NUMTEXT, CALC_SCI_NUMBER,
  108. 0, 0 };
  109. switch (iMessage)
  110. {
  111. case WM_HELP:
  112. {
  113. LPHELPINFO phi = (LPHELPINFO)lParam;
  114. HWND hwndChild = GetDlgItem(hStatBox,phi->iCtrlId);
  115. WinHelp( hwndChild, rgpsz[IDS_HELPFILE], HELP_WM_HELP, (ULONG_PTR)(void *)control );
  116. return TRUE;
  117. }
  118. case WM_CONTEXTMENU:
  119. WinHelp( (HWND)wParam, rgpsz[IDS_HELPFILE], HELP_CONTEXTMENU, (ULONG_PTR)(void *)control );
  120. return TRUE;
  121. case WM_CLOSE:
  122. SetStat(FALSE);
  123. case WM_DESTROY:
  124. lStatNum=0L; /* Reset data count. */
  125. return(TRUE);
  126. case WM_INITDIALOG:
  127. /* Get a handle to this here things listbox display. */
  128. hListBox=GetDlgItem(hStatBox, IDC_STATLIST);
  129. return TRUE;
  130. case WM_COMMAND:
  131. /* Check for LOAD or double-click and recall number if so. */
  132. if (GET_WM_COMMAND_CMD(wParam, lParam)==LBN_DBLCLK ||
  133. GET_WM_COMMAND_ID(wParam, lParam)==IDC_LOAD)
  134. {
  135. /* Lock data, get pointer to it, and get index of item. */
  136. lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
  137. lData=(LONG)SendMessage(hListBox,LB_GETCURSEL,0,0L);
  138. if (lStatNum>0 && lData !=LB_ERR)
  139. // SPEED: REVIEW: can we use a pointer instead of Assign?
  140. NumObjAssign( &ghnoNum, lphnoStatNum[lData]); /* Get the data. */
  141. else
  142. MessageBeep(0); /* Cannodo if no data nor selection. */
  143. // Cancel kbd input mode
  144. gbRecord = FALSE;
  145. DisplayNum ();
  146. nTempCom = 32;
  147. GlobalUnlock(hgMem); /* Let the memory move! */
  148. break;
  149. }
  150. // switch (wParam)
  151. switch (GET_WM_COMMAND_ID(wParam, lParam))
  152. {
  153. case IDC_FOCUS:
  154. /* Change focus back to main window. Primarily for */
  155. /* use with the keyboard. */
  156. SetFocus(g_hwndDlg);
  157. return (TRUE);
  158. case IDC_CD:
  159. /* Clear the selected item from the listbox. */
  160. /* Get the index and a pointer to the data. */
  161. lData=(LONG)SendMessage(hListBox,LB_GETCURSEL,0,0L);
  162. /* Check for possible error conditions. */
  163. if (lData==LB_ERR || lData > lStatNum-1 || lStatNum==0)
  164. {
  165. MessageBeep (0);
  166. break;
  167. }
  168. /* Fix listbox strings. */
  169. lIndex=(LONG)SendMessage(hListBox, LB_DELETESTRING, (WORD)lData, 0L);
  170. if ((--lStatNum)==0)
  171. goto ClearItAll;
  172. /* Place the highlight over the next one. */
  173. if (lData<lIndex || lIndex==0)
  174. lIndex=lData+1;
  175. SendMessage(hListBox, LB_SETCURSEL, (WORD)lIndex-1, 0L);
  176. lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
  177. /* Fix numbers in memory. */
  178. for (lIndex=lData; lIndex < lStatNum ; lIndex++)
  179. {
  180. NumObjAssign( &lphnoStatNum[lIndex], lphnoStatNum[lIndex+1] );
  181. }
  182. GlobalUnlock(hgMem); /* Movin' again. */
  183. /* Update the number by the "n=". */
  184. SetDlgItemInt(hStatBox, IDC_NUMTEXT, lStatNum, FALSE);
  185. dwSize=(DWORD)GlobalSize(hgMem); /* Get size of memory block.*/
  186. /* Unallocate memory if not needed after data removal.*/
  187. /* hMem is used so we don't possibly trach hgMem. */
  188. if ((lStatNum % lReAllocCount)==0)
  189. if ((hMem=GlobalReAlloc(hgMem, dwSize-GMEMCHUNK, GMEM_ZEROINIT)))
  190. hgMem=hMem;
  191. return(TRUE);
  192. case IDC_CAD:
  193. ClearItAll:
  194. /* Nuke it all! */
  195. SendMessage(hListBox, LB_RESETCONTENT, 0L, 0L);
  196. SetDlgItemInt(hStatBox, IDC_NUMTEXT, 0, FALSE);;
  197. // Free the numobj's
  198. lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
  199. for( lIndex = 0; lIndex < lStatNum; lIndex++ )
  200. NumObjDestroy( &lphnoStatNum[lIndex] );
  201. GlobalUnlock(hgMem);
  202. GlobalFree(hgMem); /* Drop the memory. */
  203. lStatNum = 0;
  204. hgMem=GlobalAlloc(GHND, 0L); /* Get a CLEAN slate. */
  205. return(TRUE);
  206. }
  207. }
  208. return (FALSE);
  209. }
  210. /* Routine for functions AVE, SUM, DEV, and DATA. */
  211. VOID APIENTRY StatFunctions (WPARAM wParam)
  212. {
  213. LONG lIndex; /* Temp index. */
  214. DWORD dwSize; /* Return value for GlobalSize. */
  215. switch (wParam)
  216. {
  217. case IDC_DATA: /* Add current fpNum to listbox. */
  218. if ((lStatNum % lReAllocCount)==0)
  219. {
  220. /* If needed, allocate another 96 bytes. */
  221. dwSize=(DWORD)GlobalSize(hgMem);
  222. if (StatAlloc (1, dwSize))
  223. {
  224. GlobalCompact((DWORD)-1L);
  225. if (StatAlloc (1, dwSize))
  226. {
  227. StatError ();
  228. return;
  229. }
  230. }
  231. hgMem=hMem;
  232. }
  233. /* Add the display string to the listbox. */
  234. hListBox=GetDlgItem(hStatBox, IDC_STATLIST);
  235. lIndex=StatAlloc (2,0L);
  236. if (lIndex==LB_ERR || lIndex==LB_ERRSPACE)
  237. {
  238. GlobalCompact((DWORD)-1L);
  239. lIndex=StatAlloc (2,0L);
  240. if (lIndex==LB_ERR || lIndex==LB_ERRSPACE)
  241. {
  242. StatError ();
  243. return;
  244. }
  245. }
  246. /* Highlight last entered string. */
  247. SendMessage(hListBox, LB_SETCURSEL, (WORD)lIndex, 0L);
  248. /* Add the number and increase the "n=" value. */
  249. lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
  250. NumObjAssign( &lphnoStatNum[lStatNum], ghnoNum );
  251. SetDlgItemInt(hStatBox, IDC_NUMTEXT, ++lStatNum, FALSE);
  252. break;
  253. case IDC_AVE: /* Calculate averages and sums. */
  254. case IDC_B_SUM: {
  255. DECLARE_HNUMOBJ( hnoTemp );
  256. lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
  257. /* Sum the numbers or squares, depending on bInv. */
  258. NumObjAssign( &ghnoNum, HNO_ZERO );
  259. for (lIndex=0L; lIndex < lStatNum; lIndex++)
  260. {
  261. NumObjAssign( &hnoTemp, lphnoStatNum[lIndex] );
  262. if (bInv)
  263. {
  264. DECLARE_HNUMOBJ( hno );
  265. /* Get sum of squares. */
  266. NumObjAssign( &hno, hnoTemp );
  267. mulrat( &hno, hnoTemp );
  268. addrat( &ghnoNum, hno );
  269. NumObjDestroy( &hno );
  270. }
  271. else
  272. {
  273. /* Get sum. */
  274. addrat( &ghnoNum, hnoTemp );
  275. }
  276. }
  277. if (wParam==IDC_AVE) /* Divide by lStatNum=# of items for mean. */
  278. {
  279. DECLARE_HNUMOBJ( hno );
  280. if (lStatNum==0)
  281. {
  282. DisplayError (SCERR_DIVIDEZERO);
  283. break;
  284. }
  285. NumObjSetIntValue( &hno, lStatNum );
  286. divrat( &ghnoNum, hno );
  287. NumObjDestroy( &hno );
  288. }
  289. NumObjDestroy( &hnoTemp );
  290. /* Fall out for sums. */
  291. break;
  292. }
  293. case IDC_DEV: { /* Calculate deviations. */
  294. DECLARE_HNUMOBJ(hnoTemp);
  295. DECLARE_HNUMOBJ(hnoX);
  296. DECLARE_HNUMOBJ( hno );
  297. if (lStatNum <=1) /* 1 item or less, NO deviation. */
  298. {
  299. NumObjAssign( &ghnoNum, HNO_ZERO );
  300. return;
  301. }
  302. /* Get sum and sum of squares. */
  303. lphnoStatNum=(HNUMOBJ *)GlobalLock(hgMem);
  304. NumObjAssign( &ghnoNum, HNO_ZERO );
  305. NumObjAssign( &hnoTemp, HNO_ZERO );
  306. for (lIndex=0L; lIndex < lStatNum; lIndex++)
  307. {
  308. NumObjAssign(&hnoX, lphnoStatNum[lIndex]);
  309. addrat( &hnoTemp, hnoX );
  310. NumObjAssign( &hno, hnoX );
  311. mulrat( &hno, hnoX );
  312. addrat( &ghnoNum, hno );
  313. }
  314. /* x�- nx�/n� */
  315. /* fpTemp=fpNum-(fpTemp*fpTemp/(double)lStatNum);*/
  316. /* */
  317. NumObjSetIntValue( &hno, lStatNum );
  318. NumObjAssign( &hnoX, hnoTemp );
  319. mulrat( &hnoX, hnoTemp );
  320. divrat( &hnoX, hno );
  321. NumObjAssign( &hnoTemp, ghnoNum );
  322. subrat( &hnoTemp, hnoX );
  323. /* All numbers are identical if fpTemp==0 */
  324. if (NumObjIsZero( hnoTemp))
  325. NumObjAssign( &ghnoNum, HNO_ZERO); /* No deviation. */
  326. else {
  327. /* If bInv=TRUE, divide by n (number of data) otherwise */
  328. /* divide by n-1. */
  329. /* fpNum=sqrt(fpTemp/(lStatNum-1+(LONG)bInv)); */
  330. //
  331. // hno still equals lStatNum
  332. if (!bInv) {
  333. subrat( &hno, HNO_ONE );
  334. }
  335. divrat( &hnoTemp, hno );
  336. rootrat( &hnoTemp, HNO_TWO );
  337. NumObjAssign( &ghnoNum, hnoTemp );
  338. }
  339. NumObjDestroy( &hno );
  340. NumObjDestroy( &hnoX );
  341. NumObjDestroy( &hnoTemp );
  342. break;
  343. }
  344. }
  345. GlobalUnlock(hgMem); /* Da memwry is fwee to move as Findows fishes. */
  346. return;
  347. }
  348. LONG NEAR StatAlloc (WORD wType, DWORD dwSize)
  349. {
  350. LONG lRet=FALSE;
  351. if (wType==1)
  352. {
  353. if ((hMem=GlobalReAlloc(hgMem, dwSize+GMEMCHUNK, GMEM_ZEROINIT)))
  354. return 0L;
  355. }
  356. else
  357. {
  358. lRet=(LONG)SendMessage(hListBox, LB_ADDSTRING, 0, (LONG_PTR)(LPTSTR)gpszNum);
  359. return lRet;
  360. }
  361. return 1L;
  362. }
  363. VOID NEAR StatError (VOID)
  364. {
  365. TCHAR szFoo[50]; /* This comes locally. Gets the Stat Box Caption. */
  366. MessageBeep(0);
  367. /* Error if out of room. */
  368. GetWindowText(hStatBox, szFoo, 49);
  369. MessageBox(hStatBox, rgpsz[IDS_STATMEM], szFoo, MB_OK);
  370. return;
  371. }