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.

3440 lines
92 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 1995-1998 Microsoft Corporation
  3. Module Name:
  4. espexe.c
  5. Abstract:
  6. Author:
  7. Dan Knudson (DanKn) 15-Sep-1995
  8. Revision History:
  9. --*/
  10. #include "espexe.h"
  11. typedef LONG (WINAPI *TAPIPROC)();
  12. int
  13. WINAPI
  14. WinMain(
  15. HINSTANCE hInstance,
  16. HINSTANCE hPrevInstance,
  17. LPSTR lpCmdLine,
  18. int nCmdShow
  19. )
  20. {
  21. MSG msg;
  22. HACCEL hAccel;
  23. ghInstance = hInstance;
  24. ghwndMain = CreateDialog(
  25. ghInstance,
  26. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG1),
  27. (HWND)NULL,
  28. MainWndProc
  29. );
  30. if (!ghwndMain)
  31. {
  32. }
  33. hAccel = LoadAccelerators(
  34. ghInstance,
  35. (LPCSTR)MAKEINTRESOURCE(IDR_ACCELERATOR1)
  36. );
  37. while (GetMessage (&msg, (HWND) NULL, 0, 0))
  38. {
  39. if (!hAccel || !TranslateAccelerator (ghwndMain, hAccel, &msg))
  40. {
  41. TranslateMessage (&msg);
  42. DispatchMessage (&msg);
  43. }
  44. }
  45. DestroyWindow (ghwndMain);
  46. DestroyAcceleratorTable (hAccel);
  47. return 0;
  48. }
  49. void
  50. ESPServiceThread(
  51. LPVOID pParams
  52. )
  53. {
  54. HANDLE hInitEvent;
  55. ShowStr ("ESPServiceThread: enter");
  56. hInitEvent = CreateEvent(
  57. (LPSECURITY_ATTRIBUTES) NULL,
  58. FALSE, // auto-reset
  59. FALSE, // non-signaled
  60. "ESPevent"
  61. );
  62. while (1)
  63. {
  64. HANDLE ahEvents[3];
  65. wait_for_esp_to_init:
  66. gbESPLoaded = FALSE;
  67. EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON1), FALSE);
  68. EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON2), FALSE);
  69. //
  70. //
  71. //
  72. {
  73. DWORD dwUsedSize;
  74. RPC_STATUS status;
  75. #define CNLEN 25 // computer name length
  76. #define UNCLEN CNLEN+2 // \\computername
  77. #define PATHLEN 260 // Path
  78. #define MAXPROTSEQ 20 // protocol sequence "ncacn_np"
  79. unsigned char pszNetworkAddress[UNCLEN+1];
  80. unsigned char * pszUuid = NULL;
  81. unsigned char * pszOptions = NULL;
  82. unsigned char * pszStringBinding = NULL;
  83. pszNetworkAddress[0] = '\0';
  84. status = RpcStringBindingCompose(
  85. pszUuid,
  86. "ncalrpc",
  87. pszNetworkAddress,
  88. "esplpc",
  89. pszOptions,
  90. &pszStringBinding
  91. );
  92. if (status)
  93. {
  94. ShowStr(
  95. "RpcStringBindingCompose failed: err=%d, szNetAddr='%s'",
  96. status,
  97. pszNetworkAddress
  98. );
  99. }
  100. else
  101. {
  102. status = RpcBindingFromStringBinding(
  103. pszStringBinding,
  104. &hEsp
  105. );
  106. if (status)
  107. {
  108. ShowStr(
  109. "RpcBindingFromStringBinding failed, err=%d, szBinding='%s'",
  110. status,
  111. pszStringBinding
  112. );
  113. }
  114. }
  115. RpcStringFree (&pszStringBinding);
  116. }
  117. ShowStr ("ESPServiceThread: waiting for esp init event");
  118. WaitForSingleObject (hInitEvent, INFINITE);
  119. RpcTryExcept
  120. {
  121. ESPAttach(
  122. (long) GetCurrentProcessId(),
  123. (ULONG_PTR *) ahEvents, // &hShutdownEvent
  124. (ULONG_PTR *) ahEvents + 1, // &hDebugOutputEvent
  125. (ULONG_PTR *) ahEvents + 2 // &hWidgetEventsEvent
  126. );
  127. }
  128. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  129. {
  130. ShowStr ("ESPServiceThread: esp init event signaled, EXCEPTION while trying to attach to esp");
  131. continue;
  132. }
  133. RpcEndExcept
  134. gbESPLoaded = TRUE;
  135. UpdateESPOptions();
  136. gbPBXThreadRunning = FALSE;
  137. EnableMenuItem (ghMenu, IDM_PBXSTART, MF_BYCOMMAND | MF_ENABLED);
  138. ShowStr ("ESPServiceThread: esp init event signaled, attached to esp");
  139. gpWidgets = NULL;
  140. EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON1), TRUE);
  141. EnableWindow (GetDlgItem (ghwndMain, IDC_BUTTON2), TRUE);
  142. //
  143. //
  144. //
  145. {
  146. DWORD dwBufSize = 50 * sizeof (WIDGETEVENT);
  147. char *buf = MyAlloc (dwBufSize);
  148. // fix for bug 57370
  149. if (!buf) break;
  150. while (1)
  151. {
  152. switch (WaitForMultipleObjects (3, ahEvents, FALSE, INFINITE))
  153. {
  154. case WAIT_OBJECT_0+1:
  155. {
  156. DWORD dwSize;
  157. get_debug_output:
  158. dwSize = dwBufSize - 1;
  159. RpcTryExcept
  160. {
  161. ESPGetDebugOutput (buf, &dwSize);
  162. }
  163. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  164. {
  165. ShowStr ("ESPServiceThread: EXCEPTION while calling ESPGetDebugOutput()");
  166. break;
  167. }
  168. RpcEndExcept
  169. buf[dwSize] = 0;
  170. xxxShowStr (buf);
  171. if (dwSize == (dwBufSize - 1))
  172. {
  173. char *newBuf;
  174. if ((newBuf = MyAlloc (2*dwBufSize)))
  175. {
  176. MyFree (buf);
  177. buf = newBuf;
  178. dwBufSize *= 2;
  179. }
  180. goto get_debug_output;
  181. }
  182. break;
  183. }
  184. case WAIT_OBJECT_0+2:
  185. {
  186. DWORD dwSize, i, dwNumEvents;
  187. PWIDGETEVENT pEvent;
  188. get_widget_events:
  189. dwSize = dwBufSize;
  190. RpcTryExcept
  191. {
  192. ESPGetWidgetEvents (buf, &dwSize);
  193. }
  194. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  195. {
  196. ShowStr ("ESPServiceThread: EXCEPTION while calling ESPGetWidgetEvents()");
  197. break;
  198. }
  199. RpcEndExcept
  200. dwNumEvents = dwSize / sizeof (WIDGETEVENT);
  201. pEvent = (PWIDGETEVENT) buf;
  202. for (i = 0; i < dwNumEvents; i++)
  203. {
  204. ProcessWidgetEvent (pEvent++);
  205. }
  206. if (dwSize == dwBufSize)
  207. {
  208. goto get_widget_events;
  209. }
  210. break;
  211. }
  212. default:
  213. RpcBindingFree (&hEsp);
  214. SaveIniFileSettings();
  215. CloseHandle (ahEvents[0]);
  216. CloseHandle (ahEvents[1]);
  217. CloseHandle (ahEvents[2]);
  218. MyFree (buf);
  219. SendMessage (ghwndList1, LB_RESETCONTENT, 0, 0);
  220. while (gpWidgets)
  221. {
  222. PMYWIDGET pNextWidget = gpWidgets->pNext;
  223. MyFree (gpWidgets);
  224. gpWidgets = pNextWidget;
  225. }
  226. // BUGBUG disable lots of menuitems, etc.
  227. EnableMenuItem(
  228. ghMenu,
  229. IDM_PBXSTART,
  230. MF_BYCOMMAND | MF_GRAYED
  231. );
  232. EnableMenuItem(
  233. ghMenu,
  234. IDM_PBXSTOP,
  235. MF_BYCOMMAND | MF_GRAYED
  236. );
  237. if (gbAutoClose)
  238. {
  239. gbESPLoaded = FALSE;
  240. PostMessage (ghwndMain, WM_CLOSE, 0, 0);
  241. goto ESPServiceThread_exit;
  242. }
  243. goto wait_for_esp_to_init;
  244. } // switch (WaitForMultipleObjects (...))
  245. } // while (1)
  246. }
  247. } // while (1)
  248. ESPServiceThread_exit:
  249. CloseHandle (hInitEvent);
  250. ExitThread (0);
  251. }
  252. INT_PTR
  253. CALLBACK
  254. MainWndProc(
  255. HWND hwnd,
  256. UINT msg,
  257. WPARAM wParam,
  258. LPARAM lParam
  259. )
  260. {
  261. static int icyButton, icyBorder, cyWnd;
  262. static BOOL bCaptured = FALSE;
  263. static LONG xCapture, cxVScroll;
  264. static HFONT hFont;
  265. static HICON hIcon;
  266. switch (msg)
  267. {
  268. case WM_INITDIALOG:
  269. {
  270. char buf[64];
  271. RECT rect;
  272. //
  273. // Init some globals
  274. //
  275. hIcon = LoadIcon (ghInstance, MAKEINTRESOURCE(IDI_ICON1));
  276. ghwndMain = hwnd;
  277. ghwndList1 = GetDlgItem (hwnd, IDC_LIST1);
  278. ghwndList2 = GetDlgItem (hwnd, IDC_LIST2);
  279. ghwndEdit = GetDlgItem (hwnd, IDC_EDIT1);
  280. ghMenu = GetMenu (hwnd);
  281. icyBorder = GetSystemMetrics (SM_CYFRAME);
  282. GetWindowRect (GetDlgItem (hwnd, IDC_BUTTON1), &rect);
  283. icyButton = (rect.bottom - rect.top) + icyBorder + 3;
  284. cxVScroll = 2*GetSystemMetrics (SM_CXVSCROLL);
  285. gbPBXThreadRunning = FALSE;
  286. EnableMenuItem (ghMenu, IDM_PBXSTART, MF_BYCOMMAND | MF_GRAYED);
  287. EnableMenuItem (ghMenu, IDM_PBXSTOP, MF_BYCOMMAND | MF_GRAYED);
  288. //
  289. //
  290. //
  291. {
  292. typedef struct _XXX
  293. {
  294. DWORD dwDefValue;
  295. LPCSTR pszValueName;
  296. LPDWORD pdwValue;
  297. } XXX, *PXXX;
  298. XXX axxx[] =
  299. {
  300. { DEF_SPI_VERSION, "TSPIVersion", &gdwTSPIVersion },
  301. { 0, "AutoClose", &gbAutoClose },
  302. { DEF_NUM_LINES, "NumLines", &gdwNumLines },
  303. { DEF_NUM_ADDRS_PER_LINE, "NumAddrsPerLine", &gdwNumAddrsPerLine },
  304. { DEF_NUM_CALLS_PER_ADDR, "NumCallsPerAddr", &gdwNumCallsPerAddr },
  305. { DEF_NUM_PHONES, "NumPhones", &gdwNumPhones },
  306. { DEF_DEBUG_OPTIONS, "DebugOutput", &gdwDebugOptions },
  307. { DEF_COMPLETION_MODE, "Completion", &gdwCompletionMode },
  308. { 0, "DisableUI", &gbDisableUI },
  309. { 1, "AutoGatherGenerateMsgs", &gbAutoGatherGenerateMsgs },
  310. { 0, NULL, NULL },
  311. };
  312. DWORD i;
  313. for (i = 0; axxx[i].pszValueName; i++)
  314. {
  315. *(axxx[i].pdwValue) = (DWORD) GetProfileInt(
  316. szMySection,
  317. axxx[i].pszValueName,
  318. (int) axxx[i].dwDefValue
  319. );
  320. }
  321. for (i = 0; i < 6; i++)
  322. {
  323. if (gdwDebugOptions & (0x1 << i))
  324. {
  325. CheckMenuItem(
  326. ghMenu,
  327. IDM_SHOWFUNCENTRY + i,
  328. MF_BYCOMMAND | MF_CHECKED
  329. );
  330. }
  331. }
  332. CheckMenuItem(
  333. ghMenu,
  334. IDM_SYNCCOMPL + gdwCompletionMode,
  335. MF_BYCOMMAND | MF_CHECKED
  336. );
  337. CheckMenuItem(
  338. ghMenu,
  339. IDM_AUTOCLOSE,
  340. MF_BYCOMMAND | (gbAutoClose ? MF_CHECKED : MF_UNCHECKED)
  341. );
  342. CheckMenuItem(
  343. ghMenu,
  344. IDM_AUTOGATHERGENERATEMSGS,
  345. MF_BYCOMMAND |
  346. (gbAutoGatherGenerateMsgs ? MF_CHECKED : MF_UNCHECKED)
  347. );
  348. CheckMenuItem(
  349. ghMenu,
  350. IDM_DISABLEUI,
  351. MF_BYCOMMAND | (gbDisableUI ? MF_CHECKED : MF_UNCHECKED)
  352. );
  353. }
  354. //
  355. // Set control fonts
  356. //
  357. {
  358. HWND hwndCtrl = GetDlgItem (hwnd, IDC_BUTTON1);
  359. hFont = CreateFont(
  360. 13, 5, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 34, "MS Sans Serif"
  361. );
  362. do
  363. {
  364. SendMessage(
  365. hwndCtrl,
  366. WM_SETFONT,
  367. (WPARAM) hFont,
  368. 0
  369. );
  370. } while ((hwndCtrl = GetNextWindow (hwndCtrl, GW_HWNDNEXT)));
  371. }
  372. //
  373. // Read in control size ratios
  374. //
  375. cxWnd = GetProfileInt (szMySection, "cxWnd", 100);
  376. cxList1 = GetProfileInt (szMySection, "cxList1", 25);
  377. //
  378. // Send self WM_SIZE to position child controls correctly
  379. //
  380. GetProfileString(
  381. szMySection,
  382. "Left",
  383. "0",
  384. buf,
  385. 63
  386. );
  387. if (strcmp (buf, "max") == 0)
  388. {
  389. ShowWindow (hwnd, SW_SHOWMAXIMIZED);
  390. }
  391. else if (strcmp (buf, "min") == 0)
  392. {
  393. ShowWindow (hwnd, SW_SHOWMINIMIZED);
  394. }
  395. else
  396. {
  397. int left, top, right, bottom;
  398. int cxScreen = GetSystemMetrics (SM_CXSCREEN);
  399. int cyScreen = GetSystemMetrics (SM_CYSCREEN);
  400. left = GetProfileInt (szMySection, "Left", 0);
  401. top = GetProfileInt (szMySection, "Top", 3*cyScreen/4);
  402. right = GetProfileInt (szMySection, "Right", cxScreen);
  403. bottom = GetProfileInt (szMySection, "Bottom", cyScreen);
  404. SetWindowPos(
  405. hwnd,
  406. HWND_TOP,
  407. left,
  408. top,
  409. right - left,
  410. bottom - top,
  411. SWP_SHOWWINDOW
  412. );
  413. GetClientRect (hwnd, &rect);
  414. SendMessage(
  415. hwnd,
  416. WM_SIZE,
  417. 0,
  418. MAKELONG((rect.right-rect.left),(rect.bottom-rect.top))
  419. );
  420. ShowWindow (hwnd, SW_SHOW);
  421. }
  422. //
  423. // Start the service thread
  424. //
  425. {
  426. DWORD dwThreadID;
  427. HANDLE hThread;
  428. hThread = CreateThread(
  429. (LPSECURITY_ATTRIBUTES) NULL,
  430. 0,
  431. (LPTHREAD_START_ROUTINE) ESPServiceThread,
  432. NULL,
  433. 0,
  434. &dwThreadID
  435. );
  436. SetThreadPriority (hThread, THREAD_PRIORITY_ABOVE_NORMAL);
  437. CloseHandle (hThread);
  438. }
  439. break;
  440. }
  441. case WM_COMMAND:
  442. {
  443. UINT uiCtrlID = (UINT) LOWORD(wParam);
  444. switch (uiCtrlID)
  445. {
  446. case IDM_INSTALL:
  447. case IDM_UNINSTALL:
  448. {
  449. BOOL bESPInstalled = FALSE;
  450. LONG lResult;
  451. DWORD i;
  452. TAPIPROC pfnLineGetProviderList, pfnLineAddProvider,
  453. pfnLineRemoveProvider;
  454. HINSTANCE hTapi32;
  455. LINEPROVIDERLIST providerList, *pProviderList;
  456. LPLINEPROVIDERENTRY pProviderEntry;
  457. if (!(hTapi32 = LoadLibrary ("tapi32.dll")))
  458. {
  459. ShowStr(
  460. "LoadLibrary(tapi32.dll) failed, err=%d",
  461. GetLastError()
  462. );
  463. break;
  464. }
  465. if (!(pfnLineAddProvider = (TAPIPROC) GetProcAddress(
  466. hTapi32,
  467. "lineAddProvider"
  468. )) ||
  469. !(pfnLineGetProviderList = (TAPIPROC) GetProcAddress(
  470. hTapi32,
  471. "lineGetProviderList"
  472. )) ||
  473. !(pfnLineRemoveProvider = (TAPIPROC) GetProcAddress(
  474. hTapi32,
  475. "lineRemoveProvider"
  476. )))
  477. {
  478. ShowStr(
  479. "GetProcAddr(tapi32,lineAddProvider) failed, err=%d",
  480. GetLastError()
  481. );
  482. goto install_free_tapi32;
  483. }
  484. providerList.dwTotalSize = sizeof (LINEPROVIDERLIST);
  485. if ((lResult = (*pfnLineGetProviderList)(0x20000, &providerList)))
  486. {
  487. ShowStr(
  488. "ESP (Un)Install: error, lineGetProviderList returned x%x",
  489. lResult
  490. );
  491. goto install_free_tapi32;
  492. }
  493. pProviderList = MyAlloc (providerList.dwNeededSize);
  494. pProviderList->dwTotalSize = providerList.dwNeededSize;
  495. if ((lResult = (*pfnLineGetProviderList)(0x20000, pProviderList)))
  496. {
  497. ShowStr(
  498. "ESP (Un)Install: error, lineGetProviderList returned x%x",
  499. lResult
  500. );
  501. goto install_free_provider_list;
  502. }
  503. pProviderEntry = (LPLINEPROVIDERENTRY) (((LPBYTE) pProviderList) +
  504. pProviderList->dwProviderListOffset);
  505. for (i = 0; i < pProviderList->dwNumProviders; i++)
  506. {
  507. int j;
  508. char *pszProviderName = (char *) (((LPBYTE) pProviderList) +
  509. pProviderEntry->dwProviderFilenameOffset);
  510. //
  511. // Convert the string to lower case, then see if it
  512. // contains "esp32.tsp"
  513. //
  514. for (j = 0; pszProviderName[j]; j++)
  515. {
  516. pszProviderName[j] |= 0x20;
  517. }
  518. if (strstr (pszProviderName, "esp32.tsp"))
  519. {
  520. bESPInstalled = TRUE;
  521. break;
  522. }
  523. pProviderEntry++;
  524. }
  525. if (uiCtrlID == IDM_INSTALL)
  526. {
  527. if (bESPInstalled)
  528. {
  529. ShowStr ("ESP Install: already installed");
  530. }
  531. else
  532. {
  533. DWORD dwPermanentProviderID;
  534. if ((lResult = (*pfnLineAddProvider)(
  535. "esp32.tsp",
  536. hwnd,
  537. &dwPermanentProviderID
  538. )) == 0)
  539. {
  540. ShowStr(
  541. "ESP Install: success, ProviderID=%d",
  542. dwPermanentProviderID
  543. );
  544. }
  545. else
  546. {
  547. ShowStr(
  548. "ESP Install: error, lineAddProvider returned x%x",
  549. lResult
  550. );
  551. }
  552. }
  553. }
  554. else // IDM_UNINSTALL
  555. {
  556. if (bESPInstalled)
  557. {
  558. if ((lResult = (*pfnLineRemoveProvider)(
  559. pProviderEntry->dwPermanentProviderID,
  560. hwnd
  561. )) == 0)
  562. {
  563. ShowStr ("ESP Uninstall: success");
  564. }
  565. else
  566. {
  567. ShowStr(
  568. "ESP Uninstall: error, lineRemoveProvider " \
  569. "returned x%x",
  570. lResult
  571. );
  572. }
  573. }
  574. else
  575. {
  576. ShowStr ("ESP Uninstall: not installed");
  577. }
  578. }
  579. install_free_provider_list:
  580. MyFree (pProviderList);
  581. install_free_tapi32:
  582. FreeLibrary (hTapi32);
  583. break;
  584. }
  585. case IDM_AUTOCLOSE:
  586. {
  587. gbAutoClose = (gbAutoClose ? FALSE : TRUE);
  588. CheckMenuItem(
  589. ghMenu,
  590. IDM_AUTOCLOSE,
  591. MF_BYCOMMAND | (gbAutoClose ? MF_CHECKED : MF_UNCHECKED)
  592. );
  593. SaveIniFileSettings();
  594. break;
  595. }
  596. case IDM_AUTOGATHERGENERATEMSGS:
  597. {
  598. gbAutoGatherGenerateMsgs =
  599. (gbAutoGatherGenerateMsgs ? FALSE : TRUE);
  600. CheckMenuItem(
  601. ghMenu,
  602. IDM_AUTOGATHERGENERATEMSGS,
  603. MF_BYCOMMAND |
  604. (gbAutoGatherGenerateMsgs ? MF_CHECKED : MF_UNCHECKED)
  605. );
  606. SaveIniFileSettings();
  607. break;
  608. }
  609. case IDM_DISABLEUI:
  610. {
  611. gbDisableUI = (gbDisableUI ? FALSE : TRUE);
  612. CheckMenuItem(
  613. ghMenu,
  614. IDM_DISABLEUI,
  615. MF_BYCOMMAND | (gbDisableUI ? MF_CHECKED : MF_UNCHECKED)
  616. );
  617. SaveIniFileSettings();
  618. break;
  619. }
  620. case IDM_DEFAULTS:
  621. {
  622. EVENT_PARAM params[] =
  623. {
  624. { "TSPI Version", PT_ORDINAL, gdwTSPIVersion, aVersions },
  625. { "Num lines", PT_DWORD, gdwNumLines, 0 },
  626. { "Num addrs per line", PT_DWORD, gdwNumAddrsPerLine, 0 },
  627. { "Num calls per addr", PT_DWORD, gdwNumCallsPerAddr, 0 },
  628. { "Num phones", PT_DWORD, gdwNumPhones, 0 },
  629. };
  630. EVENT_PARAM_HEADER paramsHeader =
  631. { 5, "Default values", 0, params };
  632. if (DialogBoxParam(
  633. ghInstance,
  634. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  635. hwnd,
  636. ValuesDlgProc,
  637. (LPARAM) &paramsHeader
  638. ) == IDOK)
  639. {
  640. char *aszValueNames[] =
  641. {
  642. "TSPIVersion",
  643. "NumLines",
  644. "NumAddrsPerLine",
  645. "NumCallsPerAddr",
  646. "NumPhones",
  647. NULL
  648. };
  649. LPDWORD lpdwValues[] =
  650. {
  651. &gdwTSPIVersion,
  652. &gdwNumLines,
  653. &gdwNumAddrsPerLine,
  654. &gdwNumCallsPerAddr,
  655. &gdwNumPhones
  656. };
  657. int i;
  658. BOOL bValuesChanged = FALSE;
  659. for (i = 0; aszValueNames[i]; i++)
  660. {
  661. char buf[16];
  662. if (*(lpdwValues[i]) != params[i].dwValue)
  663. {
  664. *(lpdwValues[i]) = (DWORD) params[i].dwValue;
  665. wsprintf (buf, "%d", params[i].dwValue);
  666. WriteProfileString(
  667. szMySection,
  668. aszValueNames[i],
  669. buf
  670. );
  671. bValuesChanged = TRUE;
  672. }
  673. }
  674. if (bValuesChanged && gbESPLoaded)
  675. {
  676. MessageBox(
  677. hwnd,
  678. "New values will not take effect until provider is" \
  679. " shutdown and reinitialized",
  680. "ESP Defaults",
  681. MB_OK
  682. );
  683. }
  684. }
  685. break;
  686. }
  687. case IDC_BUTTON1:
  688. {
  689. LRESULT lSel;
  690. EVENT_PARAM params[] =
  691. {
  692. { "htLine", PT_DWORD, 0, 0 },
  693. { "htCall", PT_DWORD, 0, 0 },
  694. { "dwMsg", PT_ORDINAL, 0, aLineMsgs },
  695. { "dwParam1", PT_DWORD, 0, 0 },
  696. { "dwParam2", PT_DWORD, 0, 0 },
  697. { "dwParam3", PT_DWORD, 0, 0 },
  698. };
  699. EVENT_PARAM_HEADER paramsHeader =
  700. { 6, "Line event", 0, params };
  701. lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0);
  702. if (lSel != LB_ERR)
  703. {
  704. PMYWIDGET pWidget;
  705. pWidget = (PMYWIDGET) SendMessage(
  706. ghwndList1,
  707. LB_GETITEMDATA,
  708. lSel,
  709. 0
  710. );
  711. if (pWidget->dwWidgetType == WIDGETTYPE_LINE)
  712. {
  713. params[0].dwValue =
  714. params[0].dwDefValue = pWidget->htXxx;
  715. }
  716. else if (pWidget->dwWidgetType == WIDGETTYPE_CALL)
  717. {
  718. params[1].dwValue =
  719. params[1].dwDefValue = pWidget->htXxx;
  720. do
  721. {
  722. pWidget = pWidget->pPrev;
  723. }
  724. while (pWidget->dwWidgetType != WIDGETTYPE_LINE);
  725. params[0].dwValue =
  726. params[0].dwDefValue = pWidget->htXxx;
  727. }
  728. }
  729. if (DialogBoxParam(
  730. ghInstance,
  731. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  732. hwnd,
  733. ValuesDlgProc,
  734. (LPARAM) &paramsHeader
  735. ) == IDOK)
  736. {
  737. ESPEvent(
  738. params[0].dwValue,
  739. params[1].dwValue,
  740. params[2].dwValue,
  741. params[3].dwValue,
  742. params[4].dwValue,
  743. params[5].dwValue
  744. );
  745. }
  746. break;
  747. }
  748. case IDC_BUTTON2:
  749. {
  750. LRESULT lSel;
  751. EVENT_PARAM params[] =
  752. {
  753. { "htPhone", PT_DWORD, 0, 0 },
  754. { "dwMsg", PT_ORDINAL, 0, aPhoneMsgs },
  755. { "dwParam1", PT_DWORD, 0, 0 },
  756. { "dwParam2", PT_DWORD, 0, 0 },
  757. { "dwParam3", PT_DWORD, 0, 0 },
  758. };
  759. EVENT_PARAM_HEADER paramsHeader =
  760. { 5, "Phone event", 0, params };
  761. lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0);
  762. if (lSel != LB_ERR)
  763. {
  764. PMYWIDGET pWidget;
  765. pWidget = (PMYWIDGET) SendMessage(
  766. ghwndList1,
  767. LB_GETITEMDATA,
  768. lSel,
  769. 0
  770. );
  771. if (pWidget->dwWidgetType == WIDGETTYPE_PHONE)
  772. {
  773. params[0].dwValue =
  774. params[0].dwDefValue = pWidget->htXxx;
  775. }
  776. }
  777. if (DialogBoxParam(
  778. ghInstance,
  779. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  780. hwnd,
  781. ValuesDlgProc,
  782. (LPARAM) &paramsHeader
  783. ) == IDOK)
  784. {
  785. ESPEvent(
  786. params[0].dwValue,
  787. 0,
  788. params[1].dwValue,
  789. params[2].dwValue,
  790. params[3].dwValue,
  791. params[4].dwValue
  792. );
  793. }
  794. break;
  795. }
  796. case IDC_ENTER:
  797. {
  798. HWND hwndFocus = GetFocus();
  799. if (hwndFocus == ghwndList1)
  800. {
  801. goto show_widget_dialog;
  802. }
  803. else if (hwndFocus == ghwndList2)
  804. {
  805. goto complete_pending_request;
  806. }
  807. break;
  808. }
  809. case IDC_LIST1:
  810. {
  811. if (HIWORD(wParam) == LBN_DBLCLK)
  812. {
  813. LRESULT lSel;
  814. show_widget_dialog:
  815. lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0);
  816. if (lSel != LB_ERR)
  817. {
  818. //
  819. // Determine the widget type, & put up the
  820. // appropriate properties dlg
  821. //
  822. PMYWIDGET pWidget;
  823. pWidget = (PMYWIDGET) SendMessage(
  824. ghwndList1,
  825. LB_GETITEMDATA,
  826. lSel,
  827. 0
  828. );
  829. switch (pWidget->dwWidgetType)
  830. {
  831. case WIDGETTYPE_LINE:
  832. {
  833. char szTitle[32];
  834. EVENT_PARAM params[] =
  835. {
  836. { "<under construction>", PT_DWORD, 0, 0 }
  837. };
  838. EVENT_PARAM_HEADER paramsHeader =
  839. { 1, szTitle, 0, params };
  840. wsprintf(
  841. szTitle,
  842. "Line%d properties",
  843. pWidget->dwWidgetID
  844. );
  845. if (DialogBoxParam(
  846. ghInstance,
  847. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  848. hwnd,
  849. ValuesDlgProc,
  850. (LPARAM) &paramsHeader
  851. ) == IDOK)
  852. {
  853. }
  854. break;
  855. }
  856. case WIDGETTYPE_CALL:
  857. {
  858. char szTitle[32];
  859. EVENT_PARAM params[] =
  860. {
  861. { "Call state", PT_ORDINAL, pWidget->dwCallState, aCallStates },
  862. { "Call state mode", PT_DWORD, 0, 0 }
  863. };
  864. EVENT_PARAM_HEADER paramsHeader =
  865. { 2, szTitle, 0, params };
  866. wsprintf(
  867. szTitle,
  868. "Call x%x properties",
  869. pWidget->hdXxx
  870. );
  871. if (DialogBoxParam(
  872. ghInstance,
  873. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  874. hwnd,
  875. ValuesDlgProc,
  876. (LPARAM) &paramsHeader
  877. ) == IDOK)
  878. {
  879. if (params[0].dwValue != pWidget->dwCallState)
  880. {
  881. ESPEvent(
  882. 0,
  883. pWidget->hdXxx,
  884. LINE_CALLSTATE,
  885. params[0].dwValue,
  886. params[1].dwValue,
  887. 0
  888. );
  889. }
  890. }
  891. break;
  892. }
  893. case WIDGETTYPE_PHONE:
  894. {
  895. char szTitle[32];
  896. EVENT_PARAM params[] =
  897. {
  898. { "<under construction>", PT_DWORD, 0, 0 }
  899. };
  900. EVENT_PARAM_HEADER paramsHeader =
  901. { 1, szTitle, 0, params };
  902. wsprintf(
  903. szTitle,
  904. "Phone%d properties",
  905. pWidget->dwWidgetID
  906. );
  907. if (DialogBoxParam(
  908. ghInstance,
  909. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  910. hwnd,
  911. ValuesDlgProc,
  912. (LPARAM) &paramsHeader
  913. ) == IDOK)
  914. {
  915. }
  916. break;
  917. }
  918. }
  919. }
  920. }
  921. break;
  922. }
  923. case IDC_LIST2:
  924. {
  925. if (HIWORD(wParam) == LBN_DBLCLK)
  926. {
  927. LRESULT lSel;
  928. complete_pending_request:
  929. lSel = SendMessage (ghwndList2, LB_GETCURSEL, 0, 0);
  930. if (lSel != LB_ERR)
  931. {
  932. LONG lResult = 0;
  933. ULONG_PTR pAsyncReqInfo;
  934. if (gdwDebugOptions & MANUAL_RESULTS)
  935. {
  936. EVENT_PARAM params[] =
  937. {
  938. { "lResult", PT_ORDINAL, 0, aLineErrs }
  939. };
  940. EVENT_PARAM_HEADER paramsHeader =
  941. { 1, "Completing request", 0, params };
  942. if (DialogBoxParam(
  943. ghInstance,
  944. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  945. hwnd,
  946. ValuesDlgProc,
  947. (LPARAM) &paramsHeader
  948. ) != IDOK)
  949. {
  950. break;
  951. }
  952. lResult = (LONG) params[0].dwValue;
  953. }
  954. pAsyncReqInfo = SendMessage(
  955. ghwndList2,
  956. LB_GETITEMDATA,
  957. (WPARAM) lSel,
  958. 0
  959. );
  960. SendMessage(
  961. ghwndList2,
  962. LB_DELETESTRING,
  963. (WPARAM) lSel,
  964. 0
  965. );
  966. ESPCompleteRequest (pAsyncReqInfo, lResult);
  967. }
  968. }
  969. break;
  970. }
  971. case IDC_PREVCTRL:
  972. {
  973. HWND hwndPrev = GetNextWindow (GetFocus (), GW_HWNDPREV);
  974. if (!hwndPrev)
  975. {
  976. hwndPrev = GetDlgItem (hwnd, IDC_LIST2);
  977. }
  978. SetFocus (hwndPrev);
  979. break;
  980. }
  981. case IDC_NEXTCTRL:
  982. {
  983. HWND hwndNext = GetNextWindow (GetFocus (), GW_HWNDNEXT);
  984. if (!hwndNext)
  985. {
  986. hwndNext = GetDlgItem (hwnd, IDC_BUTTON1);
  987. }
  988. SetFocus (hwndNext);
  989. break;
  990. }
  991. case IDC_BUTTON4: // "Clear"
  992. SetWindowText (ghwndEdit, "");
  993. break;
  994. case IDM_PBXCONFIG:
  995. DialogBox(
  996. ghInstance,
  997. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG4),
  998. hwnd,
  999. PBXConfigDlgProc
  1000. );
  1001. break;
  1002. case IDM_PBXSTART:
  1003. {
  1004. DWORD dwTID, aPBXSettings[2];
  1005. aPBXSettings[0] = (gPBXSettings[0].dwNumber ?
  1006. gPBXSettings[0].dwTime / gPBXSettings[0].dwNumber : 0);
  1007. aPBXSettings[1] = (gPBXSettings[1].dwNumber ?
  1008. gPBXSettings[1].dwTime / gPBXSettings[1].dwNumber : 0);
  1009. if (ESPStartPBXThread ((char *) aPBXSettings, 2 * sizeof(DWORD))
  1010. == 0)
  1011. {
  1012. gbPBXThreadRunning = TRUE;
  1013. EnableMenuItem(
  1014. ghMenu,
  1015. IDM_PBXSTART,
  1016. MF_BYCOMMAND | MF_GRAYED
  1017. );
  1018. EnableMenuItem(
  1019. ghMenu,
  1020. IDM_PBXSTOP,
  1021. MF_BYCOMMAND | MF_ENABLED
  1022. );
  1023. }
  1024. break;
  1025. }
  1026. case IDM_PBXSTOP:
  1027. if (ESPStopPBXThread (0) == 0)
  1028. {
  1029. gbPBXThreadRunning = FALSE;
  1030. EnableMenuItem(
  1031. ghMenu,
  1032. IDM_PBXSTOP,
  1033. MF_BYCOMMAND | MF_GRAYED
  1034. );
  1035. EnableMenuItem(
  1036. ghMenu,
  1037. IDM_PBXSTART,
  1038. MF_BYCOMMAND | MF_ENABLED
  1039. );
  1040. }
  1041. break;
  1042. case IDM_USAGE:
  1043. DialogBox(
  1044. ghInstance,
  1045. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG5),
  1046. (HWND) hwnd,
  1047. HelpDlgProc
  1048. );
  1049. break;
  1050. case IDM_ABOUT:
  1051. DialogBox(
  1052. ghInstance,
  1053. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG2),
  1054. (HWND) hwnd,
  1055. AboutDlgProc
  1056. );
  1057. break;
  1058. case IDC_EDIT1:
  1059. if (HIWORD(wParam) == EN_CHANGE)
  1060. {
  1061. //
  1062. // Watch to see if the edit control is full, & if so
  1063. // purge the top half of the text to make room for more
  1064. //
  1065. int length = GetWindowTextLength (ghwndEdit);
  1066. if (length > 20000)
  1067. {
  1068. SendMessage(
  1069. ghwndEdit,
  1070. EM_SETSEL,
  1071. (WPARAM)0 ,
  1072. (LPARAM) 10000
  1073. );
  1074. SendMessage(
  1075. ghwndEdit,
  1076. EM_REPLACESEL,
  1077. 0,
  1078. (LPARAM) (char far *) ""
  1079. );
  1080. SendMessage(
  1081. ghwndEdit,
  1082. EM_SETSEL,
  1083. (WPARAM)0xfffffffd,
  1084. (LPARAM)0xfffffffe
  1085. );
  1086. }
  1087. UpdateESPOptions();
  1088. }
  1089. break;
  1090. case IDM_SYNCCOMPL:
  1091. case IDM_ASYNCCOMPL:
  1092. case IDM_SYNCASYNCCOMPL:
  1093. case IDM_MANUALCOMPL:
  1094. if ((uiCtrlID - IDM_SYNCCOMPL) != gdwCompletionMode)
  1095. {
  1096. CheckMenuItem(
  1097. ghMenu,
  1098. IDM_SYNCCOMPL + gdwCompletionMode,
  1099. MF_BYCOMMAND | MF_UNCHECKED
  1100. );
  1101. gdwCompletionMode = uiCtrlID - IDM_SYNCCOMPL;
  1102. CheckMenuItem(
  1103. ghMenu,
  1104. uiCtrlID,
  1105. MF_BYCOMMAND | MF_CHECKED
  1106. );
  1107. UpdateESPOptions();
  1108. }
  1109. break;
  1110. case IDM_SHOWFUNCENTRY:
  1111. case IDM_SHOWFUNCPARAMS:
  1112. case IDM_SHOWFUNCEXIT:
  1113. case IDM_SHOWEVENTS:
  1114. case IDM_SHOWCOMPLETIONS:
  1115. case IDM_MANUALRESULTS:
  1116. {
  1117. DWORD dwBitField = 0x1 << (uiCtrlID - IDM_SHOWFUNCENTRY);
  1118. gdwDebugOptions ^= dwBitField;
  1119. CheckMenuItem(
  1120. ghMenu,
  1121. uiCtrlID,
  1122. MF_BYCOMMAND | (gdwDebugOptions & dwBitField ?
  1123. MF_CHECKED : MF_UNCHECKED)
  1124. );
  1125. UpdateESPOptions();
  1126. break;
  1127. }
  1128. case IDM_SHOWALL:
  1129. case IDM_SHOWNONE:
  1130. {
  1131. int i;
  1132. gdwDebugOptions = (uiCtrlID == IDM_SHOWALL ? 0xffffffff : 0);
  1133. for (i = 0; i < 5; i++)
  1134. {
  1135. CheckMenuItem(
  1136. ghMenu,
  1137. IDM_SHOWFUNCENTRY + i,
  1138. MF_BYCOMMAND | (uiCtrlID == IDM_SHOWALL ?
  1139. MF_CHECKED : MF_UNCHECKED)
  1140. );
  1141. UpdateESPOptions();
  1142. }
  1143. break;
  1144. }
  1145. case IDM_EXIT:
  1146. goto do_wm_close;
  1147. break;
  1148. } // switch (LOWORD(wParam))
  1149. break;
  1150. }
  1151. case WM_PAINT:
  1152. {
  1153. PAINTSTRUCT ps;
  1154. BeginPaint (hwnd, &ps);
  1155. if (IsIconic (hwnd))
  1156. {
  1157. DrawIcon (ps.hdc, 0, 0, hIcon);
  1158. }
  1159. else
  1160. {
  1161. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  1162. #ifdef WIN32
  1163. MoveToEx (ps.hdc, 0, 0, NULL);
  1164. #else
  1165. MoveTo (ps.hdc, 0, 0);
  1166. #endif
  1167. LineTo (ps.hdc, 5000, 0);
  1168. #ifdef WIN32
  1169. MoveToEx (ps.hdc, 0, icyButton - 4, NULL);
  1170. #else
  1171. MoveTo (ps.hdc, 0, icyButton - 4);
  1172. #endif
  1173. LineTo (ps.hdc, 5000, icyButton - 4);
  1174. }
  1175. EndPaint (hwnd, &ps);
  1176. break;
  1177. }
  1178. case WM_SIZE:
  1179. {
  1180. if (wParam != SIZE_MINIMIZED)
  1181. {
  1182. LONG width = (LONG)LOWORD(lParam);
  1183. //
  1184. // Adjust globals based on new size
  1185. //
  1186. cxWnd = (cxWnd ? cxWnd : 1); // avoid div by 0
  1187. cxList1 = (cxList1 * width) / cxWnd;
  1188. cxWnd = width;
  1189. cyWnd = ((int)HIWORD(lParam)) - icyButton;
  1190. //
  1191. // Now reposition the child windows
  1192. //
  1193. SetWindowPos(
  1194. ghwndList1,
  1195. GetNextWindow (ghwndList1, GW_HWNDPREV),
  1196. 0,
  1197. icyButton,
  1198. (int) cxList1,
  1199. 2*cyWnd/3,
  1200. SWP_SHOWWINDOW
  1201. );
  1202. SetWindowPos(
  1203. ghwndList2,
  1204. GetNextWindow (ghwndList2, GW_HWNDPREV),
  1205. 0,
  1206. icyButton + 2*cyWnd/3 + icyBorder,
  1207. (int) cxList1,
  1208. cyWnd/3 - icyBorder,
  1209. SWP_SHOWWINDOW
  1210. );
  1211. SetWindowPos(
  1212. ghwndEdit,
  1213. GetNextWindow (ghwndEdit, GW_HWNDPREV),
  1214. (int) cxList1 + icyBorder,
  1215. icyButton,
  1216. (int)width - ((int)cxList1 + icyBorder),
  1217. cyWnd,
  1218. SWP_SHOWWINDOW
  1219. );
  1220. InvalidateRect (hwnd, NULL, TRUE);
  1221. }
  1222. break;
  1223. }
  1224. case WM_MOUSEMOVE:
  1225. {
  1226. LONG x = (LONG)((short)LOWORD(lParam));
  1227. int y = (int)((short)HIWORD(lParam));
  1228. int cxList1New;
  1229. if (((y > icyButton) && (x > cxList1)) || bCaptured)
  1230. {
  1231. SetCursor(
  1232. LoadCursor ((HINSTANCE) NULL, MAKEINTRESOURCE(IDC_SIZEWE))
  1233. );
  1234. }
  1235. if (bCaptured)
  1236. {
  1237. x = (x < cxVScroll ? cxVScroll : x);
  1238. x = (x > (cxWnd - cxVScroll) ? (cxWnd - cxVScroll) : x);
  1239. cxList1New = (int) (cxList1 + x - xCapture);
  1240. SetWindowPos(
  1241. ghwndList1,
  1242. GetNextWindow (ghwndList1, GW_HWNDPREV),
  1243. 0,
  1244. icyButton,
  1245. cxList1New,
  1246. 2*cyWnd/3,
  1247. SWP_SHOWWINDOW
  1248. );
  1249. SetWindowPos(
  1250. ghwndList2,
  1251. GetNextWindow (ghwndList2, GW_HWNDPREV),
  1252. 0,
  1253. icyButton + 2*cyWnd/3 + icyBorder,
  1254. cxList1New,
  1255. cyWnd/3 - icyBorder,
  1256. SWP_SHOWWINDOW
  1257. );
  1258. SetWindowPos(
  1259. ghwndEdit,
  1260. GetNextWindow (ghwndEdit, GW_HWNDPREV),
  1261. (int) cxList1New + icyBorder,
  1262. icyButton,
  1263. (int)cxWnd - (cxList1New + icyBorder),
  1264. cyWnd,
  1265. SWP_SHOWWINDOW
  1266. );
  1267. }
  1268. break;
  1269. }
  1270. case WM_LBUTTONDOWN:
  1271. {
  1272. if (((int)((short)HIWORD(lParam)) > icyButton) &&
  1273. ((int)((short)LOWORD(lParam)) > cxList1))
  1274. {
  1275. xCapture = (LONG)LOWORD(lParam);
  1276. SetCapture (hwnd);
  1277. bCaptured = TRUE;
  1278. }
  1279. break;
  1280. }
  1281. case WM_LBUTTONUP:
  1282. {
  1283. if (bCaptured)
  1284. {
  1285. POINT p;
  1286. LONG x;
  1287. GetCursorPos (&p);
  1288. MapWindowPoints (HWND_DESKTOP, hwnd, &p, 1);
  1289. x = (LONG) p.x;
  1290. ReleaseCapture();
  1291. x = (x < cxVScroll ? cxVScroll : x);
  1292. x = (x > (cxWnd - cxVScroll) ? (cxWnd - cxVScroll) : x);
  1293. cxList1 = cxList1 + (x - xCapture);
  1294. bCaptured = FALSE;
  1295. InvalidateRect (hwnd, NULL, TRUE);
  1296. }
  1297. break;
  1298. }
  1299. case WM_CLOSE:
  1300. do_wm_close:
  1301. if (!gbESPLoaded)
  1302. {
  1303. SaveIniFileSettings();
  1304. DestroyIcon (hIcon);
  1305. DeleteObject (hFont);
  1306. PostQuitMessage (0);
  1307. }
  1308. break;
  1309. } // switch (msg)
  1310. return 0;
  1311. }
  1312. void
  1313. UpdateSummary(
  1314. HWND hwnd,
  1315. PPBXSETTING pPBXSettings
  1316. )
  1317. {
  1318. int i, j;
  1319. SendDlgItemMessage (hwnd, IDC_LIST4, LB_RESETCONTENT, 0, 0);
  1320. for (i = 0, j= 0; i < NUM_PBXSETTINGS; i++)
  1321. {
  1322. if (pPBXSettings[i].dwNumber)
  1323. {
  1324. char buf[64];
  1325. wsprintf(
  1326. buf, "%s %s per %s",
  1327. aPBXNumbers[pPBXSettings[i].dwNumber].pszVal,
  1328. pPBXSettings[i].pszEvent,
  1329. aPBXTimes[pPBXSettings[i].dwTime].pszVal
  1330. );
  1331. SendDlgItemMessage(
  1332. hwnd,
  1333. IDC_LIST4,
  1334. LB_ADDSTRING,
  1335. 0,
  1336. (LPARAM) buf
  1337. );
  1338. SendDlgItemMessage (hwnd, IDC_LIST4, LB_SETITEMDATA, j, i);
  1339. j++;
  1340. }
  1341. }
  1342. }
  1343. INT_PTR
  1344. CALLBACK
  1345. PBXConfigDlgProc(
  1346. HWND hwnd,
  1347. UINT msg,
  1348. WPARAM wParam,
  1349. LPARAM lParam
  1350. )
  1351. {
  1352. static PBXSETTING pbxSettings[NUM_PBXSETTINGS];
  1353. switch (msg)
  1354. {
  1355. case WM_INITDIALOG:
  1356. {
  1357. int i, j;
  1358. //
  1359. // Mkae a local copy of the global PBX settings
  1360. //
  1361. for (i = 0; i < NUM_PBXSETTINGS; i++)
  1362. {
  1363. pbxSettings[i].pszEvent = gPBXSettings[i].pszEvent;
  1364. //
  1365. // For Number & time fields convert from values to indexes
  1366. //
  1367. for (j = 0; aPBXNumbers[j].pszVal; j++)
  1368. {
  1369. if (gPBXSettings[i].dwNumber == aPBXNumbers[j].dwVal)
  1370. {
  1371. pbxSettings[i].dwNumber = j;
  1372. }
  1373. }
  1374. for (j = 0; aPBXTimes[j].pszVal; j++)
  1375. {
  1376. if (gPBXSettings[i].dwTime == aPBXTimes[j].dwVal)
  1377. {
  1378. pbxSettings[i].dwTime = j;
  1379. }
  1380. }
  1381. }
  1382. if (gbPBXThreadRunning)
  1383. {
  1384. EnableWindow (GetDlgItem (hwnd, IDC_RESET), FALSE);
  1385. }
  1386. else
  1387. {
  1388. for (i = 0; aPBXNumbers[i].pszVal; i++)
  1389. {
  1390. SendDlgItemMessage(
  1391. hwnd,
  1392. IDC_LIST1,
  1393. LB_ADDSTRING,
  1394. 0,
  1395. (LPARAM) aPBXNumbers[i].pszVal
  1396. );
  1397. }
  1398. for (i = 0; i < NUM_PBXSETTINGS; i++)
  1399. {
  1400. SendDlgItemMessage(
  1401. hwnd,
  1402. IDC_LIST2,
  1403. LB_ADDSTRING,
  1404. 0,
  1405. (LPARAM) pbxSettings[i].pszEvent
  1406. );
  1407. }
  1408. for (i = 0; aPBXTimes[i].pszVal; i++)
  1409. {
  1410. SendDlgItemMessage(
  1411. hwnd,
  1412. IDC_LIST3,
  1413. LB_ADDSTRING,
  1414. 0,
  1415. (LPARAM) aPBXTimes[i].pszVal
  1416. );
  1417. }
  1418. }
  1419. UpdateSummary (hwnd, pbxSettings);
  1420. break;
  1421. }
  1422. case WM_COMMAND:
  1423. switch (LOWORD(wParam))
  1424. {
  1425. case IDC_LIST1:
  1426. if (HIWORD(wParam) == LBN_SELCHANGE)
  1427. {
  1428. LRESULT lSelSetting, lSelNumber;
  1429. lSelSetting = SendDlgItemMessage(
  1430. hwnd,
  1431. IDC_LIST2,
  1432. LB_GETCURSEL,
  1433. 0,
  1434. 0
  1435. );
  1436. lSelNumber = SendDlgItemMessage(
  1437. hwnd,
  1438. IDC_LIST1,
  1439. LB_GETCURSEL,
  1440. 0,
  1441. 0
  1442. );
  1443. pbxSettings[lSelSetting].dwNumber = (DWORD) lSelNumber;
  1444. UpdateSummary (hwnd, pbxSettings);
  1445. }
  1446. break;
  1447. case IDC_LIST2:
  1448. if (HIWORD(wParam) == LBN_SELCHANGE)
  1449. {
  1450. LRESULT lSelSetting;
  1451. lSelSetting = SendDlgItemMessage(
  1452. hwnd,
  1453. IDC_LIST2,
  1454. LB_GETCURSEL,
  1455. 0,
  1456. 0
  1457. );
  1458. SendDlgItemMessage(
  1459. hwnd,
  1460. IDC_LIST1,
  1461. LB_SETCURSEL,
  1462. pbxSettings[lSelSetting].dwNumber,
  1463. 0
  1464. );
  1465. SendDlgItemMessage(
  1466. hwnd,
  1467. IDC_LIST3,
  1468. LB_SETCURSEL,
  1469. pbxSettings[lSelSetting].dwTime,
  1470. 0
  1471. );
  1472. UpdateSummary (hwnd, pbxSettings);
  1473. }
  1474. break;
  1475. case IDC_LIST3:
  1476. if (HIWORD(wParam) == LBN_SELCHANGE)
  1477. {
  1478. LRESULT lSelSetting, lSelTime;
  1479. lSelSetting = SendDlgItemMessage(
  1480. hwnd,
  1481. IDC_LIST2,
  1482. LB_GETCURSEL,
  1483. 0,
  1484. 0
  1485. );
  1486. lSelTime = SendDlgItemMessage(
  1487. hwnd,
  1488. IDC_LIST3,
  1489. LB_GETCURSEL,
  1490. 0,
  1491. 0
  1492. );
  1493. pbxSettings[lSelSetting].dwTime = (DWORD) lSelTime;
  1494. UpdateSummary (hwnd, pbxSettings);
  1495. }
  1496. break;
  1497. case IDC_LIST4:
  1498. if ((HIWORD(wParam) == LBN_SELCHANGE) && !gbPBXThreadRunning)
  1499. {
  1500. LRESULT lSel, lEntryToSel;
  1501. lSel = SendDlgItemMessage(
  1502. hwnd,
  1503. IDC_LIST4,
  1504. LB_GETCURSEL,
  1505. 0,
  1506. 0
  1507. );
  1508. lEntryToSel = SendDlgItemMessage(
  1509. hwnd,
  1510. IDC_LIST4,
  1511. LB_GETITEMDATA,
  1512. lSel,
  1513. 0
  1514. );
  1515. SendDlgItemMessage(
  1516. hwnd,
  1517. IDC_LIST1,
  1518. LB_SETCURSEL,
  1519. pbxSettings[lEntryToSel].dwNumber,
  1520. 0
  1521. );
  1522. SendDlgItemMessage(
  1523. hwnd,
  1524. IDC_LIST2,
  1525. LB_SETCURSEL,
  1526. lEntryToSel,
  1527. 0
  1528. );
  1529. SendDlgItemMessage(
  1530. hwnd,
  1531. IDC_LIST3,
  1532. LB_SETCURSEL,
  1533. pbxSettings[lEntryToSel].dwTime,
  1534. 0
  1535. );
  1536. }
  1537. break;
  1538. case IDC_RESET:
  1539. memset (pbxSettings, 0, NUM_PBXSETTINGS * sizeof(PBXSETTING));
  1540. UpdateSummary (hwnd, pbxSettings);
  1541. break;
  1542. case IDOK:
  1543. {
  1544. int i;
  1545. // convert from indexes to values
  1546. for (i = 0; i < NUM_PBXSETTINGS; i++)
  1547. {
  1548. gPBXSettings[i].dwNumber =
  1549. aPBXNumbers[pbxSettings[i].dwNumber].dwVal;
  1550. gPBXSettings[i].dwTime =
  1551. aPBXTimes[pbxSettings[i].dwTime].dwVal;
  1552. }
  1553. // drop thru to IDM_CANCEL code
  1554. }
  1555. case IDCANCEL:
  1556. EndDialog (hwnd, 0);
  1557. break;
  1558. }
  1559. break;
  1560. case WM_CTLCOLORSTATIC:
  1561. SetBkColor ((HDC) wParam, RGB (192,192,192));
  1562. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  1563. case WM_PAINT:
  1564. {
  1565. PAINTSTRUCT ps;
  1566. BeginPaint (hwnd, &ps);
  1567. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  1568. EndPaint (hwnd, &ps);
  1569. break;
  1570. }
  1571. } // switch (msg)
  1572. return FALSE;
  1573. }
  1574. INT_PTR
  1575. CALLBACK
  1576. AboutDlgProc(
  1577. HWND hwnd,
  1578. UINT msg,
  1579. WPARAM wParam,
  1580. LPARAM lParam
  1581. )
  1582. {
  1583. switch (msg)
  1584. {
  1585. case WM_COMMAND:
  1586. switch (LOWORD(wParam))
  1587. {
  1588. case IDOK:
  1589. EndDialog (hwnd, 0);
  1590. break;
  1591. }
  1592. break;
  1593. case WM_CTLCOLORSTATIC:
  1594. SetBkColor ((HDC) wParam, RGB (192,192,192));
  1595. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  1596. case WM_PAINT:
  1597. {
  1598. PAINTSTRUCT ps;
  1599. BeginPaint (hwnd, &ps);
  1600. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  1601. EndPaint (hwnd, &ps);
  1602. break;
  1603. }
  1604. }
  1605. return FALSE;
  1606. }
  1607. INT_PTR
  1608. CALLBACK
  1609. HelpDlgProc(
  1610. HWND hwnd,
  1611. UINT msg,
  1612. WPARAM wParam,
  1613. LPARAM lParam
  1614. )
  1615. {
  1616. switch (msg)
  1617. {
  1618. case WM_INITDIALOG:
  1619. {
  1620. static char szUsageText[] =
  1621. "ABSTRACT:\r\n" \
  1622. " ESP is a TAPI Service Provider that supports\r\n" \
  1623. "multiple virtual line and phone devices. It is\r\n" \
  1624. "configurable, requires no special hardware,\r\n" \
  1625. "and implements the entire Telephony Service\r\n" \
  1626. "Provider Interface (including Win95 TAPI\r\n" \
  1627. "extensions). ESP will work in both Windows 3.1/\r\n" \
  1628. "TAPI 1.0 and Windows95/TAPI 1.1 systems.\r\n" \
  1629. "\r\nGETTING STARTED:\r\n" \
  1630. " 1. Choose 'File/Install' to install ESP.\r\n" \
  1631. " 2. Start a TAPI application and try to make\r\n" \
  1632. "a call on one of ESP's line devices (watch for\r\n" \
  1633. "messages appearing in the ESP window).\r\n" \
  1634. " *. Choose 'File/Uninstall' to uninstall ESP.\r\n" \
  1635. "\r\nMORE INFO:\r\n" \
  1636. " * Double-click on a line, call, or phone\r\n" \
  1637. "widget (in upper-left listbox) to view/modify\r\n" \
  1638. "properties. The 'hd'widget field is the driver\r\n" \
  1639. "handle; the 'ht' field is the TAPI handle.\r\n" \
  1640. " * Press the 'LEvt' or 'PEvt' button to\r\n" \
  1641. "indicate a line or phone event to TAPI.DLL.\r\n" \
  1642. "Press the 'Call+' button to indicate an incoming\r\n" \
  1643. " call.\r\n" \
  1644. " * Choose 'Options/Default values...' to\r\n" \
  1645. "modify provider paramters (SPI version, etc.)\r\n" \
  1646. " * All parameter values displayed in\r\n" \
  1647. "hexadecimal unless specified otherwise (strings\r\n" \
  1648. "displayed by contents).\r\n" \
  1649. " * Choose 'Options/Complete async requests/Xxx'\r\n" \
  1650. "to specify async requests completion behavior.\r\n" \
  1651. "Manually-completed requests appear in lower-left\r\n" \
  1652. "listbox.";
  1653. SetDlgItemText (hwnd, IDC_EDIT1, szUsageText);
  1654. break;
  1655. }
  1656. case WM_COMMAND:
  1657. switch (LOWORD(wParam))
  1658. {
  1659. case IDOK:
  1660. EndDialog (hwnd, 0);
  1661. break;
  1662. }
  1663. break;
  1664. case WM_CTLCOLORSTATIC:
  1665. SetBkColor ((HDC) wParam, RGB (192,192,192));
  1666. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  1667. case WM_PAINT:
  1668. {
  1669. PAINTSTRUCT ps;
  1670. BeginPaint (hwnd, &ps);
  1671. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  1672. EndPaint (hwnd, &ps);
  1673. break;
  1674. }
  1675. }
  1676. return 0;
  1677. }
  1678. void
  1679. ProcessWidgetEvent(
  1680. PWIDGETEVENT pEvent
  1681. )
  1682. {
  1683. char buf[64];
  1684. LRESULT lIndex = (LRESULT) -2; // 0xfffffffe
  1685. PMYWIDGET pWidget = gpWidgets;
  1686. switch (pEvent->dwWidgetType)
  1687. {
  1688. case WIDGETTYPE_ASYNCREQUEST:
  1689. {
  1690. wsprintf (buf, "ReqID=x%x", pEvent->dwWidgetID);
  1691. // BUGBUG want to incl the req type at some point (str table lookup)
  1692. lIndex = SendMessage (ghwndList2, LB_ADDSTRING, 0, (LPARAM) buf);
  1693. SendMessage(
  1694. ghwndList2,
  1695. LB_SETITEMDATA,
  1696. (WPARAM) lIndex,
  1697. (LPARAM) pEvent->pAsyncReqInfo
  1698. );
  1699. return;
  1700. }
  1701. case WIDGETTYPE_LINE:
  1702. {
  1703. for (lIndex = 0; pWidget; lIndex++)
  1704. {
  1705. if ((pWidget->dwWidgetType == WIDGETTYPE_LINE) &&
  1706. (pWidget->dwWidgetID == pEvent->dwWidgetID))
  1707. {
  1708. break;
  1709. }
  1710. pWidget = pWidget->pNext;
  1711. }
  1712. if (!pWidget)
  1713. {
  1714. //
  1715. // This is a dynamically created device - add it to end of the list
  1716. //
  1717. pWidget = MyAlloc (sizeof (MYWIDGET));
  1718. // fix for bug 49692
  1719. if (!pWidget) break;
  1720. pWidget->dwWidgetID = (DWORD) pEvent->dwWidgetID;
  1721. pWidget->dwWidgetType = WIDGETTYPE_LINE;
  1722. if (!gpWidgets)
  1723. {
  1724. gpWidgets = pWidget;
  1725. }
  1726. else
  1727. {
  1728. PMYWIDGET pLastWidget = gpWidgets;
  1729. while (pLastWidget->pNext)
  1730. {
  1731. pLastWidget = pLastWidget->pNext;
  1732. }
  1733. pLastWidget->pNext = pWidget;
  1734. }
  1735. wsprintf (buf, "Line%d (CLOSED)", pWidget->dwWidgetID);
  1736. SendMessage (ghwndList1, LB_ADDSTRING, 0, (LPARAM) buf);
  1737. SendMessage (ghwndList1, LB_SETITEMDATA, lIndex, (LPARAM) pWidget);
  1738. }
  1739. else if (pEvent->htXxx == 0)
  1740. {
  1741. PMYWIDGET pWidget2 = pWidget->pNext;
  1742. // line closing so nuke all following calls (listbox & widg list)
  1743. while (pWidget2 && pWidget2->dwWidgetType == WIDGETTYPE_CALL)
  1744. {
  1745. pWidget->pNext = pWidget2->pNext;
  1746. MyFree (pWidget2);
  1747. pWidget2 = pWidget->pNext;
  1748. SendMessage(
  1749. ghwndList1,
  1750. LB_DELETESTRING,
  1751. (WPARAM) lIndex + 1,
  1752. (LPARAM) 0
  1753. );
  1754. }
  1755. if (pWidget2)
  1756. {
  1757. pWidget2->pPrev = pWidget;
  1758. }
  1759. wsprintf (buf, "Line%d (CLOSED)", pEvent->dwWidgetID);
  1760. }
  1761. else
  1762. {
  1763. wsprintf (buf, "Line%d, hd=x%x, ht=x%x",
  1764. pEvent->dwWidgetID,
  1765. pEvent->hdXxx,
  1766. pEvent->htXxx
  1767. );
  1768. }
  1769. pWidget->hdXxx = pEvent->hdXxx;
  1770. pWidget->htXxx = pEvent->htXxx;
  1771. break;
  1772. }
  1773. case WIDGETTYPE_CALL:
  1774. {
  1775. LRESULT lIndexLine = 0;
  1776. PMYWIDGET pLine = NULL;
  1777. for (lIndex = 0; pWidget; lIndex++)
  1778. {
  1779. if ((pWidget->dwWidgetType == WIDGETTYPE_LINE) &&
  1780. (pWidget->dwWidgetID == pEvent->dwWidgetID))
  1781. {
  1782. pLine = pWidget;
  1783. lIndexLine = lIndex;
  1784. }
  1785. if ((pWidget->dwWidgetType == WIDGETTYPE_CALL) &&
  1786. (pWidget->hdXxx == pEvent->hdXxx))
  1787. {
  1788. break;
  1789. }
  1790. pWidget = pWidget->pNext;
  1791. }
  1792. if (pWidget)
  1793. {
  1794. //
  1795. // Found call in list
  1796. //
  1797. if (pEvent->htXxx)
  1798. {
  1799. //
  1800. // Update the call's listbox entry
  1801. //
  1802. int i;
  1803. for (i = 0; pEvent->dwCallState != aCallStates[i].dwVal; i++);
  1804. wsprintf(
  1805. buf,
  1806. " hdCall=x%x, ht=x%x, %s Addr=%d",
  1807. pEvent->hdXxx,
  1808. pEvent->htXxx,
  1809. aCallStates[i].pszVal,
  1810. pEvent->dwCallAddressID
  1811. );
  1812. pWidget->dwCallState = (DWORD) pEvent->dwCallState;
  1813. }
  1814. else
  1815. {
  1816. //
  1817. // Call was destroyed, so remove it from the listbox &
  1818. // widget lists and nuke the data structure
  1819. //
  1820. SendMessage(
  1821. ghwndList1,
  1822. LB_DELETESTRING,
  1823. (WPARAM) lIndex,
  1824. (LPARAM) 0
  1825. );
  1826. pWidget->pPrev->pNext = pWidget->pNext;
  1827. if (pWidget->pNext)
  1828. {
  1829. pWidget->pNext->pPrev = pWidget->pPrev;
  1830. }
  1831. MyFree (pWidget);
  1832. return;
  1833. }
  1834. }
  1835. else if (pEvent->htXxx)
  1836. {
  1837. //
  1838. // Call wasn't in the list, but it's valid so add it to
  1839. // listbox & widget lists
  1840. //
  1841. int i;
  1842. pWidget = MyAlloc (sizeof (MYWIDGET));
  1843. // fix for bug 49693
  1844. if (!pWidget) break;
  1845. memcpy (pWidget, pEvent, sizeof (WIDGETEVENT));
  1846. if ((pWidget->pNext = pLine->pNext))
  1847. {
  1848. pWidget->pNext->pPrev = pWidget;
  1849. }
  1850. pWidget->pPrev = pLine;
  1851. pLine->pNext = pWidget;
  1852. for (i = 0; pEvent->dwCallState != aCallStates[i].dwVal; i++);
  1853. wsprintf(
  1854. buf,
  1855. " hdCall=x%x, ht=x%x, %s Addr=%d",
  1856. pEvent->hdXxx,
  1857. pEvent->htXxx,
  1858. aCallStates[i].pszVal,
  1859. pEvent->dwCallAddressID
  1860. );
  1861. SendMessage(
  1862. ghwndList1,
  1863. LB_INSERTSTRING,
  1864. (WPARAM) lIndexLine + 1,
  1865. (LPARAM) buf
  1866. );
  1867. SendMessage(
  1868. ghwndList1,
  1869. LB_SETITEMDATA,
  1870. (WPARAM) lIndexLine + 1,
  1871. (LPARAM) pWidget
  1872. );
  1873. return;
  1874. }
  1875. break;
  1876. }
  1877. case WIDGETTYPE_PHONE:
  1878. {
  1879. for (lIndex = 0; pWidget; lIndex++)
  1880. {
  1881. if ((pWidget->dwWidgetType == WIDGETTYPE_PHONE) &&
  1882. (pWidget->dwWidgetID == pEvent->dwWidgetID))
  1883. {
  1884. break;
  1885. }
  1886. pWidget = pWidget->pNext;
  1887. }
  1888. if (!pWidget)
  1889. {
  1890. //
  1891. // This is a dynamically created device - add it to end of the list
  1892. //
  1893. pWidget = MyAlloc (sizeof (MYWIDGET));
  1894. pWidget->dwWidgetID = (DWORD) pEvent->dwWidgetID;
  1895. pWidget->dwWidgetType = WIDGETTYPE_PHONE;
  1896. if (!gpWidgets)
  1897. {
  1898. gpWidgets = pWidget;
  1899. }
  1900. else
  1901. {
  1902. PMYWIDGET pLastWidget = gpWidgets;
  1903. while (pLastWidget->pNext)
  1904. {
  1905. pLastWidget = pLastWidget->pNext;
  1906. }
  1907. pLastWidget->pNext = pWidget;
  1908. }
  1909. wsprintf (buf, "Phone%d (CLOSED)", pWidget->dwWidgetID);
  1910. SendMessage (ghwndList1, LB_ADDSTRING, 0, (LPARAM) buf);
  1911. SendMessage (ghwndList1, LB_SETITEMDATA, lIndex, (LPARAM) pWidget);
  1912. }
  1913. else if (pEvent->htXxx == 0)
  1914. {
  1915. wsprintf (buf, "Phone%d (CLOSED)", pEvent->dwWidgetID);
  1916. }
  1917. else
  1918. {
  1919. wsprintf (buf, "Phone%d, hd=x%x, ht=x%x",
  1920. pEvent->dwWidgetID,
  1921. pEvent->hdXxx,
  1922. pEvent->htXxx
  1923. );
  1924. }
  1925. pWidget->hdXxx = pEvent->hdXxx;
  1926. pWidget->htXxx = pEvent->htXxx;
  1927. break;
  1928. }
  1929. case WIDGETTYPE_STARTUP:
  1930. {
  1931. //
  1932. // Build widget list for "static" devices
  1933. //
  1934. DWORD i, j;
  1935. PMYWIDGET pWidget, pLastWidget = NULL;
  1936. for (i = 0; i < pEvent->dwNumLines; i++)
  1937. {
  1938. pWidget = MyAlloc (sizeof (MYWIDGET));
  1939. pWidget->dwWidgetID = i + (DWORD) pEvent->dwLineDeviceIDBase;
  1940. pWidget->dwWidgetType = WIDGETTYPE_LINE;
  1941. if ((pWidget->pPrev = pLastWidget))
  1942. {
  1943. pLastWidget->pNext = pWidget;
  1944. }
  1945. else
  1946. {
  1947. gpWidgets = pWidget;
  1948. }
  1949. pLastWidget = pWidget;
  1950. wsprintf (buf, "Line%d (CLOSED)", pWidget->dwWidgetID);
  1951. SendMessage (ghwndList1, LB_ADDSTRING, 0, (LPARAM) buf);
  1952. SendMessage (ghwndList1, LB_SETITEMDATA, i, (LPARAM) pWidget);
  1953. }
  1954. for (j = 0; j < pEvent->dwNumPhones; j++)
  1955. {
  1956. pWidget = MyAlloc (sizeof (MYWIDGET));
  1957. pWidget->dwWidgetID = j + (DWORD) pEvent->dwPhoneDeviceIDBase;
  1958. pWidget->dwWidgetType = WIDGETTYPE_PHONE;
  1959. if ((pWidget->pPrev = pLastWidget))
  1960. {
  1961. pLastWidget->pNext = pWidget;
  1962. }
  1963. else
  1964. {
  1965. gpWidgets = pWidget;
  1966. }
  1967. pLastWidget = pWidget;
  1968. wsprintf (buf, "Phone%d (CLOSED)", pWidget->dwWidgetID);
  1969. SendMessage (ghwndList1, LB_ADDSTRING, 0, (LPARAM) buf);
  1970. SendMessage (ghwndList1, LB_SETITEMDATA, i + j, (LPARAM) pWidget);
  1971. }
  1972. return;
  1973. }
  1974. } // switch (pEvent->dwWidgetType)
  1975. //
  1976. // Update the widget's listbox entry given the index &
  1977. // description filled in above
  1978. //
  1979. SendMessage (ghwndList1, LB_DELETESTRING, (WPARAM) lIndex, (LPARAM) 0);
  1980. SendMessage (ghwndList1, LB_INSERTSTRING, (WPARAM) lIndex, (LPARAM) buf);
  1981. SendMessage (ghwndList1, LB_SETITEMDATA, (WPARAM) lIndex, (LPARAM)pWidget);
  1982. }
  1983. void
  1984. UpdateESPOptions(
  1985. void
  1986. )
  1987. {
  1988. if (gbESPLoaded)
  1989. {
  1990. RpcTryExcept
  1991. {
  1992. ESPSetOptions(
  1993. (long) gdwDebugOptions,
  1994. (long) gdwCompletionMode
  1995. );
  1996. }
  1997. RpcExcept (I_RpcExceptionFilter(RpcExceptionCode()))
  1998. {
  1999. ShowStr ("UpdateESPOptions: EXCEPTION while calling ESPSetOptions()");
  2000. }
  2001. RpcEndExcept
  2002. }
  2003. }
  2004. void
  2005. SaveIniFileSettings(
  2006. void
  2007. )
  2008. {
  2009. RECT rect;
  2010. GetWindowRect (ghwndMain, &rect);
  2011. {
  2012. typedef struct _YYY
  2013. {
  2014. LPCSTR pszValueName;
  2015. DWORD dwValue;
  2016. } YYY, *PYYY;
  2017. YYY ayyy[] =
  2018. {
  2019. { "Left", (DWORD) rect.left },
  2020. { "Top", (DWORD) rect.top },
  2021. { "Right", (DWORD) rect.right },
  2022. { "Bottom", (DWORD) rect.bottom },
  2023. { "cxWnd", (DWORD) cxWnd },
  2024. { "cxList1", (DWORD) cxList1 },
  2025. { "AutoClose", (DWORD) gbAutoClose },
  2026. { "DebugOutput", (DWORD) gdwDebugOptions },
  2027. { "Completion", (DWORD) gdwCompletionMode },
  2028. { "TSPIVersion", (DWORD) gdwTSPIVersion },
  2029. { "NumLines", (DWORD) gdwNumLines },
  2030. { "NumAddrsPerLine", (DWORD) gdwNumAddrsPerLine },
  2031. { "NumCallsPerAddr", (DWORD) gdwNumCallsPerAddr },
  2032. { "NumPhones", (DWORD) gdwNumPhones },
  2033. { "AutoGatherGenerateMsgs", (DWORD) gbAutoGatherGenerateMsgs },
  2034. { "DisableUI", (DWORD) gbDisableUI },
  2035. { NULL, (DWORD) 0 }
  2036. };
  2037. DWORD i = (IsIconic (ghwndMain) ? 6 : 0); // don't chg pos if iconic
  2038. for (i = 0; ayyy[i].pszValueName; i++)
  2039. {
  2040. char buf[16];
  2041. wsprintf (buf, "%d", ayyy[i].dwValue);
  2042. WriteProfileString (szMySection, ayyy[i].pszValueName, buf);
  2043. }
  2044. }
  2045. }
  2046. void
  2047. xxxShowStr(
  2048. char *psz
  2049. )
  2050. {
  2051. SendMessage (ghwndEdit, EM_SETSEL, (WPARAM)0xfffffffd, (LPARAM)0xfffffffe);
  2052. SendMessage (ghwndEdit, EM_REPLACESEL, 0, (LPARAM) psz);
  2053. SendMessage (ghwndEdit, EM_SCROLLCARET, 0, 0);
  2054. }
  2055. void
  2056. ShowStr(
  2057. char *pszFormat,
  2058. ...
  2059. )
  2060. {
  2061. char buf[256];
  2062. va_list ap;
  2063. va_start(ap, pszFormat);
  2064. wvsprintf (buf, pszFormat, ap);
  2065. strcat (buf, "\r\n");
  2066. xxxShowStr (buf);
  2067. va_end(ap);
  2068. }
  2069. LPVOID
  2070. MyAlloc(
  2071. size_t numBytes
  2072. )
  2073. {
  2074. LPVOID p = (LPVOID) LocalAlloc (LPTR, numBytes);
  2075. if (!p)
  2076. {
  2077. ShowStr ("Error: MyAlloc () failed");
  2078. }
  2079. return p;
  2080. }
  2081. void
  2082. MyFree(
  2083. LPVOID p
  2084. )
  2085. {
  2086. #if DBG
  2087. //
  2088. // Fill the buf to free with 0x5a's to facilitate debugging
  2089. //
  2090. memset (p, 0x5a, (size_t) LocalSize (LocalHandle (p)));
  2091. #endif
  2092. LocalFree (p);
  2093. }
  2094. void
  2095. __RPC_FAR *
  2096. __RPC_API
  2097. midl_user_allocate(
  2098. size_t len
  2099. )
  2100. {
  2101. return NULL;
  2102. }
  2103. void
  2104. __RPC_API
  2105. midl_user_free(
  2106. void __RPC_FAR * ptr
  2107. )
  2108. {
  2109. }
  2110. BOOL
  2111. ScanForDWORD(
  2112. char far *pBuf,
  2113. ULONG_PTR *lpdw
  2114. )
  2115. {
  2116. char c;
  2117. BOOL bValid = FALSE;
  2118. ULONG_PTR d = 0;
  2119. while ((c = *pBuf))
  2120. {
  2121. if ((c >= '0') && (c <= '9'))
  2122. {
  2123. c -= '0';
  2124. }
  2125. else if ((c >= 'a') && (c <= 'f'))
  2126. {
  2127. c -= ('a' - 10);
  2128. }
  2129. else if ((c >= 'A') && (c <= 'F'))
  2130. {
  2131. c -= ('A' - 10);
  2132. }
  2133. else
  2134. {
  2135. break;
  2136. }
  2137. bValid = TRUE;
  2138. d *= 16;
  2139. d += (ULONG_PTR) c;
  2140. pBuf++;
  2141. }
  2142. if (bValid)
  2143. {
  2144. *lpdw = d;
  2145. }
  2146. return bValid;
  2147. }
  2148. INT_PTR
  2149. CALLBACK
  2150. ValuesDlgProc(
  2151. HWND hwnd,
  2152. UINT msg,
  2153. WPARAM wParam,
  2154. LPARAM lParam
  2155. )
  2156. {
  2157. DWORD i;
  2158. static HWND hwndCombo, hwndList1, hwndList2;
  2159. static LRESULT lLastSel;
  2160. static char szComboText[MAX_STRING_PARAM_SIZE];
  2161. static PEVENT_PARAM_HEADER pParamsHeader;
  2162. switch (msg)
  2163. {
  2164. case WM_INITDIALOG:
  2165. {
  2166. hwndList1 = GetDlgItem (hwnd, IDC_LIST1);
  2167. hwndList2 = GetDlgItem (hwnd, IDC_LIST2);
  2168. hwndCombo = GetDlgItem (hwnd, IDC_COMBO1);
  2169. lLastSel = -1;
  2170. pParamsHeader = (PEVENT_PARAM_HEADER) lParam;
  2171. //
  2172. // Limit the max text length for the combobox's edit field
  2173. // (NOTE: A combobox ctrl actually has two child windows: a
  2174. // edit ctrl & a listbox. We need to get the hwnd of the
  2175. // child edit ctrl & send it the LIMITTEXT msg.)
  2176. //
  2177. {
  2178. HWND hwndChild = GetWindow (hwndCombo, GW_CHILD);
  2179. while (hwndChild)
  2180. {
  2181. char buf[8];
  2182. GetClassName (hwndChild, buf, 7);
  2183. if (_stricmp (buf, "edit") == 0)
  2184. {
  2185. break;
  2186. }
  2187. hwndChild = GetWindow (hwndChild, GW_HWNDNEXT);
  2188. }
  2189. SendMessage(
  2190. hwndChild,
  2191. EM_LIMITTEXT,
  2192. (WPARAM) MAX_STRING_PARAM_SIZE - 1,
  2193. 0
  2194. );
  2195. }
  2196. //
  2197. // Misc other init
  2198. //
  2199. SetWindowText (hwnd, pParamsHeader->pszDlgTitle);
  2200. for (i = 0; i < pParamsHeader->dwNumParams; i++)
  2201. {
  2202. SendMessage(
  2203. hwndList1,
  2204. LB_INSERTSTRING,
  2205. (WPARAM) -1,
  2206. (LPARAM) pParamsHeader->aParams[i].szName
  2207. );
  2208. }
  2209. break;
  2210. }
  2211. case WM_COMMAND:
  2212. {
  2213. switch (LOWORD(wParam))
  2214. {
  2215. case IDOK:
  2216. if (lLastSel != -1)
  2217. {
  2218. char buf[MAX_STRING_PARAM_SIZE];
  2219. //
  2220. // Save val of currently selected param
  2221. //
  2222. i = GetDlgItemText(
  2223. hwnd,
  2224. IDC_COMBO1,
  2225. buf,
  2226. MAX_STRING_PARAM_SIZE - 1
  2227. );
  2228. switch (pParamsHeader->aParams[lLastSel].dwType)
  2229. {
  2230. case PT_STRING:
  2231. {
  2232. LRESULT lComboSel;
  2233. lComboSel = SendMessage (hwndCombo, CB_GETCURSEL, 0, 0);
  2234. if (lComboSel == 0) // "NULL string (dwXxxSize = 0)"
  2235. {
  2236. pParamsHeader->aParams[lLastSel].dwValue = 0;
  2237. }
  2238. else // "Valid string"
  2239. {
  2240. strncpy(
  2241. pParamsHeader->aParams[lLastSel].buf,
  2242. buf,
  2243. MAX_STRING_PARAM_SIZE - 1
  2244. );
  2245. pParamsHeader->aParams[lLastSel].buf
  2246. [MAX_STRING_PARAM_SIZE-1] = 0;
  2247. pParamsHeader->aParams[lLastSel].dwValue = (ULONG_PTR)
  2248. pParamsHeader->aParams[lLastSel].buf;
  2249. }
  2250. break;
  2251. }
  2252. case PT_DWORD:
  2253. case PT_FLAGS:
  2254. case PT_ORDINAL:
  2255. {
  2256. if (!ScanForDWORD(
  2257. buf,
  2258. &pParamsHeader->aParams[lLastSel].dwValue
  2259. ))
  2260. {
  2261. //
  2262. // Default to 0
  2263. //
  2264. pParamsHeader->aParams[lLastSel].dwValue = 0;
  2265. }
  2266. break;
  2267. }
  2268. } // switch
  2269. }
  2270. // Drop thru to IDCANCEL cleanup code
  2271. case IDCANCEL:
  2272. EndDialog (hwnd, (int)LOWORD(wParam));
  2273. break;
  2274. case IDC_LIST1:
  2275. if (HIWORD(wParam) == LBN_SELCHANGE)
  2276. {
  2277. char buf[MAX_STRING_PARAM_SIZE] = "";
  2278. LPCSTR lpstr = buf;
  2279. LRESULT lSel = SendMessage (hwndList1, LB_GETCURSEL, 0, 0);
  2280. if (lLastSel != -1)
  2281. {
  2282. //
  2283. // Save the old param value
  2284. //
  2285. i = GetWindowText(
  2286. hwndCombo,
  2287. buf,
  2288. MAX_STRING_PARAM_SIZE - 1
  2289. );
  2290. switch (pParamsHeader->aParams[lLastSel].dwType)
  2291. {
  2292. case PT_STRING:
  2293. {
  2294. LRESULT lComboSel;
  2295. lComboSel = SendMessage (hwndCombo, CB_GETCURSEL, 0,0);
  2296. if (lComboSel == 0) // "NULL string (dwXxxSize = 0)"
  2297. {
  2298. pParamsHeader->aParams[lLastSel].dwValue = 0;
  2299. }
  2300. else // "Valid string" or no sel
  2301. {
  2302. strncpy(
  2303. pParamsHeader->aParams[lLastSel].buf,
  2304. buf,
  2305. MAX_STRING_PARAM_SIZE - 1
  2306. );
  2307. pParamsHeader->aParams[lLastSel].buf[MAX_STRING_PARAM_SIZE - 1] = 0;
  2308. pParamsHeader->aParams[lLastSel].dwValue =
  2309. (ULONG_PTR)
  2310. pParamsHeader->aParams[lLastSel].buf;
  2311. }
  2312. break;
  2313. }
  2314. case PT_DWORD:
  2315. case PT_FLAGS:
  2316. case PT_ORDINAL:
  2317. {
  2318. if (!ScanForDWORD(
  2319. buf,
  2320. &pParamsHeader->aParams[lLastSel].dwValue
  2321. ))
  2322. {
  2323. //
  2324. // Default to 0
  2325. //
  2326. pParamsHeader->aParams[lLastSel].dwValue = 0;
  2327. }
  2328. break;
  2329. }
  2330. } // switch
  2331. }
  2332. SendMessage (hwndList2, LB_RESETCONTENT, 0, 0);
  2333. SendMessage (hwndCombo, CB_RESETCONTENT, 0, 0);
  2334. switch (pParamsHeader->aParams[lSel].dwType)
  2335. {
  2336. case PT_STRING:
  2337. {
  2338. char * aszOptions[] =
  2339. {
  2340. "NUL (dwXxxSize=0)",
  2341. "Valid string"
  2342. };
  2343. for (i = 0; i < 2; i++)
  2344. {
  2345. SendMessage(
  2346. hwndCombo,
  2347. CB_INSERTSTRING,
  2348. (WPARAM) -1,
  2349. (LPARAM) aszOptions[i]
  2350. );
  2351. }
  2352. if (pParamsHeader->aParams[lSel].dwValue == 0)
  2353. {
  2354. i = 0;
  2355. buf[0] = 0;
  2356. }
  2357. else
  2358. {
  2359. i = 1;
  2360. lpstr = (LPCSTR) pParamsHeader->aParams[lSel].dwValue;
  2361. }
  2362. SendMessage (hwndCombo, CB_SETCURSEL, (WPARAM) i, 0);
  2363. break;
  2364. }
  2365. case PT_DWORD:
  2366. {
  2367. SendMessage(
  2368. hwndCombo,
  2369. CB_INSERTSTRING,
  2370. (WPARAM) -1,
  2371. (LPARAM) (char far *) "0000000"
  2372. );
  2373. if (pParamsHeader->aParams[lSel].dwDefValue)
  2374. {
  2375. //
  2376. // Add the default val string to the combo
  2377. //
  2378. wsprintf(
  2379. buf,
  2380. "%08lx",
  2381. pParamsHeader->aParams[lSel].dwDefValue
  2382. );
  2383. SendMessage(
  2384. hwndCombo,
  2385. CB_INSERTSTRING,
  2386. (WPARAM) -1,
  2387. (LPARAM) buf
  2388. );
  2389. }
  2390. SendMessage(
  2391. hwndCombo,
  2392. CB_INSERTSTRING,
  2393. (WPARAM) -1,
  2394. (LPARAM) (char far *) "ffffffff"
  2395. );
  2396. wsprintf(
  2397. buf,
  2398. "%08lx",
  2399. pParamsHeader->aParams[lSel].dwValue
  2400. );
  2401. break;
  2402. }
  2403. case PT_ORDINAL:
  2404. {
  2405. //
  2406. // Stick the bit flag strings in the list box
  2407. //
  2408. PLOOKUP pLookup = (PLOOKUP)
  2409. pParamsHeader->aParams[lSel].pLookup;
  2410. for (i = 0; pLookup[i].dwVal != 0xffffffff; i++)
  2411. {
  2412. SendMessage(
  2413. hwndList2,
  2414. LB_INSERTSTRING,
  2415. (WPARAM) -1,
  2416. (LPARAM) pLookup[i].pszVal
  2417. );
  2418. if (pParamsHeader->aParams[lSel].dwValue ==
  2419. pLookup[i].dwVal)
  2420. {
  2421. SendMessage(
  2422. hwndList2,
  2423. LB_SETSEL,
  2424. (WPARAM) TRUE,
  2425. (LPARAM) MAKELPARAM((WORD)i,0)
  2426. );
  2427. }
  2428. }
  2429. SendMessage(
  2430. hwndCombo,
  2431. CB_INSERTSTRING,
  2432. (WPARAM) -1,
  2433. (LPARAM) (char far *) "select none"
  2434. );
  2435. wsprintf(
  2436. buf,
  2437. "%08lx",
  2438. pParamsHeader->aParams[lSel].dwValue
  2439. );
  2440. break;
  2441. }
  2442. case PT_FLAGS:
  2443. {
  2444. //
  2445. // Stick the bit flag strings in the list box
  2446. //
  2447. HWND hwndList2 = GetDlgItem (hwnd, IDC_LIST2);
  2448. PLOOKUP pLookup = (PLOOKUP)
  2449. pParamsHeader->aParams[lSel].pLookup;
  2450. for (i = 0; pLookup[i].dwVal != 0xffffffff; i++)
  2451. {
  2452. SendMessage(
  2453. hwndList2,
  2454. LB_INSERTSTRING,
  2455. (WPARAM) -1,
  2456. (LPARAM) pLookup[i].pszVal
  2457. );
  2458. if (pParamsHeader->aParams[lSel].dwValue &
  2459. pLookup[i].dwVal)
  2460. {
  2461. SendMessage(
  2462. hwndList2,
  2463. LB_SETSEL,
  2464. (WPARAM) TRUE,
  2465. (LPARAM) MAKELPARAM((WORD)i,0)
  2466. );
  2467. }
  2468. }
  2469. SendMessage(
  2470. hwndCombo,
  2471. CB_INSERTSTRING,
  2472. (WPARAM) -1,
  2473. (LPARAM) (char far *) "select none"
  2474. );
  2475. SendMessage(
  2476. hwndCombo,
  2477. CB_INSERTSTRING,
  2478. (WPARAM) -1,
  2479. (LPARAM) (char far *) "select all"
  2480. );
  2481. wsprintf(
  2482. buf,
  2483. "%08lx",
  2484. pParamsHeader->aParams[lSel].dwValue
  2485. );
  2486. break;
  2487. }
  2488. } //switch
  2489. SetWindowText (hwndCombo, lpstr);
  2490. lLastSel = lSel;
  2491. }
  2492. break;
  2493. case IDC_LIST2:
  2494. if (HIWORD(wParam) == LBN_SELCHANGE)
  2495. {
  2496. //
  2497. // BUGBUG in the PT_ORDINAL case we should compare the
  2498. // currently selected item(s) against the previous DWORD
  2499. // val and figure out which item we need to deselect,
  2500. // if any, in order to maintain a mutex of values
  2501. //
  2502. char buf[16];
  2503. LONG i;
  2504. int far *ai;
  2505. LRESULT lSelCount =
  2506. SendMessage (hwndList2, LB_GETSELCOUNT, 0, 0);
  2507. PLOOKUP pLookup = (PLOOKUP)
  2508. pParamsHeader->aParams[lLastSel].pLookup;
  2509. ULONG_PTR dwValue = 0;
  2510. ai = (int far *) MyAlloc ((size_t)lSelCount * sizeof(int));
  2511. SendMessage(
  2512. hwndList2,
  2513. LB_GETSELITEMS,
  2514. (WPARAM) lSelCount,
  2515. (LPARAM) ai
  2516. );
  2517. if (pParamsHeader->aParams[lLastSel].dwType == PT_FLAGS)
  2518. {
  2519. for (i = 0; i < lSelCount; i++)
  2520. {
  2521. dwValue |= pLookup[ai[i]].dwVal;
  2522. }
  2523. }
  2524. else // if (.dwType == PT_ORDINAL)
  2525. {
  2526. if (lSelCount == 1)
  2527. {
  2528. dwValue = pLookup[ai[0]].dwVal;
  2529. }
  2530. else if (lSelCount == 2)
  2531. {
  2532. //
  2533. // Figure out which item we need to de-select, since
  2534. // we're doing ordinals & only want 1 item selected
  2535. // at a time
  2536. //
  2537. GetWindowText (hwndCombo, buf, 16);
  2538. if (ScanForDWORD (buf, &dwValue))
  2539. {
  2540. if (pLookup[ai[0]].dwVal == dwValue)
  2541. {
  2542. SendMessage(
  2543. hwndList2,
  2544. LB_SETSEL,
  2545. 0,
  2546. (LPARAM) ai[0]
  2547. );
  2548. dwValue = pLookup[ai[1]].dwVal;
  2549. }
  2550. else
  2551. {
  2552. SendMessage(
  2553. hwndList2,
  2554. LB_SETSEL,
  2555. 0,
  2556. (LPARAM) ai[1]
  2557. );
  2558. dwValue = pLookup[ai[0]].dwVal;
  2559. }
  2560. }
  2561. else
  2562. {
  2563. // BUGBUG de-select items???
  2564. dwValue = 0;
  2565. }
  2566. }
  2567. else if (lSelCount > 2)
  2568. {
  2569. //
  2570. // Determine previous selection & de-select all the
  2571. // latest selections
  2572. //
  2573. GetDlgItemText (hwnd, IDC_COMBO1, buf, 16);
  2574. if (ScanForDWORD (buf, &dwValue))
  2575. {
  2576. for (i = 0; i < lSelCount; i++)
  2577. {
  2578. if (pLookup[ai[i]].dwVal != dwValue)
  2579. {
  2580. SendMessage(
  2581. hwndList2,
  2582. LB_SETSEL,
  2583. 0,
  2584. (LPARAM) ai[i]
  2585. );
  2586. }
  2587. }
  2588. }
  2589. else
  2590. {
  2591. // BUGBUG de-select items???
  2592. dwValue = 0;
  2593. }
  2594. }
  2595. }
  2596. MyFree (ai);
  2597. wsprintf (buf, "%08lx", dwValue);
  2598. SetWindowText (hwndCombo, buf);
  2599. }
  2600. break;
  2601. case IDC_COMBO1:
  2602. switch (HIWORD(wParam))
  2603. {
  2604. case CBN_SELCHANGE:
  2605. {
  2606. LRESULT lSel = SendMessage (hwndCombo, CB_GETCURSEL, 0, 0);
  2607. switch (pParamsHeader->aParams[lLastSel].dwType)
  2608. {
  2609. case PT_ORDINAL:
  2610. //
  2611. // The only option here is "select none"
  2612. //
  2613. strcpy (szComboText, "00000000");
  2614. PostMessage (hwnd, WM_USER+55, 0, 0);
  2615. break;
  2616. case PT_FLAGS:
  2617. {
  2618. BOOL bSelect = (lSel ? TRUE : FALSE);
  2619. SendMessage(
  2620. hwndList2,
  2621. LB_SETSEL,
  2622. (WPARAM) bSelect,
  2623. (LPARAM) -1
  2624. );
  2625. if (bSelect)
  2626. {
  2627. PLOOKUP pLookup = (PLOOKUP)
  2628. pParamsHeader->aParams[lLastSel].pLookup;
  2629. DWORD dwValue = 0;
  2630. int far *ai;
  2631. LONG i;
  2632. LRESULT lSelCount =
  2633. SendMessage (hwndList2, LB_GETSELCOUNT, 0, 0);
  2634. ai = (int far *) MyAlloc(
  2635. (size_t)lSelCount * sizeof(int)
  2636. );
  2637. SendMessage(
  2638. hwndList2,
  2639. LB_GETSELITEMS,
  2640. (WPARAM) lSelCount,
  2641. (LPARAM) ai
  2642. );
  2643. for (i = 0; i < lSelCount; i++)
  2644. {
  2645. dwValue |= pLookup[ai[i]].dwVal;
  2646. }
  2647. MyFree (ai);
  2648. wsprintf (szComboText, "%08lx", dwValue);
  2649. }
  2650. else
  2651. {
  2652. strcpy (szComboText, "00000000");
  2653. }
  2654. PostMessage (hwnd, WM_USER+55, 0, 0);
  2655. break;
  2656. }
  2657. case PT_STRING:
  2658. if (lSel == 1)
  2659. {
  2660. strncpy(
  2661. szComboText,
  2662. pParamsHeader->aParams[lLastSel].buf,
  2663. MAX_STRING_PARAM_SIZE
  2664. );
  2665. szComboText[MAX_STRING_PARAM_SIZE-1] = 0;
  2666. }
  2667. else
  2668. {
  2669. szComboText[0] = 0;
  2670. }
  2671. PostMessage (hwnd, WM_USER+55, 0, 0);
  2672. break;
  2673. case PT_DWORD:
  2674. break;
  2675. } // switch
  2676. break;
  2677. }
  2678. case CBN_EDITCHANGE:
  2679. {
  2680. //
  2681. // If user entered text in the edit field then copy the
  2682. // text to our buffer
  2683. //
  2684. if (pParamsHeader->aParams[lLastSel].dwType == PT_STRING)
  2685. {
  2686. char buf[MAX_STRING_PARAM_SIZE];
  2687. GetWindowText (hwndCombo, buf, MAX_STRING_PARAM_SIZE);
  2688. strncpy(
  2689. pParamsHeader->aParams[lLastSel].buf,
  2690. buf,
  2691. MAX_STRING_PARAM_SIZE
  2692. );
  2693. pParamsHeader->aParams[lLastSel].buf
  2694. [MAX_STRING_PARAM_SIZE-1] = 0;
  2695. }
  2696. break;
  2697. }
  2698. } // switch
  2699. } // switch
  2700. break;
  2701. }
  2702. case WM_USER+55:
  2703. SetWindowText (hwndCombo, szComboText);
  2704. break;
  2705. case WM_CTLCOLORSTATIC:
  2706. SetBkColor ((HDC) wParam, RGB (192,192,192));
  2707. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  2708. case WM_PAINT:
  2709. {
  2710. PAINTSTRUCT ps;
  2711. BeginPaint (hwnd, &ps);
  2712. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  2713. EndPaint (hwnd, &ps);
  2714. break;
  2715. }
  2716. }
  2717. return 0;
  2718. }