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.

4973 lines
147 KiB

  1. /*++ BUILD Version: 0000 // Increment this if a change has global effects
  2. Copyright (c) 1994-97 Microsoft Corporation
  3. Module Name:
  4. ui.c
  5. Abstract:
  6. Contains UI support for TAPI Browser util.
  7. Author:
  8. Dan Knudson (DanKn) 23-Oct-1994
  9. Revision History:
  10. --*/
  11. #include "tb.h"
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <stdarg.h>
  15. #include <string.h>
  16. #include <ctype.h>
  17. #include <io.h>
  18. #include <malloc.h>
  19. #include <time.h>
  20. #include <commdlg.h>
  21. #include "resource.h"
  22. #include "vars.h"
  23. extern char szdwSize[];
  24. extern char szdwAddressID[];
  25. HWND hwndEdit2;
  26. HFONT ghFixedFont;
  27. char gszEnterAs[32];
  28. BYTE aHex[] =
  29. {
  30. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  31. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  32. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  33. 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,255,255,255,255,255,255,
  34. 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255,
  35. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  36. 255, 10, 11, 12, 13, 14, 15,255,255,255,255,255,255,255,255,255,
  37. 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
  38. };
  39. char *
  40. PASCAL
  41. GetTimeStamp(
  42. void
  43. );
  44. void
  45. ShowStructByField(
  46. PSTRUCT_FIELD_HEADER pHeader,
  47. BOOL bSubStructure
  48. );
  49. void
  50. CompletionPortThread(
  51. LPVOID pParams
  52. );
  53. int
  54. WINAPI
  55. WinMain(
  56. HINSTANCE hInstance,
  57. HINSTANCE hPrevInstance,
  58. LPSTR lpCmdLine,
  59. int nCmdShow
  60. )
  61. {
  62. MSG msg;
  63. HWND hwnd;
  64. HACCEL hAccel;
  65. {
  66. DWORD d = 0x76543210;
  67. wsprintf(
  68. gszEnterAs,
  69. "Ex: enter x%x as %02x%02x%02x%02x",
  70. d,
  71. *((LPBYTE) &d),
  72. *(((LPBYTE) &d) + 1),
  73. *(((LPBYTE) &d) + 2),
  74. *(((LPBYTE) &d) + 3)
  75. );
  76. }
  77. ghInst = hInstance;
  78. hwnd = CreateDialog(
  79. ghInst,
  80. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG1),
  81. (HWND)NULL,
  82. (DLGPROC) MainWndProc
  83. );
  84. hwndEdit2 = CreateWindow ("edit", "", 0, 0, 0, 0, 0, NULL, NULL, ghInst, NULL);
  85. if (!hwndEdit2)
  86. {
  87. MessageBox (NULL, "err creating edit ctl", "", MB_OK);
  88. }
  89. hAccel = LoadAccelerators(
  90. ghInst,
  91. (LPCSTR)MAKEINTRESOURCE(IDR_ACCELERATOR1)
  92. );
  93. #if TAPI_2_0
  94. if ((ghCompletionPort = CreateIoCompletionPort(
  95. INVALID_HANDLE_VALUE,
  96. NULL,
  97. 0,
  98. 0
  99. )))
  100. {
  101. DWORD dwTID;
  102. HANDLE hThread;
  103. if ((hThread = CreateThread(
  104. (LPSECURITY_ATTRIBUTES) NULL,
  105. 0,
  106. (LPTHREAD_START_ROUTINE) CompletionPortThread,
  107. NULL,
  108. 0,
  109. &dwTID
  110. )))
  111. {
  112. CloseHandle (hThread);
  113. }
  114. else
  115. {
  116. ShowStr(
  117. "CreateThread(CompletionPortThread) failed, err=%d",
  118. GetLastError()
  119. );
  120. }
  121. }
  122. else
  123. {
  124. ShowStr ("CreateIoCompletionPort failed, err=%d", GetLastError());
  125. }
  126. #endif
  127. ghFixedFont = CreateFont(
  128. 13, 8, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 49, "Courier"
  129. );
  130. while (GetMessage (&msg, NULL, 0, 0))
  131. {
  132. if (!TranslateAccelerator (hwnd, hAccel, &msg))
  133. {
  134. TranslateMessage (&msg);
  135. DispatchMessage (&msg);
  136. }
  137. }
  138. DestroyWindow (hwndEdit2);
  139. return 0;
  140. }
  141. void
  142. CompletionPortThread(
  143. LPVOID pParams
  144. )
  145. {
  146. DWORD dwNumBytesTransfered;
  147. ULONG_PTR completionKey;
  148. LPLINEMESSAGE pMsg;
  149. while (GetQueuedCompletionStatus(
  150. ghCompletionPort,
  151. &dwNumBytesTransfered,
  152. &completionKey,
  153. (LPOVERLAPPED *) &pMsg,
  154. INFINITE
  155. ))
  156. {
  157. if (pMsg)
  158. {
  159. tapiCallback(
  160. pMsg->hDevice,
  161. pMsg->dwMessageID,
  162. pMsg->dwCallbackInstance,
  163. pMsg->dwParam1,
  164. pMsg->dwParam2,
  165. pMsg->dwParam3
  166. );
  167. LocalFree (pMsg);
  168. }
  169. else
  170. {
  171. break;
  172. }
  173. }
  174. }
  175. void
  176. GetCurrentSelections(
  177. void
  178. )
  179. {
  180. LRESULT lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0);
  181. PMYWIDGET pWidget = aWidgets;
  182. //
  183. // Init all pXxxSel ptrs to NULL
  184. //
  185. pLineAppSel = (PMYLINEAPP) NULL;
  186. pLineSel = (PMYLINE) NULL;
  187. pCallSel =
  188. pCallSel2 = (PMYCALL) NULL;
  189. pPhoneAppSel = (PMYPHONEAPP) NULL;
  190. pPhoneSel = (PMYPHONE) NULL;
  191. if (lSel != LB_ERR)
  192. {
  193. //
  194. // Find the selected widget & set globals appropriately
  195. //
  196. pWidget = (PMYWIDGET) SendMessage(
  197. ghwndList1,
  198. LB_GETITEMDATA,
  199. (WPARAM) lSel,
  200. 0
  201. );
  202. switch (pWidget->dwType)
  203. {
  204. case WT_LINEAPP:
  205. pLineAppSel = (PMYLINEAPP) pWidget;
  206. break;
  207. case WT_LINE:
  208. pLineSel = (PMYLINE) pWidget;
  209. pLineAppSel = pLineSel->pLineApp;
  210. break;
  211. case WT_CALL:
  212. pCallSel = (PMYCALL) pWidget;
  213. pLineSel = pCallSel->pLine;
  214. pLineAppSel = pCallSel->pLine->pLineApp;
  215. if (pWidget->pNext && (pWidget->pNext->dwType == WT_CALL))
  216. {
  217. pCallSel2 = (PMYCALL) pWidget->pNext;
  218. }
  219. else if ((((PMYWIDGET)pLineSel)->pNext != pWidget) &&
  220. (((PMYWIDGET)pLineSel)->pNext->dwType == WT_CALL))
  221. {
  222. pCallSel2 = (PMYCALL) (((PMYWIDGET)pLineSel)->pNext);
  223. }
  224. break;
  225. case WT_PHONEAPP:
  226. pPhoneAppSel = (PMYPHONEAPP) pWidget;
  227. break;
  228. case WT_PHONE:
  229. pPhoneSel = (PMYPHONE) pWidget;
  230. pPhoneAppSel = pPhoneSel->pPhoneApp;
  231. break;
  232. }
  233. }
  234. //
  235. // The following is an attempt to up the usability level a little bit.
  236. // Most folks are going to be messing around with 1 lineapp/line/call
  237. // at a time, and it'd end up being a real PITA for them to have to
  238. // select a widget each time (and it's fairly obvious which widget
  239. // are referring to). So we're going to try to make some intelligent
  240. // decisions in case they haven't selected a widget... (Obviously this
  241. // could be cleaned up a bit, like maybe maintaining dwNumXxx as
  242. // globals rather than walking the list each time.)
  243. //
  244. {
  245. DWORD dwNumLineApps = 0, dwNumLines = 0, dwNumCalls = 0,
  246. dwNumPhoneApps = 0, dwNumPhones = 0;
  247. PMYPHONEAPP pPhoneApp = NULL;
  248. pWidget = aWidgets;
  249. while (pWidget)
  250. {
  251. switch (pWidget->dwType)
  252. {
  253. case WT_LINEAPP:
  254. dwNumLineApps++;
  255. break;
  256. case WT_LINE:
  257. dwNumLines++;
  258. break;
  259. case WT_CALL:
  260. dwNumCalls++;
  261. break;
  262. case WT_PHONEAPP:
  263. dwNumPhoneApps++;
  264. if (dwNumPhoneApps == 1)
  265. {
  266. pPhoneApp = (PMYPHONEAPP) pWidget;
  267. }
  268. break;
  269. case WT_PHONE:
  270. dwNumPhones++;
  271. break;
  272. }
  273. pWidget = pWidget->pNext;
  274. }
  275. if (dwNumLineApps == 1)
  276. {
  277. pLineAppSel = (PMYLINEAPP) aWidgets;
  278. if (dwNumLines == 1)
  279. {
  280. pLineSel = (PMYLINE) pLineAppSel->Widget.pNext;
  281. if (dwNumCalls == 1)
  282. {
  283. pCallSel = (PMYCALL) pLineSel->Widget.pNext;
  284. }
  285. }
  286. }
  287. if (dwNumPhoneApps == 1)
  288. {
  289. pPhoneAppSel = (PMYPHONEAPP) pPhoneApp;
  290. if (dwNumPhones == 1)
  291. {
  292. pPhoneSel = (PMYPHONE) pPhoneAppSel->Widget.pNext;
  293. }
  294. }
  295. }
  296. }
  297. /* help
  298. VOID
  299. MyWinHelp(
  300. HWND hwndOwner,
  301. BOOL bTapiHlp,
  302. UINT uiCommand,
  303. DWORD dwData
  304. )
  305. {
  306. char *lpszHelpFile = (bTapiHlp ? szTapiHlp : szTspiHlp);
  307. if (lpszHelpFile[0] == 0 || _access (lpszHelpFile, 0))
  308. {
  309. //
  310. // Prompt user for helpfile path
  311. //
  312. OPENFILENAME ofn;
  313. char szDirName[256] = ".\\";
  314. char szFile[256] = "tapi.hlp\0";
  315. char szFileTitle[256] = "";
  316. char szFilter[] = "Telephony API Help\0tapi.hlp\0\0";
  317. if (MessageBox(
  318. hwndOwner,
  319. "Help file not found- do you want to specify a new help file?",
  320. "Warning",
  321. MB_YESNO
  322. ) == IDNO)
  323. {
  324. return;
  325. }
  326. if (!bTapiHlp)
  327. {
  328. szFile[1] = 's';
  329. szFilter[10] = 'S';
  330. szFilter[20] = 's';
  331. }
  332. ofn.lStructSize = sizeof(OPENFILENAME);
  333. ofn.hwndOwner = hwndOwner;
  334. ofn.lpstrFilter = szFilter;
  335. ofn.lpstrCustomFilter = (LPSTR) NULL;
  336. ofn.nMaxCustFilter = 0L;
  337. ofn.nFilterIndex = 1;
  338. ofn.lpstrFile = szFile;
  339. ofn.nMaxFile = sizeof(szFile);
  340. ofn.lpstrFileTitle = szFileTitle;
  341. ofn.nMaxFileTitle = sizeof(szFileTitle);
  342. ofn.lpstrInitialDir = szDirName;
  343. ofn.lpstrTitle = (LPSTR) NULL;
  344. ofn.Flags = 0L;
  345. ofn.nFileOffset = 0;
  346. ofn.nFileExtension = 0;
  347. ofn.lpstrDefExt = "HLP";
  348. if (!GetOpenFileName(&ofn))
  349. {
  350. return;
  351. }
  352. strcpy (lpszHelpFile, szFile);
  353. }
  354. if (!WinHelp (ghwndMain, (LPCSTR) lpszHelpFile, uiCommand, dwData))
  355. {
  356. lpszHelpFile[0] = 0;
  357. }
  358. }
  359. */
  360. INT_PTR
  361. CALLBACK
  362. MainWndProc(
  363. HWND hwnd,
  364. UINT msg,
  365. WPARAM wParam,
  366. LPARAM lParam
  367. )
  368. {
  369. static HICON hIcon;
  370. static HMENU hMenu;
  371. static int icyButton, icyBorder;
  372. static HFONT hFont, hFont2;
  373. int i;
  374. static LONG cxList1, cxList2, cxWnd, xCapture, cxVScroll, lCaptureFlags = 0;
  375. static int cyWnd;
  376. typedef struct _XXX
  377. {
  378. DWORD dwMenuID;
  379. DWORD dwFlags;
  380. } XXX, *PXXX;
  381. static XXX aXxx[] =
  382. {
  383. { IDM_LOGSTRUCTDWORD ,DS_BYTEDUMP },
  384. { IDM_LOGSTRUCTALLFIELD ,DS_NONZEROFIELDS|DS_ZEROFIELDS },
  385. { IDM_LOGSTRUCTNONZEROFIELD ,DS_NONZEROFIELDS },
  386. { IDM_LOGSTRUCTNONE ,0 }
  387. };
  388. switch (msg)
  389. {
  390. case WM_INITDIALOG:
  391. {
  392. RECT rect;
  393. char buf[64];
  394. ghwndMain = hwnd;
  395. ghwndList1 = GetDlgItem (hwnd, IDC_LIST1);
  396. ghwndList2 = GetDlgItem (hwnd, IDC_LIST2);
  397. ghwndEdit = GetDlgItem (hwnd, IDC_EDIT1);
  398. hMenu = GetMenu (hwnd);
  399. hIcon = LoadIcon (ghInst, MAKEINTRESOURCE(IDI_ICON1));
  400. icyBorder = GetSystemMetrics (SM_CYFRAME);
  401. cxVScroll = 2*GetSystemMetrics (SM_CXVSCROLL);
  402. GetWindowRect (GetDlgItem (hwnd, IDC_BUTTON1), &rect);
  403. icyButton = (rect.bottom - rect.top) + icyBorder + 3;
  404. for (i = 0; aFuncNames[i]; i++)
  405. {
  406. SendMessage(
  407. ghwndList2,
  408. LB_INSERTSTRING,
  409. (WPARAM) -1,
  410. (LPARAM) aFuncNames[i]
  411. );
  412. }
  413. SendMessage (ghwndList2, LB_SETCURSEL, (WPARAM) lInitialize, 0);
  414. #ifdef WIN32
  415. SetWindowText (hwnd, "TAPI32 Browser");
  416. #else
  417. SetWindowText (hwnd, "TAPI16 Browser");
  418. #endif
  419. //
  420. // Read in defaults from ini file
  421. //
  422. {
  423. typedef struct _DEF_VALUE
  424. {
  425. char far *lpszEntry;
  426. char far *lpszDefValue;
  427. LPVOID lp;
  428. } DEF_VALUE;
  429. DEF_VALUE aDefVals[] =
  430. {
  431. { "BufSize", "1000", &dwBigBufSize },
  432. { "AddressID", "0", &dwDefAddressID },
  433. #if TAPI_2_0
  434. { "20LineAPIVersion", "20000", &dwDefLineAPIVersion },
  435. #else
  436. #if TAPI_1_1
  437. { "14LineAPIVersion", "10004", &dwDefLineAPIVersion },
  438. #else
  439. { "13LineAPIVersion", "10003", &dwDefLineAPIVersion },
  440. #endif
  441. #endif
  442. { "BearerMode", "1", &dwDefBearerMode },
  443. { "CountryCode", "0", &dwDefCountryCode },
  444. { "LineDeviceID", "0", &dwDefLineDeviceID },
  445. { "LineExtVersion", "0", &dwDefLineExtVersion },
  446. { "MediaMode", "10", &dwDefMediaMode }, // DATAMODEM
  447. { "LinePrivilege", "1", &dwDefLinePrivilege }, // NONE (dialout only)
  448. #if TAPI_2_0
  449. { "20PhoneAPIVersion", "20000", &dwDefPhoneAPIVersion },
  450. #else
  451. #if TAPI_1_1
  452. { "14PhoneAPIVersion", "10004", &dwDefPhoneAPIVersion },
  453. #else
  454. { "13PhoneAPIVersion", "10003", &dwDefPhoneAPIVersion },
  455. #endif
  456. #endif
  457. { "PhoneDeviceID", "0", &dwDefPhoneDeviceID },
  458. { "PhoneExtVersion", "0", &dwDefPhoneExtVersion },
  459. { "PhonePrivilege", "2", &dwDefPhonePrivilege }, // OWNER
  460. #if TAPI_2_0
  461. { "20UserButton1", "500", aUserButtonFuncs },
  462. { "20UserButton2", "500", aUserButtonFuncs + 1 },
  463. { "20UserButton3", "500", aUserButtonFuncs + 2 },
  464. { "20UserButton4", "500", aUserButtonFuncs + 3 },
  465. { "20UserButton5", "500", aUserButtonFuncs + 4 },
  466. { "20UserButton6", "500", aUserButtonFuncs + 5 },
  467. #else
  468. #if TAPI_1_1
  469. { "14UserButton1", "500", aUserButtonFuncs },
  470. { "14UserButton2", "500", aUserButtonFuncs + 1 },
  471. { "14UserButton3", "500", aUserButtonFuncs + 2 },
  472. { "14UserButton4", "500", aUserButtonFuncs + 3 },
  473. { "14UserButton5", "500", aUserButtonFuncs + 4 },
  474. { "14UserButton6", "500", aUserButtonFuncs + 5 },
  475. #else
  476. { "13UserButton1", "500", aUserButtonFuncs },
  477. { "13UserButton2", "500", aUserButtonFuncs + 1 },
  478. { "13UserButton3", "500", aUserButtonFuncs + 2 },
  479. { "13UserButton4", "500", aUserButtonFuncs + 3 },
  480. { "13UserButton5", "500", aUserButtonFuncs + 4 },
  481. { "13UserButton6", "500", aUserButtonFuncs + 5 },
  482. #endif
  483. #endif
  484. { "TimeStamp", "0", &bTimeStamp },
  485. { "NukeIdleMonitorCalls", "1", &bNukeIdleMonitorCalls },
  486. { "NukeIdleOwnedCalls", "0", &bNukeIdleOwnedCalls },
  487. { "DisableHandleChecking", "0", &gbDisableHandleChecking },
  488. { "DumpStructsFlags", "1", &dwDumpStructsFlags },
  489. { NULL, NULL, NULL },
  490. { "UserUserInfo", "my user user info", szDefUserUserInfo },
  491. { "DestAddress", "55555", szDefDestAddress },
  492. { "LineDeviceClass", "tapi/line", szDefLineDeviceClass },
  493. { "PhoneDeviceClass", "tapi/phone", szDefPhoneDeviceClass },
  494. { "AppName", "Tapi Browser", szDefAppName },
  495. { NULL, NULL, NULL },
  496. #if TAPI_2_0
  497. { "20UserButton1Text", "", &aUserButtonsText[0] },
  498. { "20UserButton2Text", "", &aUserButtonsText[1] },
  499. { "20UserButton3Text", "", &aUserButtonsText[2] },
  500. { "20UserButton4Text", "", &aUserButtonsText[3] },
  501. { "20UserButton5Text", "", &aUserButtonsText[4] },
  502. { "20UserButton6Text", "", &aUserButtonsText[5] },
  503. #else
  504. #if TAPI_1_1
  505. { "14UserButton1Text", "", &aUserButtonsText[0] },
  506. { "14UserButton2Text", "", &aUserButtonsText[1] },
  507. { "14UserButton3Text", "", &aUserButtonsText[2] },
  508. { "14UserButton4Text", "", &aUserButtonsText[3] },
  509. { "14UserButton5Text", "", &aUserButtonsText[4] },
  510. { "14UserButton6Text", "", &aUserButtonsText[5] },
  511. #else
  512. { "13UserButton1Text", "", &aUserButtonsText[0] },
  513. { "13UserButton2Text", "", &aUserButtonsText[1] },
  514. { "13UserButton3Text", "", &aUserButtonsText[2] },
  515. { "13UserButton4Text", "", &aUserButtonsText[3] },
  516. { "13UserButton5Text", "", &aUserButtonsText[4] },
  517. { "13UserButton6Text", "", &aUserButtonsText[5] },
  518. #endif
  519. #endif
  520. { NULL, NULL, NULL }
  521. };
  522. int i, j;
  523. #define MYSECTION "Tapi Browser"
  524. for (i = 0; aDefVals[i].lpszEntry; i++)
  525. {
  526. GetProfileString(
  527. MYSECTION,
  528. aDefVals[i].lpszEntry,
  529. aDefVals[i].lpszDefValue,
  530. buf,
  531. 15
  532. );
  533. sscanf (buf, "%lx", aDefVals[i].lp);
  534. }
  535. i++;
  536. for (; aDefVals[i].lpszEntry; i++)
  537. {
  538. GetProfileString(
  539. MYSECTION,
  540. aDefVals[i].lpszEntry,
  541. aDefVals[i].lpszDefValue,
  542. (LPSTR) aDefVals[i].lp,
  543. MAX_STRING_PARAM_SIZE - 1
  544. );
  545. }
  546. i++;
  547. for (j = i; aDefVals[i].lpszEntry; i++)
  548. {
  549. GetProfileString(
  550. MYSECTION,
  551. aDefVals[i].lpszEntry,
  552. aDefVals[i].lpszDefValue,
  553. (LPSTR) aDefVals[i].lp,
  554. MAX_USER_BUTTON_TEXT_SIZE - 1
  555. );
  556. SetDlgItemText(
  557. hwnd,
  558. IDC_BUTTON13 + (i - j),
  559. (LPCSTR)aDefVals[i].lp
  560. );
  561. }
  562. lpszDefAppName = szDefAppName;
  563. lpszDefUserUserInfo = szDefUserUserInfo;
  564. lpszDefDestAddress = szDefDestAddress;
  565. lpszDefLineDeviceClass = szDefLineDeviceClass;
  566. lpszDefPhoneDeviceClass = szDefPhoneDeviceClass;
  567. if (GetProfileString (
  568. MYSECTION,
  569. "Version",
  570. "",
  571. buf,
  572. 15
  573. ) == 0 || (strcmp (buf, szCurrVer)))
  574. {
  575. //
  576. // If here assume this is first time user had started
  577. // TB, so post a msg that will automatically bring up
  578. // the hlp dlg
  579. //
  580. PostMessage (hwnd, WM_COMMAND, IDM_USINGTB, 0);
  581. }
  582. // help GetProfileString (MYSECTION, "TapiHlpPath", "", szTapiHlp, 256);
  583. // help GetProfileString (MYSECTION, "TspiHlpPath", "", szTspiHlp, 256);
  584. }
  585. pBigBuf = malloc ((size_t)dwBigBufSize);
  586. {
  587. //HFONT hFontMenu = SendMessage (hMenu, WM_GETFONT, 0, 0);
  588. hFont = CreateFont(
  589. 13, 5, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 34, "MS Sans Serif"
  590. );
  591. hFont2 = CreateFont(
  592. 13, 8, 0, 0, 400, 0, 0, 0, 0, 1, 2, 1, 49, "Courier"
  593. );
  594. for (i = 0; i < 18; i++)
  595. {
  596. SendDlgItemMessage(
  597. hwnd,
  598. IDC_BUTTON1 + i,
  599. WM_SETFONT,
  600. (WPARAM) hFont,
  601. 0
  602. );
  603. }
  604. SendMessage (ghwndList1, WM_SETFONT, (WPARAM) hFont, 0);
  605. SendMessage (ghwndList2, WM_SETFONT, (WPARAM) hFont, 0);
  606. SendMessage (ghwndEdit, WM_SETFONT, (WPARAM) hFont2, 0);
  607. }
  608. GetProfileString(
  609. MYSECTION,
  610. "ControlRatios",
  611. "20, 20, 100",
  612. buf,
  613. 63
  614. );
  615. sscanf (buf, "%ld,%ld,%ld", &cxList2, &cxList1, &cxWnd);
  616. GetProfileString(
  617. MYSECTION,
  618. "Position",
  619. "max",
  620. buf,
  621. 63
  622. );
  623. if (strcmp (buf, "max") == 0)
  624. {
  625. ShowWindow (hwnd, SW_SHOWMAXIMIZED);
  626. }
  627. else
  628. {
  629. int left = 100, top = 100, right = 600, bottom = 400;
  630. sscanf (buf, "%d,%d,%d,%d", &left, &top, &right, &bottom);
  631. //
  632. // Check to see if wnd pos is wacky, if so reset to reasonable vals
  633. //
  634. if (left < 0 ||
  635. left >= (GetSystemMetrics (SM_CXSCREEN) - 32) ||
  636. top < 0 ||
  637. top >= (GetSystemMetrics (SM_CYSCREEN) - 32))
  638. {
  639. left = top = 100;
  640. right = 600;
  641. bottom = 400;
  642. }
  643. SetWindowPos(
  644. hwnd,
  645. HWND_TOP,
  646. left,
  647. top,
  648. right - left,
  649. bottom - top,
  650. SWP_SHOWWINDOW
  651. );
  652. GetClientRect (hwnd, &rect);
  653. SendMessage(
  654. hwnd,
  655. WM_SIZE,
  656. 0,
  657. MAKELONG((rect.right-rect.left),(rect.bottom-rect.top))
  658. );
  659. ShowWindow (hwnd, SW_SHOW);
  660. }
  661. for (i = 0; aXxx[i].dwFlags != dwDumpStructsFlags; i++);
  662. CheckMenuItem (hMenu, aXxx[i].dwMenuID, MF_BYCOMMAND | MF_CHECKED);
  663. CheckMenuItem(
  664. hMenu,
  665. IDM_TIMESTAMP,
  666. MF_BYCOMMAND | (bTimeStamp ? MF_CHECKED : MF_UNCHECKED)
  667. );
  668. CheckMenuItem(
  669. hMenu,
  670. IDM_NUKEIDLEMONITORCALLS,
  671. MF_BYCOMMAND | (bNukeIdleMonitorCalls ? MF_CHECKED : MF_UNCHECKED)
  672. );
  673. CheckMenuItem(
  674. hMenu,
  675. IDM_NUKEIDLEOWNEDCALLS,
  676. MF_BYCOMMAND | (bNukeIdleOwnedCalls ? MF_CHECKED : MF_UNCHECKED)
  677. );
  678. CheckMenuItem(
  679. hMenu,
  680. IDM_NOHANDLECHK,
  681. MF_BYCOMMAND | (gbDisableHandleChecking ? MF_CHECKED : MF_UNCHECKED)
  682. );
  683. //
  684. // Alloc & init the global call params
  685. //
  686. #if TAPI_2_0
  687. lpCallParamsW = NULL;
  688. init_call_params:
  689. #endif
  690. {
  691. #if TAPI_2_0
  692. size_t callParamsSize =
  693. sizeof(LINECALLPARAMS) + 15 * MAX_STRING_PARAM_SIZE;
  694. #else
  695. size_t callParamsSize =
  696. sizeof(LINECALLPARAMS) + 8 * MAX_STRING_PARAM_SIZE;
  697. #endif
  698. if ((lpCallParams = (LPLINECALLPARAMS) malloc (callParamsSize)))
  699. {
  700. LPDWORD lpdwXxxOffset = &lpCallParams->dwOrigAddressOffset;
  701. memset (lpCallParams, 0, callParamsSize);
  702. lpCallParams->dwTotalSize = (DWORD) callParamsSize;
  703. lpCallParams->dwBearerMode = LINEBEARERMODE_VOICE;
  704. lpCallParams->dwMinRate = 3100;
  705. lpCallParams->dwMaxRate = 3100;
  706. lpCallParams->dwMediaMode = LINEMEDIAMODE_INTERACTIVEVOICE;
  707. lpCallParams->dwAddressMode = LINEADDRESSMODE_ADDRESSID;
  708. for (i = 0; i < 8; i++)
  709. {
  710. *(lpdwXxxOffset + 2*i) =
  711. sizeof(LINECALLPARAMS) + i*MAX_STRING_PARAM_SIZE;
  712. }
  713. #if TAPI_2_0
  714. {
  715. LPDWORD pdwProxyRequests = (LPDWORD)
  716. (((LPBYTE) lpCallParams) +
  717. lpCallParams->dwDevSpecificOffset);
  718. for (i = 0; i < 8; i++)
  719. {
  720. *(pdwProxyRequests + i) = i +
  721. LINEPROXYREQUEST_SETAGENTGROUP;
  722. }
  723. }
  724. lpdwXxxOffset = &lpCallParams->dwTargetAddressOffset;
  725. for (i = 0; i < 6; i++)
  726. {
  727. *(lpdwXxxOffset + 2 * i) =
  728. sizeof(LINECALLPARAMS) + (8+i)*MAX_STRING_PARAM_SIZE;
  729. }
  730. lpCallParams->dwCallingPartyIDOffset =
  731. sizeof(LINECALLPARAMS) + 14 * MAX_STRING_PARAM_SIZE;
  732. if (!lpCallParamsW)
  733. {
  734. lpCallParamsW = lpCallParams;
  735. goto init_call_params;
  736. }
  737. #endif
  738. }
  739. else
  740. {
  741. // BUGBUG
  742. }
  743. }
  744. break;
  745. }
  746. case WM_COMMAND:
  747. {
  748. FUNC_INDEX funcIndex;
  749. BOOL bShowParamsSave = bShowParams;
  750. switch (LOWORD(wParam))
  751. {
  752. case IDC_EDIT1:
  753. #ifdef WIN32
  754. if (HIWORD(wParam) == EN_CHANGE)
  755. #else
  756. if (HIWORD(lParam) == EN_CHANGE)
  757. #endif
  758. {
  759. //
  760. // Watch to see if the edit control is full, & if so
  761. // purge the top half of the text to make room for more
  762. //
  763. int length = GetWindowTextLength (ghwndEdit);
  764. if (length > 29998)
  765. {
  766. #ifdef WIN32
  767. SendMessage(
  768. ghwndEdit,
  769. EM_SETSEL,
  770. (WPARAM) 0,
  771. (LPARAM) 10000
  772. );
  773. #else
  774. SendMessage(
  775. ghwndEdit,
  776. EM_SETSEL,
  777. (WPARAM) 1,
  778. (LPARAM) MAKELONG (0, 10000)
  779. );
  780. #endif
  781. SendMessage(
  782. ghwndEdit,
  783. EM_REPLACESEL,
  784. 0,
  785. (LPARAM) (char far *) ""
  786. );
  787. #ifdef WIN32
  788. SendMessage(
  789. ghwndEdit,
  790. EM_SETSEL,
  791. (WPARAM)0xfffffffd,
  792. (LPARAM)0xfffffffe
  793. );
  794. #else
  795. SendMessage(
  796. ghwndEdit,
  797. EM_SETSEL,
  798. (WPARAM)1,
  799. (LPARAM) MAKELONG (0xfffd, 0xfffe)
  800. );
  801. #endif
  802. }
  803. }
  804. break;
  805. case IDC_BUTTON1:
  806. funcIndex = lInitialize;
  807. goto IDC_BUTTON10_callFuncDriver;
  808. case IDC_BUTTON2:
  809. funcIndex = lShutdown;
  810. goto IDC_BUTTON10_callFuncDriver;
  811. case IDC_BUTTON3:
  812. funcIndex = lOpen;
  813. goto IDC_BUTTON10_callFuncDriver;
  814. case IDC_BUTTON4:
  815. funcIndex = lClose;
  816. goto IDC_BUTTON10_callFuncDriver;
  817. case IDC_BUTTON5:
  818. funcIndex = lMakeCall;
  819. goto IDC_BUTTON10_callFuncDriver;
  820. case IDC_BUTTON6:
  821. GetCurrentSelections();
  822. if (pCallSel && (pCallSel->dwCallState == LINECALLSTATE_IDLE))
  823. {
  824. funcIndex = lDeallocateCall;
  825. }
  826. else
  827. {
  828. funcIndex = lDrop;
  829. gbDeallocateCall = TRUE;
  830. }
  831. FuncDriver (funcIndex);
  832. gbDeallocateCall = FALSE;
  833. break;
  834. case IDC_BUTTON7:
  835. funcIndex = pInitialize;
  836. goto IDC_BUTTON10_callFuncDriver;
  837. case IDC_BUTTON8:
  838. funcIndex = pShutdown;
  839. goto IDC_BUTTON10_callFuncDriver;
  840. case IDC_BUTTON9:
  841. funcIndex = pOpen;
  842. goto IDC_BUTTON10_callFuncDriver;
  843. case IDC_BUTTON10:
  844. funcIndex = pClose;
  845. IDC_BUTTON10_callFuncDriver:
  846. //
  847. // Want to make the "hot buttons" as simple as possible, so
  848. // turn off the show params flag, then call FuncDriver, and
  849. // finally restore the flag
  850. //
  851. GetCurrentSelections ();
  852. FuncDriver (funcIndex);
  853. break;
  854. case IDC_BUTTON11:
  855. case IDM_CLEAR:
  856. SetWindowText (ghwndEdit, "");
  857. break;
  858. case IDM_PARAMS:
  859. case IDC_BUTTON12:
  860. bShowParams = (bShowParams ? FALSE : TRUE);
  861. if (bShowParams)
  862. {
  863. CheckMenuItem(
  864. hMenu,
  865. IDM_PARAMS,
  866. MF_BYCOMMAND | MF_CHECKED
  867. );
  868. CheckDlgButton (hwnd, IDC_BUTTON12, 1);
  869. }
  870. else
  871. {
  872. CheckMenuItem(
  873. hMenu,
  874. IDM_PARAMS,
  875. MF_BYCOMMAND | MF_UNCHECKED
  876. );
  877. CheckDlgButton (hwnd, IDC_BUTTON12, 0);
  878. }
  879. break;
  880. case IDC_BUTTON13:
  881. case IDC_BUTTON14:
  882. case IDC_BUTTON15:
  883. case IDC_BUTTON16:
  884. case IDC_BUTTON17:
  885. case IDC_BUTTON18:
  886. {
  887. DWORD i = (DWORD) (LOWORD(wParam)) - IDC_BUTTON13;
  888. if (aUserButtonFuncs[i] >= MiscBegin)
  889. {
  890. //
  891. // Hot button func id is bogus, so bring
  892. // up hot button init dlg
  893. //
  894. DialogBoxParam(
  895. ghInst,
  896. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  897. (HWND) hwnd,
  898. (DLGPROC) UserButtonsDlgProc,
  899. (LPARAM) &i
  900. );
  901. }
  902. else
  903. {
  904. //
  905. // Invoke the user button's corresponding func
  906. //
  907. GetCurrentSelections ();
  908. FuncDriver ((FUNC_INDEX) aUserButtonFuncs[i]);
  909. }
  910. break;
  911. }
  912. /* help case IDC_F1HELP:
  913. if ((GetFocus() == ghwndEdit) &&
  914. SendMessage (ghwndEdit, EM_GETSEL, 0, 0))
  915. {
  916. //
  917. // Display help for the selected text in the edit ctrl
  918. //
  919. char buf[32];
  920. //
  921. // Copy the selected text in the edit ctrl to our
  922. // temp edit control, then query the temp edit ctrl's
  923. // text (this seems to be the easiest way to get the
  924. // selected text)
  925. //
  926. SendMessage (ghwndEdit, WM_COPY, 0, 0);
  927. SetWindowText (hwndEdit2, "");
  928. SendMessage (hwndEdit2, WM_PASTE, 0, 0);
  929. //
  930. // In the interest of getting an exact match on a
  931. // helpfile key strip off any trailing spaces
  932. //
  933. GetWindowText (hwndEdit2, buf, 32);
  934. buf[31] = 0;
  935. for (i = 0; i < 32; i++)
  936. {
  937. if (buf[i] == ' ')
  938. {
  939. buf[i] = 0;
  940. break;
  941. }
  942. }
  943. MyWinHelp (hwnd, TRUE, HELP_PARTIALKEY, buf);
  944. }
  945. else
  946. {
  947. //
  948. // Display help for the currently selected func
  949. //
  950. FUNC_INDEX funcIndex = (FUNC_INDEX)
  951. SendMessage (ghwndList2, LB_GETCURSEL, 0, 0);
  952. MyWinHelp (hwnd, TRUE, HELP_PARTIALKEY, aFuncNames[funcIndex]);
  953. }
  954. break;
  955. */
  956. case IDC_PREVCTRL:
  957. {
  958. HWND hwndPrev = GetNextWindow (GetFocus (), GW_HWNDPREV);
  959. if (!hwndPrev)
  960. {
  961. hwndPrev = ghwndList2;
  962. }
  963. SetFocus (hwndPrev);
  964. break;
  965. }
  966. case IDC_NEXTCTRL:
  967. {
  968. HWND hwndNext = GetNextWindow (GetFocus (), GW_HWNDNEXT);
  969. if (!hwndNext)
  970. {
  971. hwndNext = GetDlgItem (hwnd, IDC_BUTTON12);
  972. }
  973. SetFocus (hwndNext);
  974. break;
  975. }
  976. case IDC_ENTER:
  977. {
  978. if (GetFocus() != ghwndEdit)
  979. {
  980. GetCurrentSelections ();
  981. FuncDriver(
  982. (FUNC_INDEX)SendMessage(
  983. ghwndList2,
  984. LB_GETCURSEL,
  985. 0,
  986. 0
  987. ));
  988. }
  989. else
  990. {
  991. // Send the edit ctrl a cr/lf
  992. }
  993. break;
  994. }
  995. case IDC_LIST1:
  996. #ifdef WIN32
  997. switch (HIWORD(wParam))
  998. #else
  999. switch (HIWORD(lParam))
  1000. #endif
  1001. {
  1002. case LBN_DBLCLK:
  1003. {
  1004. LRESULT lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0);
  1005. PMYWIDGET pWidget;
  1006. pWidget = (PMYWIDGET) SendMessage(
  1007. ghwndList1,
  1008. LB_GETITEMDATA,
  1009. (WPARAM) lSel,
  1010. 0
  1011. );
  1012. if ((pWidget->dwType == WT_LINEAPP)
  1013. || (pWidget->dwType == WT_PHONEAPP)
  1014. )
  1015. {
  1016. break;
  1017. }
  1018. bShowParams = FALSE;
  1019. UpdateResults (TRUE);
  1020. switch (pWidget->dwType)
  1021. {
  1022. case WT_LINE:
  1023. {
  1024. DWORD dwDefLineDeviceIDSave = dwDefLineDeviceID;
  1025. PMYLINE pLine = (PMYLINE) pWidget;
  1026. dwDefLineDeviceID = pLine->dwDevID;
  1027. pLineAppSel = GetLineApp (pLine->hLineApp);
  1028. pLineSel = pLine;
  1029. FuncDriver (lGetDevCaps);
  1030. FuncDriver (lGetLineDevStatus);
  1031. dwDefLineDeviceID = dwDefLineDeviceIDSave;
  1032. break;
  1033. }
  1034. case WT_CALL:
  1035. {
  1036. PMYCALL pCall = (PMYCALL) pWidget;
  1037. pCallSel = pCall;
  1038. pLineSel = pCall->pLine;
  1039. FuncDriver (lGetCallInfo);
  1040. FuncDriver (lGetCallStatus);
  1041. break;
  1042. }
  1043. case WT_PHONE:
  1044. {
  1045. DWORD dwDefPhoneDeviceIDSave = dwDefPhoneDeviceID;
  1046. PMYPHONE pPhone = (PMYPHONE) pWidget;
  1047. dwDefPhoneDeviceID = pPhone->dwDevID;
  1048. pPhoneAppSel = GetPhoneApp (pPhone->hPhoneApp);
  1049. pPhoneSel = pPhone;
  1050. FuncDriver (pGetDevCaps);
  1051. FuncDriver (pGetStatus);
  1052. dwDefPhoneDeviceID = dwDefPhoneDeviceIDSave;
  1053. break;
  1054. }
  1055. }
  1056. UpdateResults (FALSE);
  1057. bShowParams = bShowParamsSave;
  1058. break;
  1059. }
  1060. } // switch
  1061. break;
  1062. case IDC_LIST2:
  1063. #ifdef WIN32
  1064. if (HIWORD(wParam) == LBN_DBLCLK)
  1065. #else
  1066. if (HIWORD(lParam) == LBN_DBLCLK)
  1067. #endif
  1068. {
  1069. GetCurrentSelections ();
  1070. FuncDriver(
  1071. (FUNC_INDEX)SendMessage(
  1072. ghwndList2,
  1073. LB_GETCURSEL,
  1074. 0,
  1075. 0
  1076. ));
  1077. }
  1078. break;
  1079. case IDM_EXIT:
  1080. {
  1081. PostMessage (hwnd, WM_CLOSE, 0, 0);
  1082. break;
  1083. }
  1084. case IDM_DEFAULTVALUES:
  1085. {
  1086. char szTmpAppName[MAX_STRING_PARAM_SIZE];
  1087. char szTmpUserUserInfo[MAX_STRING_PARAM_SIZE];
  1088. char szTmpDestAddress[MAX_STRING_PARAM_SIZE];
  1089. char szTmpLineDeviceClass[MAX_STRING_PARAM_SIZE];
  1090. char szTmpPhoneDeviceClass[MAX_STRING_PARAM_SIZE];
  1091. FUNC_PARAM params[] =
  1092. {
  1093. { "Buffer size", PT_DWORD, (ULONG_PTR) dwBigBufSize, NULL },
  1094. { "lpszAppName", PT_STRING, (ULONG_PTR) lpszDefAppName, szTmpAppName },
  1095. { "line: dwAddressID", PT_DWORD, (ULONG_PTR) dwDefAddressID, NULL },
  1096. { "line: dwAPIVersion", PT_ORDINAL,(ULONG_PTR) dwDefLineAPIVersion, aAPIVersions },
  1097. { "line: dwBearerMode", PT_FLAGS, (ULONG_PTR) dwDefBearerMode, aBearerModes },
  1098. { "line: dwCountryCode", PT_DWORD, (ULONG_PTR) dwDefCountryCode, NULL },
  1099. { "line: dwDeviceID", PT_DWORD, (ULONG_PTR) dwDefLineDeviceID, NULL },
  1100. { "line: dwExtVersion", PT_DWORD, (ULONG_PTR) dwDefLineExtVersion, NULL },
  1101. { "line: dwMediaMode", PT_FLAGS, (ULONG_PTR) dwDefMediaMode, aMediaModes },
  1102. { "line: dwPrivileges", PT_FLAGS, (ULONG_PTR) dwDefLinePrivilege, aLineOpenOptions },
  1103. { "line: lpsUserUserInfo", PT_STRING, (ULONG_PTR) lpszDefUserUserInfo, szTmpUserUserInfo },
  1104. { "line: lpszDestAddress", PT_STRING, (ULONG_PTR) lpszDefDestAddress, szTmpDestAddress },
  1105. { "line: lpszDeviceClass", PT_STRING, (ULONG_PTR) lpszDefLineDeviceClass, szTmpLineDeviceClass },
  1106. { "phone: dwAPIVersion", PT_ORDINAL,(ULONG_PTR) dwDefPhoneAPIVersion, aAPIVersions },
  1107. { "phone: dwDeviceID", PT_DWORD, (ULONG_PTR) dwDefPhoneDeviceID, NULL },
  1108. { "phone: dwExtVersion", PT_DWORD, (ULONG_PTR) dwDefPhoneExtVersion, NULL },
  1109. { "phone: dwPrivilege", PT_FLAGS, (ULONG_PTR) dwDefPhonePrivilege, aPhonePrivileges },
  1110. { "phone: lpszDeviceClass", PT_STRING, (ULONG_PTR) lpszDefPhoneDeviceClass, szTmpPhoneDeviceClass }
  1111. };
  1112. FUNC_PARAM_HEADER paramsHeader =
  1113. { 18, DefValues, params, NULL };
  1114. BOOL bShowParamsSave = bShowParams;
  1115. bShowParams = TRUE;
  1116. strcpy (szTmpAppName, szDefAppName);
  1117. strcpy (szTmpUserUserInfo, szDefUserUserInfo);
  1118. strcpy (szTmpDestAddress, szDefDestAddress);
  1119. strcpy (szTmpLineDeviceClass, szDefLineDeviceClass);
  1120. strcpy (szTmpPhoneDeviceClass, szDefPhoneDeviceClass);
  1121. if (LetUserMungeParams (&paramsHeader))
  1122. {
  1123. if (params[0].dwValue != dwBigBufSize)
  1124. {
  1125. LPVOID pTmpBigBuf = malloc ((size_t) params[0].dwValue);
  1126. if (pTmpBigBuf)
  1127. {
  1128. free (pBigBuf);
  1129. pBigBuf = pTmpBigBuf;
  1130. dwBigBufSize = (DWORD) params[0].dwValue;
  1131. }
  1132. }
  1133. strcpy (szDefAppName, szTmpAppName);
  1134. dwDefAddressID = (DWORD) params[2].dwValue;
  1135. dwDefLineAPIVersion = (DWORD) params[3].dwValue;
  1136. dwDefBearerMode = (DWORD) params[4].dwValue;
  1137. dwDefCountryCode = (DWORD) params[5].dwValue;
  1138. dwDefLineDeviceID = (DWORD) params[6].dwValue;
  1139. dwDefLineExtVersion = (DWORD) params[7].dwValue;
  1140. dwDefMediaMode = (DWORD) params[8].dwValue;
  1141. dwDefLinePrivilege = (DWORD) params[9].dwValue;
  1142. strcpy (szDefUserUserInfo, szTmpUserUserInfo);
  1143. strcpy (szDefDestAddress, szTmpDestAddress);
  1144. strcpy (szDefLineDeviceClass, szTmpLineDeviceClass);
  1145. dwDefPhoneAPIVersion = (DWORD) params[13].dwValue;
  1146. dwDefPhoneDeviceID = (DWORD) params[14].dwValue;
  1147. dwDefPhoneExtVersion = (DWORD) params[15].dwValue;
  1148. dwDefPhonePrivilege = (DWORD) params[16].dwValue;
  1149. strcpy (szDefPhoneDeviceClass, szTmpPhoneDeviceClass);
  1150. if (params[1].dwValue && (params[1].dwValue != (ULONG_PTR) -1))
  1151. {
  1152. lpszDefAppName = szDefAppName;
  1153. }
  1154. else
  1155. {
  1156. lpszDefAppName = (char far *) params[1].dwValue;
  1157. }
  1158. if (params[10].dwValue &&
  1159. (params[10].dwValue != (ULONG_PTR) -1))
  1160. {
  1161. lpszDefUserUserInfo = szDefUserUserInfo;
  1162. }
  1163. else
  1164. {
  1165. lpszDefUserUserInfo = (char far *) params[10].dwValue;
  1166. }
  1167. if (params[11].dwValue &&
  1168. (params[11].dwValue != (ULONG_PTR) -1))
  1169. {
  1170. lpszDefDestAddress = szDefDestAddress;
  1171. }
  1172. else
  1173. {
  1174. lpszDefDestAddress = (char far *) params[11].dwValue;
  1175. }
  1176. if (params[12].dwValue &&
  1177. (params[12].dwValue != (ULONG_PTR) -1))
  1178. {
  1179. lpszDefLineDeviceClass = szDefLineDeviceClass;
  1180. }
  1181. else
  1182. {
  1183. lpszDefLineDeviceClass = (char far *) params[12].dwValue;
  1184. }
  1185. if (params[17].dwValue &&
  1186. (params[17].dwValue != (ULONG_PTR) -1))
  1187. {
  1188. lpszDefPhoneDeviceClass = szDefPhoneDeviceClass;
  1189. }
  1190. else
  1191. {
  1192. lpszDefPhoneDeviceClass = (char far *) params[17].dwValue;
  1193. }
  1194. }
  1195. bShowParams = bShowParamsSave;
  1196. break;
  1197. }
  1198. case IDM_USERBUTTONS:
  1199. DialogBoxParam(
  1200. ghInst,
  1201. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG3),
  1202. (HWND) hwnd,
  1203. (DLGPROC) UserButtonsDlgProc,
  1204. (LPARAM) NULL
  1205. );
  1206. break;
  1207. case IDM_DUMPPARAMS:
  1208. bDumpParams = (bDumpParams ? FALSE : TRUE);
  1209. CheckMenuItem(
  1210. hMenu,
  1211. IDM_DUMPPARAMS,
  1212. MF_BYCOMMAND | (bDumpParams ? MF_CHECKED : MF_UNCHECKED)
  1213. );
  1214. break;
  1215. case IDM_LOGSTRUCTDWORD:
  1216. case IDM_LOGSTRUCTALLFIELD:
  1217. case IDM_LOGSTRUCTNONZEROFIELD:
  1218. case IDM_LOGSTRUCTNONE:
  1219. for (i = 0; aXxx[i].dwFlags != dwDumpStructsFlags; i++);
  1220. CheckMenuItem(
  1221. hMenu,
  1222. aXxx[i].dwMenuID,
  1223. MF_BYCOMMAND | MF_UNCHECKED
  1224. );
  1225. for (i = 0; aXxx[i].dwMenuID != LOWORD(wParam); i++);
  1226. CheckMenuItem(
  1227. hMenu,
  1228. aXxx[i].dwMenuID,
  1229. MF_BYCOMMAND | MF_CHECKED
  1230. );
  1231. dwDumpStructsFlags = aXxx[i].dwFlags;
  1232. break;
  1233. case IDM_TIMESTAMP:
  1234. bTimeStamp = (bTimeStamp ? FALSE : TRUE);
  1235. CheckMenuItem(
  1236. hMenu,
  1237. IDM_TIMESTAMP,
  1238. MF_BYCOMMAND | (bTimeStamp ? MF_CHECKED : MF_UNCHECKED)
  1239. );
  1240. break;
  1241. case IDM_LOGFILE:
  1242. {
  1243. if (hLogFile)
  1244. {
  1245. fclose (hLogFile);
  1246. hLogFile = (FILE *) NULL;
  1247. CheckMenuItem(
  1248. hMenu,
  1249. IDM_LOGFILE,
  1250. MF_BYCOMMAND | MF_UNCHECKED
  1251. );
  1252. }
  1253. else
  1254. {
  1255. OPENFILENAME ofn;
  1256. char szDirName[256] = ".\\";
  1257. char szFile[256] = "tb.log\0";
  1258. char szFileTitle[256] = "";
  1259. static char *szFilter =
  1260. "Log files (*.log)\0*.log\0All files (*.*)\0*.*\0\0";
  1261. ofn.lStructSize = sizeof(OPENFILENAME);
  1262. ofn.hwndOwner = hwnd;
  1263. ofn.lpstrFilter = szFilter;
  1264. ofn.lpstrCustomFilter = (LPSTR) NULL;
  1265. ofn.nMaxCustFilter = 0L;
  1266. ofn.nFilterIndex = 1;
  1267. ofn.lpstrFile = szFile;
  1268. ofn.nMaxFile = sizeof(szFile);
  1269. ofn.lpstrFileTitle = szFileTitle;
  1270. ofn.nMaxFileTitle = sizeof(szFileTitle);
  1271. ofn.lpstrInitialDir = szDirName;
  1272. ofn.lpstrTitle = (LPSTR) NULL;
  1273. ofn.Flags = 0L;
  1274. ofn.nFileOffset = 0;
  1275. ofn.nFileExtension = 0;
  1276. ofn.lpstrDefExt = "LOG";
  1277. if (!GetOpenFileName(&ofn))
  1278. {
  1279. return 0L;
  1280. }
  1281. if ((hLogFile = fopen (szFile, "at")) == (FILE *) NULL)
  1282. {
  1283. MessageBox(
  1284. hwnd,
  1285. "Error creating log file",
  1286. #ifdef WIN32
  1287. "TB32.EXE",
  1288. #else
  1289. "TB.EXE",
  1290. #endif
  1291. MB_OK
  1292. );
  1293. }
  1294. else
  1295. {
  1296. struct tm *newtime;
  1297. time_t aclock;
  1298. time (&aclock);
  1299. newtime = localtime (&aclock);
  1300. fprintf(
  1301. hLogFile,
  1302. "\n---Log opened: %s\n",
  1303. asctime (newtime)
  1304. );
  1305. CheckMenuItem(
  1306. hMenu,
  1307. IDM_LOGFILE,
  1308. MF_BYCOMMAND | MF_CHECKED
  1309. );
  1310. }
  1311. }
  1312. break;
  1313. }
  1314. case IDM_USINGTB:
  1315. {
  1316. static char szUsingTB[] =
  1317. "ABSTRACT:\r\n" \
  1318. " TB (TAPI Browser) is an application that\r\n" \
  1319. "allows a user to interactively call into the\r\n" \
  1320. "Windows Telephony interface and inspect all\r\n" \
  1321. "returned information. The following versions\r\n" \
  1322. "of TB are available:\r\n\r\n" \
  1323. " TB13.EXE: 16-bit app, TAPI v1.0\r\n" \
  1324. " TB14.EXE: 32-bit app, <= TAPI v1.4\r\n" \
  1325. " TB20.EXE: 32-bit app, <= TAPI v2.0\r\n" \
  1326. "\r\n" \
  1327. "GETTING STARTED:\r\n" \
  1328. "1. Press the 'LAp+' button to initialize TAPI \r\n" \
  1329. "2. Press the 'Line+' button to open a line device\r\n" \
  1330. "3. Press the 'Call+' button to make a call\r\n" \
  1331. "* Pressing the 'LAp-' button will shutdown TAPI\r\n" \
  1332. "\r\n" \
  1333. "MORE INFO:\r\n" \
  1334. "* Double-clicking on one of the items in the\r\n" \
  1335. "functions listbox (far left) will invoke that \r\n" \
  1336. "function. Check the 'Params' checkbox to enable\r\n" \
  1337. "parameter modification.\r\n" \
  1338. "* Choose 'Options/Default values...' to modify\r\n" \
  1339. "default parameter values (address,device ID, etc).\r\n"\
  1340. "* Choose 'Options/Record log file' to save all\r\n" \
  1341. "output to a file.\r\n" \
  1342. "* All parameter values in hexadecimal unless\r\n" \
  1343. "specified (strings displayed by contents, not \r\n" \
  1344. "pointer value).\r\n" \
  1345. "* All 'Xxx+' and 'Xxx-' buttons are essentially \r\n" \
  1346. "hot-links to items in the functions listbox.\r\n" \
  1347. "* Choose 'Options/User buttons...' or press\r\n" \
  1348. "one of the buttons on right side of toolbar to\r\n" \
  1349. "create a personal hot-link between a button and a\r\n" \
  1350. "particular function.\r\n" \
  1351. "\r\n" \
  1352. " * Note: Selecting a API version parameter value\r\n"\
  1353. "which is newer than that for which TB application\r\n" \
  1354. "is targeted will result in erroneous dumps of some\r\n"\
  1355. "structures (e.g. specifying an API version of\r\n" \
  1356. "0x10004 and calling lineGetTranslateCaps in TB13).\r\n";
  1357. DialogBoxParam(
  1358. ghInst,
  1359. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG6),
  1360. (HWND)hwnd,
  1361. (DLGPROC) AboutDlgProc,
  1362. (LPARAM) szUsingTB
  1363. );
  1364. break;
  1365. }
  1366. // help case IDM_TAPIHLP:
  1367. // help
  1368. // help MyWinHelp (hwnd, TRUE, HELP_CONTENTS, 0);
  1369. // help break;
  1370. // help case IDM_TSPIHLP:
  1371. // help
  1372. // help MyWinHelp (hwnd, FALSE, HELP_CONTENTS, 0);
  1373. // help break;
  1374. case IDM_NUKEIDLEMONITORCALLS:
  1375. bNukeIdleMonitorCalls = (bNukeIdleMonitorCalls ? 0 : 1);
  1376. CheckMenuItem(
  1377. hMenu,
  1378. IDM_NUKEIDLEMONITORCALLS,
  1379. MF_BYCOMMAND |
  1380. (bNukeIdleMonitorCalls ? MF_CHECKED : MF_UNCHECKED)
  1381. );
  1382. break;
  1383. case IDM_NUKEIDLEOWNEDCALLS:
  1384. bNukeIdleOwnedCalls = (bNukeIdleOwnedCalls ? 0 : 1);
  1385. CheckMenuItem(
  1386. hMenu,
  1387. IDM_NUKEIDLEOWNEDCALLS,
  1388. MF_BYCOMMAND |
  1389. (bNukeIdleOwnedCalls ? MF_CHECKED : MF_UNCHECKED)
  1390. );
  1391. break;
  1392. case IDM_NOHANDLECHK:
  1393. gbDisableHandleChecking = (gbDisableHandleChecking ? 0 : 1);
  1394. CheckMenuItem(
  1395. hMenu,
  1396. IDM_NOHANDLECHK,
  1397. MF_BYCOMMAND |
  1398. (gbDisableHandleChecking ? MF_CHECKED : MF_UNCHECKED)
  1399. );
  1400. break;
  1401. case IDM_ABOUT:
  1402. {
  1403. DialogBoxParam(
  1404. ghInst,
  1405. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG4),
  1406. (HWND)hwnd,
  1407. (DLGPROC) AboutDlgProc,
  1408. 0
  1409. );
  1410. break;
  1411. }
  1412. } // switch
  1413. break;
  1414. }
  1415. #ifdef WIN32
  1416. case WM_CTLCOLORBTN:
  1417. SetBkColor ((HDC) wParam, RGB (192,192,192));
  1418. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  1419. #else
  1420. case WM_CTLCOLOR:
  1421. {
  1422. if (HIWORD(lParam) == CTLCOLOR_BTN)
  1423. {
  1424. SetBkColor ((HDC) wParam, RGB (192,192,192));
  1425. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  1426. }
  1427. break;
  1428. }
  1429. #endif
  1430. case WM_MOUSEMOVE:
  1431. {
  1432. LONG x = (LONG)((short)LOWORD(lParam));
  1433. int y = (int)((short)HIWORD(lParam));
  1434. if ((y > icyButton) || lCaptureFlags)
  1435. {
  1436. SetCursor (LoadCursor (NULL, MAKEINTRESOURCE(IDC_SIZEWE)));
  1437. }
  1438. if (lCaptureFlags == 1)
  1439. {
  1440. int cxList2New;
  1441. x = (x > (cxList1 + cxList2 - cxVScroll) ?
  1442. (cxList1 + cxList2 - cxVScroll) : x);
  1443. x = (x < cxVScroll ? cxVScroll : x);
  1444. cxList2New = (int) (cxList2 + x - xCapture);
  1445. SetWindowPos(
  1446. ghwndList2,
  1447. GetNextWindow (ghwndList2, GW_HWNDPREV),
  1448. 0,
  1449. icyButton,
  1450. cxList2New,
  1451. cyWnd,
  1452. SWP_SHOWWINDOW
  1453. );
  1454. SetWindowPos(
  1455. ghwndList1,
  1456. GetNextWindow (ghwndList1, GW_HWNDPREV),
  1457. cxList2New + icyBorder,
  1458. icyButton,
  1459. (int) (cxList1 - (x - xCapture)),
  1460. cyWnd,
  1461. SWP_SHOWWINDOW
  1462. );
  1463. }
  1464. else if (lCaptureFlags == 2)
  1465. {
  1466. int cxList1New;
  1467. x = (x < (cxList2 + cxVScroll) ? (cxList2 + cxVScroll) : x);
  1468. x = (x > (cxWnd - cxVScroll) ? (cxWnd - cxVScroll) : x);
  1469. cxList1New = (int) (cxList1 + x - xCapture);
  1470. SetWindowPos(
  1471. ghwndList1,
  1472. GetNextWindow (ghwndList1, GW_HWNDPREV),
  1473. (int) cxList2 + icyBorder,
  1474. icyButton,
  1475. cxList1New,
  1476. cyWnd,
  1477. SWP_SHOWWINDOW
  1478. );
  1479. SetWindowPos(
  1480. ghwndEdit,
  1481. GetNextWindow (ghwndEdit, GW_HWNDPREV),
  1482. (int) (cxList1New + cxList2) + 2*icyBorder,
  1483. icyButton,
  1484. (int)cxWnd - (cxList1New + (int)cxList2 + 2*icyBorder),
  1485. cyWnd,
  1486. SWP_SHOWWINDOW
  1487. );
  1488. }
  1489. break;
  1490. }
  1491. case WM_LBUTTONDOWN:
  1492. {
  1493. if ((int)((short)HIWORD(lParam)) > icyButton)
  1494. {
  1495. xCapture = (LONG)LOWORD(lParam);
  1496. SetCapture (hwnd);
  1497. lCaptureFlags = ((xCapture < cxList1 + cxList2) ? 1 : 2);
  1498. }
  1499. break;
  1500. }
  1501. case WM_LBUTTONUP:
  1502. {
  1503. if (lCaptureFlags)
  1504. {
  1505. POINT p;
  1506. LONG x;
  1507. RECT rect = { 0, icyButton, 2000, 2000 };
  1508. GetCursorPos (&p);
  1509. MapWindowPoints (HWND_DESKTOP, hwnd, &p, 1);
  1510. x = (LONG) p.x;
  1511. ReleaseCapture();
  1512. if (lCaptureFlags == 1)
  1513. {
  1514. x = (x < cxVScroll ? cxVScroll : x);
  1515. x = (x > (cxList1 + cxList2 - cxVScroll) ?
  1516. (cxList1 + cxList2 - cxVScroll) : x);
  1517. cxList2 = cxList2 + (x - xCapture);
  1518. cxList1 = cxList1 - (x - xCapture);
  1519. rect.right = (int) (cxList1 + cxList2) + icyBorder;
  1520. }
  1521. else
  1522. {
  1523. x = (x < (cxList2 + cxVScroll) ?
  1524. (cxList2 + cxVScroll) : x);
  1525. x = (x > (cxWnd - cxVScroll) ?
  1526. (cxWnd - cxVScroll) : x);
  1527. cxList1 = cxList1 + (x - xCapture);
  1528. rect.left = (int)cxList2 + icyBorder;
  1529. }
  1530. lCaptureFlags = 0;
  1531. InvalidateRect (hwnd, &rect, TRUE);
  1532. }
  1533. break;
  1534. }
  1535. case WM_SIZE:
  1536. {
  1537. if (wParam != SIZE_MINIMIZED)
  1538. {
  1539. LONG width = (LONG)LOWORD(lParam);
  1540. //
  1541. // Adjust globals based on new size
  1542. //
  1543. cxWnd = (cxWnd ? cxWnd : 1); // avoid div by 0
  1544. cxList1 = (cxList1 * width) / cxWnd;
  1545. cxList2 = (cxList2 * width) / cxWnd;
  1546. cxWnd = width;
  1547. cyWnd = ((int)HIWORD(lParam)) - icyButton;
  1548. //
  1549. // Now reposition the child windows
  1550. //
  1551. SetWindowPos(
  1552. ghwndList2,
  1553. GetNextWindow (ghwndList2, GW_HWNDPREV),
  1554. 0,
  1555. icyButton,
  1556. (int) cxList2,
  1557. cyWnd,
  1558. SWP_SHOWWINDOW
  1559. );
  1560. SetWindowPos(
  1561. ghwndList1,
  1562. GetNextWindow (ghwndList1, GW_HWNDPREV),
  1563. (int) cxList2 + icyBorder,
  1564. icyButton,
  1565. (int) cxList1,
  1566. cyWnd,
  1567. SWP_SHOWWINDOW
  1568. );
  1569. SetWindowPos(
  1570. ghwndEdit,
  1571. GetNextWindow (ghwndEdit, GW_HWNDPREV),
  1572. (int) (cxList1 + cxList2) + 2*icyBorder,
  1573. icyButton,
  1574. (int)width - ((int)(cxList1 + cxList2) + 2*icyBorder),
  1575. cyWnd,
  1576. SWP_SHOWWINDOW
  1577. );
  1578. InvalidateRect (hwnd, NULL, TRUE);
  1579. }
  1580. break;
  1581. }
  1582. case WM_PAINT:
  1583. {
  1584. PAINTSTRUCT ps;
  1585. BeginPaint (hwnd, &ps);
  1586. if (IsIconic (hwnd))
  1587. {
  1588. DrawIcon (ps.hdc, 0, 0, hIcon);
  1589. }
  1590. else
  1591. {
  1592. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  1593. #ifdef WIN32
  1594. MoveToEx (ps.hdc, 0, 0, NULL);
  1595. #else
  1596. MoveTo (ps.hdc, 0, 0);
  1597. #endif
  1598. LineTo (ps.hdc, 5000, 0);
  1599. #ifdef WIN32
  1600. MoveToEx (ps.hdc, 0, icyButton - 4, NULL);
  1601. #else
  1602. MoveTo (ps.hdc, 0, icyButton - 4);
  1603. #endif
  1604. LineTo (ps.hdc, 5000, icyButton - 4);
  1605. }
  1606. EndPaint (hwnd, &ps);
  1607. break;
  1608. }
  1609. case WM_CLOSE:
  1610. {
  1611. BOOL bAutoShutdown = FALSE;
  1612. RECT rect;
  1613. //
  1614. // Save defaults in ini file
  1615. //
  1616. {
  1617. char buf[32];
  1618. typedef struct _DEF_VALUE2
  1619. {
  1620. char far *lpszEntry;
  1621. ULONG_PTR dwValue;
  1622. } DEF_VALUE2;
  1623. DEF_VALUE2 aDefVals[] =
  1624. {
  1625. { "BufSize", dwBigBufSize },
  1626. { "AddressID", dwDefAddressID },
  1627. #if TAPI_2_0
  1628. { "20LineAPIVersion", dwDefLineAPIVersion },
  1629. #else
  1630. #if TAPI_1_1
  1631. { "14LineAPIVersion", dwDefLineAPIVersion },
  1632. #else
  1633. { "13LineAPIVersion", dwDefLineAPIVersion },
  1634. #endif
  1635. #endif
  1636. { "BearerMode", dwDefBearerMode },
  1637. { "CountryCode", dwDefCountryCode },
  1638. { "LineDeviceID", dwDefLineDeviceID },
  1639. { "LineExtVersion", dwDefLineExtVersion },
  1640. { "MediaMode", dwDefMediaMode },
  1641. { "LinePrivilege", dwDefLinePrivilege },
  1642. #if TAPI_2_0
  1643. { "20PhoneAPIVersion", dwDefPhoneAPIVersion },
  1644. #else
  1645. #if TAPI_1_1
  1646. { "14PhoneAPIVersion", dwDefPhoneAPIVersion },
  1647. #else
  1648. { "13PhoneAPIVersion", dwDefPhoneAPIVersion },
  1649. #endif
  1650. #endif
  1651. { "PhoneDeviceID", dwDefPhoneDeviceID },
  1652. { "PhoneExtVersion", dwDefPhoneExtVersion },
  1653. { "PhonePrivilege", dwDefPhonePrivilege },
  1654. #if TAPI_2_0
  1655. { "20UserButton1", aUserButtonFuncs[0] },
  1656. { "20UserButton2", aUserButtonFuncs[1] },
  1657. { "20UserButton3", aUserButtonFuncs[2] },
  1658. { "20UserButton4", aUserButtonFuncs[3] },
  1659. { "20UserButton5", aUserButtonFuncs[4] },
  1660. { "20UserButton6", aUserButtonFuncs[5] },
  1661. #else
  1662. #if TAPI_1_1
  1663. { "14UserButton1", aUserButtonFuncs[0] },
  1664. { "14UserButton2", aUserButtonFuncs[1] },
  1665. { "14UserButton3", aUserButtonFuncs[2] },
  1666. { "14UserButton4", aUserButtonFuncs[3] },
  1667. { "14UserButton5", aUserButtonFuncs[4] },
  1668. { "14UserButton6", aUserButtonFuncs[5] },
  1669. #else
  1670. { "13UserButton1", aUserButtonFuncs[0] },
  1671. { "13UserButton2", aUserButtonFuncs[1] },
  1672. { "13UserButton3", aUserButtonFuncs[2] },
  1673. { "13UserButton4", aUserButtonFuncs[3] },
  1674. { "13UserButton5", aUserButtonFuncs[4] },
  1675. { "13UserButton6", aUserButtonFuncs[5] },
  1676. #endif
  1677. #endif
  1678. { "TimeStamp", bTimeStamp },
  1679. { "NukeIdleMonitorCalls", bNukeIdleMonitorCalls },
  1680. { "NukeIdleOwnedCalls", bNukeIdleOwnedCalls },
  1681. { "DisableHandleChecking", gbDisableHandleChecking },
  1682. { "DumpStructsFlags", dwDumpStructsFlags },
  1683. { NULL, 0 },
  1684. { "Version", (ULONG_PTR) szCurrVer },
  1685. { "UserUserInfo", (ULONG_PTR) szDefUserUserInfo },
  1686. { "DestAddress", (ULONG_PTR) szDefDestAddress },
  1687. { "LineDeviceClass", (ULONG_PTR) szDefLineDeviceClass },
  1688. { "PhoneDeviceClass", (ULONG_PTR) szDefPhoneDeviceClass },
  1689. { "AppName", (ULONG_PTR) szDefAppName },
  1690. #if TAPI_2_0
  1691. { "20UserButton1Text", (ULONG_PTR) &aUserButtonsText[0] },
  1692. { "20UserButton2Text", (ULONG_PTR) &aUserButtonsText[1] },
  1693. { "20UserButton3Text", (ULONG_PTR) &aUserButtonsText[2] },
  1694. { "20UserButton4Text", (ULONG_PTR) &aUserButtonsText[3] },
  1695. { "20UserButton5Text", (ULONG_PTR) &aUserButtonsText[4] },
  1696. { "20UserButton6Text", (ULONG_PTR) &aUserButtonsText[5] },
  1697. #else
  1698. #if TAPI_1_1
  1699. { "14UserButton1Text", (ULONG_PTR) &aUserButtonsText[0] },
  1700. { "14UserButton2Text", (ULONG_PTR) &aUserButtonsText[1] },
  1701. { "14UserButton3Text", (ULONG_PTR) &aUserButtonsText[2] },
  1702. { "14UserButton4Text", (ULONG_PTR) &aUserButtonsText[3] },
  1703. { "14UserButton5Text", (ULONG_PTR) &aUserButtonsText[4] },
  1704. { "14UserButton6Text", (ULONG_PTR) &aUserButtonsText[5] },
  1705. #else
  1706. { "13UserButton1Text", (ULONG_PTR) &aUserButtonsText[0] },
  1707. { "13UserButton2Text", (ULONG_PTR) &aUserButtonsText[1] },
  1708. { "13UserButton3Text", (ULONG_PTR) &aUserButtonsText[2] },
  1709. { "13UserButton4Text", (ULONG_PTR) &aUserButtonsText[3] },
  1710. { "13UserButton5Text", (ULONG_PTR) &aUserButtonsText[4] },
  1711. { "13UserButton6Text", (ULONG_PTR) &aUserButtonsText[5] },
  1712. #endif
  1713. #endif
  1714. // help { "TapiHlpPath", (ULONG_PTR) szTapiHlp },
  1715. // help { "TspiHlpPath", (ULONG_PTR) szTspiHlp },
  1716. { NULL, 0 }
  1717. };
  1718. int i;
  1719. for (i = 0; aDefVals[i].lpszEntry; i++)
  1720. {
  1721. sprintf (buf, "%lx", aDefVals[i].dwValue);
  1722. WriteProfileString(
  1723. MYSECTION,
  1724. aDefVals[i].lpszEntry,
  1725. buf
  1726. );
  1727. }
  1728. i++;
  1729. for (; aDefVals[i].lpszEntry; i++)
  1730. {
  1731. WriteProfileString(
  1732. MYSECTION,
  1733. aDefVals[i].lpszEntry,
  1734. (LPCSTR) aDefVals[i].dwValue
  1735. );
  1736. }
  1737. //
  1738. // Save the window dimensions (if iconic then don't bother)
  1739. //
  1740. if (!IsIconic (hwnd))
  1741. {
  1742. if (IsZoomed (hwnd))
  1743. {
  1744. strcpy (buf, "max");
  1745. }
  1746. else
  1747. {
  1748. GetWindowRect (hwnd, &rect);
  1749. sprintf(
  1750. buf,
  1751. "%d,%d,%d,%d",
  1752. rect.left,
  1753. rect.top,
  1754. rect.right,
  1755. rect.bottom
  1756. );
  1757. }
  1758. WriteProfileString(
  1759. MYSECTION,
  1760. "Position",
  1761. (LPCSTR) buf
  1762. );
  1763. sprintf (buf, "%ld,%ld,%ld", cxList2, cxList1, cxWnd);
  1764. WriteProfileString(
  1765. MYSECTION,
  1766. "ControlRatios",
  1767. (LPCSTR) buf
  1768. );
  1769. }
  1770. }
  1771. //
  1772. // Give user chance to auto-shutdown any active line/phone apps
  1773. //
  1774. if (aWidgets)
  1775. {
  1776. if (MessageBox(
  1777. hwnd,
  1778. "Shutdown all hLineApps/hPhoneApps? (recommended)",
  1779. "Tapi Browser closing",
  1780. MB_YESNO
  1781. ) == IDNO)
  1782. {
  1783. goto WM_CLOSE_freeBigBuf;
  1784. }
  1785. bShowParams = FALSE;
  1786. while (aWidgets)
  1787. {
  1788. PMYWIDGET pWidgetToClose = aWidgets;
  1789. if (aWidgets->dwType == WT_LINEAPP)
  1790. {
  1791. pLineAppSel = (PMYLINEAPP) aWidgets;
  1792. FuncDriver (lShutdown);
  1793. }
  1794. else if (aWidgets->dwType == WT_PHONEAPP)
  1795. {
  1796. pPhoneAppSel = (PMYPHONEAPP) aWidgets;
  1797. FuncDriver (pShutdown);
  1798. }
  1799. if (pWidgetToClose == aWidgets)
  1800. {
  1801. //
  1802. // The shutdown wasn't successful (or our list is
  1803. // messed up an it'd not a LINEAPP or PHONEAPP widget),
  1804. // so manually nuke this widget so we don't hang in
  1805. // this loop forever
  1806. //
  1807. RemoveWidgetFromList (pWidgetToClose);
  1808. }
  1809. }
  1810. }
  1811. WM_CLOSE_freeBigBuf:
  1812. if (hLogFile)
  1813. {
  1814. fclose (hLogFile);
  1815. }
  1816. DestroyIcon (hIcon);
  1817. free (pBigBuf);
  1818. free (lpCallParams);
  1819. // if (aSelWidgets)
  1820. // {
  1821. // free (aSelWidgets);
  1822. // }
  1823. // if (aSelWidgetsPrev)
  1824. // {
  1825. // free (aSelWidgetsPrev);
  1826. // }
  1827. DeleteObject (hFont);
  1828. DeleteObject (hFont2);
  1829. PostQuitMessage (0);
  1830. break;
  1831. }
  1832. } //switch
  1833. return 0;
  1834. }
  1835. INT_PTR
  1836. CALLBACK
  1837. AboutDlgProc(
  1838. HWND hwnd,
  1839. UINT msg,
  1840. WPARAM wParam,
  1841. LPARAM lParam
  1842. )
  1843. {
  1844. switch (msg)
  1845. {
  1846. case WM_INITDIALOG:
  1847. if (lParam)
  1848. {
  1849. SetDlgItemText (hwnd, IDC_EDIT1, (LPCSTR) lParam);
  1850. }
  1851. break;
  1852. case WM_COMMAND:
  1853. switch (LOWORD(wParam))
  1854. {
  1855. case IDOK:
  1856. EndDialog (hwnd, 0);
  1857. break;
  1858. }
  1859. break;
  1860. #ifdef WIN32
  1861. case WM_CTLCOLORSTATIC:
  1862. SetBkColor ((HDC) wParam, RGB (192,192,192));
  1863. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  1864. #else
  1865. case WM_CTLCOLOR:
  1866. {
  1867. if (HIWORD(lParam) == CTLCOLOR_STATIC)
  1868. {
  1869. SetBkColor ((HDC) wParam, RGB (192,192,192));
  1870. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  1871. }
  1872. break;
  1873. }
  1874. #endif
  1875. case WM_PAINT:
  1876. {
  1877. PAINTSTRUCT ps;
  1878. BeginPaint (hwnd, &ps);
  1879. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  1880. EndPaint (hwnd, &ps);
  1881. break;
  1882. }
  1883. }
  1884. return 0;
  1885. }
  1886. void
  1887. FAR
  1888. ShowStr(
  1889. LPCSTR format,
  1890. ...
  1891. )
  1892. {
  1893. char buf[256];
  1894. va_list ap;
  1895. va_start(ap, format);
  1896. wvsprintf (buf, format, ap);
  1897. if (hLogFile)
  1898. {
  1899. fprintf (hLogFile, "%s\n", buf);
  1900. }
  1901. strcat (buf, "\r\n");
  1902. //
  1903. // Insert text at end
  1904. //
  1905. #ifdef WIN32
  1906. SendMessage (ghwndEdit, EM_SETSEL, (WPARAM)0xfffffffd, (LPARAM)0xfffffffe);
  1907. #else
  1908. SendMessage(
  1909. ghwndEdit,
  1910. EM_SETSEL,
  1911. (WPARAM)0,
  1912. (LPARAM) MAKELONG(0xfffd,0xfffe)
  1913. );
  1914. #endif
  1915. SendMessage (ghwndEdit, EM_REPLACESEL, 0, (LPARAM) buf);
  1916. #ifdef WIN32
  1917. //
  1918. // Scroll to end of text
  1919. //
  1920. SendMessage (ghwndEdit, EM_SCROLLCARET, 0, 0);
  1921. #endif
  1922. va_end(ap);
  1923. }
  1924. VOID
  1925. UpdateWidgetListCall(
  1926. PMYCALL pCall
  1927. )
  1928. {
  1929. LONG i;
  1930. char buf[64];
  1931. LRESULT lSel;
  1932. for (i = 0; aCallStates[i].dwVal != 0xffffffff; i++)
  1933. {
  1934. if (pCall->dwCallState == aCallStates[i].dwVal)
  1935. {
  1936. break;
  1937. }
  1938. }
  1939. sprintf(
  1940. buf,
  1941. " Call=x%lx %s %s",
  1942. pCall->hCall,
  1943. aCallStates[i].lpszVal,
  1944. (pCall->bMonitor ? "Monitor" : "Owner")
  1945. );
  1946. i = (LONG) GetWidgetIndex ((PMYWIDGET) pCall);
  1947. lSel = SendMessage (ghwndList1, LB_GETCURSEL, 0, 0);
  1948. SendMessage (ghwndList1, LB_DELETESTRING, (WPARAM) i, 0);
  1949. SendMessage (ghwndList1, LB_INSERTSTRING, (WPARAM) i, (LPARAM) buf);
  1950. SendMessage (ghwndList1, LB_SETITEMDATA, (WPARAM) i, (LPARAM) pCall);
  1951. if (lSel == i)
  1952. {
  1953. SendMessage (ghwndList1, LB_SETCURSEL, (WPARAM) i, 0);
  1954. }
  1955. }
  1956. VOID
  1957. CALLBACK
  1958. tapiCallback(
  1959. DWORD hDevice,
  1960. DWORD dwMsg,
  1961. ULONG_PTR CallbackInstance,
  1962. ULONG_PTR Param1,
  1963. ULONG_PTR Param2,
  1964. ULONG_PTR Param3
  1965. )
  1966. {
  1967. typedef struct _MSG_PARAMS
  1968. {
  1969. char *lpszMsg;
  1970. LPVOID aParamFlagTables[3];
  1971. } MSG_PARAMS, *PMSG_PARAMS;
  1972. static MSG_PARAMS msgParams[] =
  1973. {
  1974. { "LINE_ADDRESSSTATE", { NULL, aAddressStates, NULL } },
  1975. { "LINE_CALLINFO", { aCallInfoStates, NULL, NULL } },
  1976. { "LINE_CALLSTATE", { aCallStates, NULL, aCallPrivileges } },
  1977. { "LINE_CLOSE", { NULL, NULL, NULL } },
  1978. { "LINE_DEVSPECIFIC", { NULL, NULL, NULL } },
  1979. { "LINE_DEVSPECIFICFEATURE", { NULL, NULL, NULL } },
  1980. { "LINE_GATHERDIGITS", { aGatherTerms, NULL, NULL } },
  1981. { "LINE_GENERATE", { aGenerateTerms, NULL, NULL } },
  1982. { "LINE_LINEDEVSTATE", { aLineStates, NULL, NULL } },
  1983. { "LINE_MONITORDIGITS", { NULL, aDigitModes, NULL } },
  1984. { "LINE_MONITORMEDIA", { aMediaModes, NULL, NULL } },
  1985. { "LINE_MONITORTONE", { NULL, NULL, NULL } },
  1986. { "LINE_REPLY", { NULL, NULL, NULL } },
  1987. { "LINE_REQUEST", { aRequestModes, NULL, NULL } }
  1988. ,
  1989. { "PHONE_BUTTON", { NULL, aButtonModes, aButtonStates } },
  1990. { "PHONE_CLOSE", { NULL, NULL, NULL } },
  1991. { "PHONE_DEVSPECIFIC", { NULL, NULL, NULL } },
  1992. { "PHONE_REPLY", { NULL, NULL, NULL } },
  1993. { "PHONE_STATE", { aPhoneStates, NULL, NULL } }
  1994. #if TAPI_1_1
  1995. ,
  1996. { "LINE_CREATE", { NULL, NULL, NULL } },
  1997. { "PHONE_CREATE", { NULL, NULL, NULL } }
  1998. #if TAPI_2_0
  1999. ,
  2000. { "LINE_AGENTSPECIFIC", { NULL, NULL, NULL } },
  2001. { "LINE_AGENTSTATUS", { NULL, NULL, NULL } },
  2002. { "LINE_APPNEWCALL", { NULL, NULL, aCallPrivileges } },
  2003. { "LINE_PROXYREQUEST", { NULL, NULL, NULL } },
  2004. { "LINE_REMOVE", { NULL, NULL, NULL } },
  2005. { "PHONE_REMOVE", { NULL, NULL, NULL } }
  2006. #endif
  2007. #endif
  2008. };
  2009. int i, j;
  2010. LONG lResult;
  2011. UpdateResults (TRUE);
  2012. #if TAPI_1_1
  2013. #if TAPI_2_0
  2014. if (dwMsg <= PHONE_REMOVE)
  2015. #else
  2016. if (dwMsg <= PHONE_CREATE)
  2017. #endif
  2018. #else
  2019. if (dwMsg <= PHONE_STATE)
  2020. #endif
  2021. {
  2022. ULONG_PTR aParams[3] = { Param1, Param2, Param3 };
  2023. {
  2024. char *pszTimeStamp = GetTimeStamp();
  2025. ShowStr(
  2026. "%sreceived %s",
  2027. pszTimeStamp,
  2028. msgParams[dwMsg].lpszMsg
  2029. );
  2030. }
  2031. ShowStr ("%sdevice=x%lx", szTab, hDevice);
  2032. ShowStr ("%scbInst=x%lx", szTab, CallbackInstance);
  2033. if (dwMsg == LINE_CALLSTATE)
  2034. {
  2035. msgParams[2].aParamFlagTables[1] = NULL;
  2036. switch (Param1)
  2037. {
  2038. case LINECALLSTATE_BUSY:
  2039. msgParams[2].aParamFlagTables[1] = (LPVOID) aBusyModes;
  2040. break;
  2041. case LINECALLSTATE_DIALTONE:
  2042. msgParams[2].aParamFlagTables[1] = (LPVOID) aDialToneModes;
  2043. break;
  2044. case LINECALLSTATE_SPECIALINFO:
  2045. msgParams[2].aParamFlagTables[1] = (LPVOID) aSpecialInfo;
  2046. break;
  2047. case LINECALLSTATE_DISCONNECTED:
  2048. msgParams[2].aParamFlagTables[1] = (LPVOID) aDisconnectModes;
  2049. break;
  2050. #if TAPI_1_1
  2051. case LINECALLSTATE_CONNECTED:
  2052. msgParams[2].aParamFlagTables[1] = (LPVOID) aConnectedModes;
  2053. break;
  2054. case LINECALLSTATE_OFFERING:
  2055. msgParams[2].aParamFlagTables[1] = (LPVOID) aOfferingModes;
  2056. break;
  2057. #endif // TAPI_1_1
  2058. } // switch
  2059. }
  2060. else if (dwMsg == PHONE_STATE)
  2061. {
  2062. msgParams[18].aParamFlagTables[1] = NULL;
  2063. switch (Param1)
  2064. {
  2065. case PHONESTATE_HANDSETHOOKSWITCH:
  2066. case PHONESTATE_SPEAKERHOOKSWITCH:
  2067. case PHONESTATE_HEADSETHOOKSWITCH:
  2068. msgParams[18].aParamFlagTables[1] = aHookSwitchModes;
  2069. break;
  2070. } // switch
  2071. }
  2072. for (i = 0; i < 3; i++)
  2073. {
  2074. char buf[80];
  2075. sprintf (buf, "%sparam%d=x%lx, ", szTab, i+1, aParams[i]);
  2076. if (msgParams[dwMsg].aParamFlagTables[i])
  2077. {
  2078. PLOOKUP pLookup = (PLOOKUP)
  2079. msgParams[dwMsg].aParamFlagTables[i];
  2080. for (j = 0; aParams[i], pLookup[j].dwVal != 0xffffffff; j++)
  2081. {
  2082. if (aParams[i] & pLookup[j].dwVal)
  2083. {
  2084. if (buf[0] == 0)
  2085. {
  2086. sprintf (buf, "%s%s", szTab, szTab);
  2087. }
  2088. strcat (buf, pLookup[j].lpszVal);
  2089. strcat (buf, " ");
  2090. aParams[i] = aParams[i] &
  2091. ~((ULONG_PTR) pLookup[j].dwVal);
  2092. if (strlen (buf) > 50)
  2093. {
  2094. //
  2095. // We don't want strings getting so long that
  2096. // they're going offscreen, so break them up.
  2097. //
  2098. ShowStr (buf);
  2099. buf[0] = 0;
  2100. }
  2101. }
  2102. }
  2103. if (aParams[i])
  2104. {
  2105. strcat (buf, "<unknown flag(s)>");
  2106. }
  2107. }
  2108. if (buf[0])
  2109. {
  2110. ShowStr (buf);
  2111. }
  2112. }
  2113. }
  2114. else
  2115. {
  2116. ShowStr ("ERROR! callback received unknown msg=x%lx", dwMsg);
  2117. ShowStr ("%shDev=x%lx, cbInst=x%lx, p1=x%lx, p2=x%lx, p3=x%lx",
  2118. szTab,
  2119. hDevice,
  2120. CallbackInstance,
  2121. Param1,
  2122. Param2,
  2123. Param3
  2124. );
  2125. return;
  2126. }
  2127. UpdateResults (FALSE);
  2128. switch (dwMsg)
  2129. {
  2130. case LINE_CALLSTATE:
  2131. {
  2132. PMYLINE pLine;
  2133. PMYCALL pCall = GetCall ((HCALL) hDevice);
  2134. //
  2135. // If the call state is idle & we're in "nuke idle xxx calls"
  2136. // mode then determine the privilege of this callto see if we
  2137. // need to nuke it
  2138. //
  2139. if ((Param1 == LINECALLSTATE_IDLE) &&
  2140. (bNukeIdleMonitorCalls || bNukeIdleOwnedCalls))
  2141. {
  2142. BOOL bNukeCall = FALSE;
  2143. LINECALLSTATUS callStatus;
  2144. callStatus.dwTotalSize = (DWORD) sizeof(LINECALLSTATUS);
  2145. lResult = lineGetCallStatus ((HCALL) hDevice, &callStatus);
  2146. ShowLineFuncResult ("lineGetCallStatus", lResult);
  2147. if (lResult == 0)
  2148. {
  2149. if ((callStatus.dwCallPrivilege & LINECALLPRIVILEGE_OWNER))
  2150. {
  2151. if (bNukeIdleOwnedCalls)
  2152. {
  2153. bNukeCall = TRUE;
  2154. }
  2155. }
  2156. else
  2157. {
  2158. if (bNukeIdleMonitorCalls)
  2159. {
  2160. bNukeCall = TRUE;
  2161. }
  2162. }
  2163. }
  2164. if (bNukeCall)
  2165. {
  2166. if ((lResult = lineDeallocateCall ((HCALL) hDevice)) == 0)
  2167. {
  2168. ShowStr ("Call x%lx deallocated on IDLE", hDevice);
  2169. if (pCall)
  2170. {
  2171. FreeCall (pCall);
  2172. }
  2173. break;
  2174. }
  2175. else
  2176. {
  2177. ShowLineFuncResult ("lineDeallocateCall", lResult);
  2178. }
  2179. }
  2180. }
  2181. //
  2182. // Find call in the widget list, save the call state, &
  2183. // update it's text in the widget list.
  2184. //
  2185. if (pCall)
  2186. {
  2187. //
  2188. // If dwNumPendingDrops is non-zero, then user previously
  2189. // pressed "Call-" button and we're waiting for a call to
  2190. // go IDLE so we can deallocate it. Check to see if this
  2191. // is the call we want to nuke. (Note: we used to nuke the
  2192. // call when we got a successful REPLY msg back from the
  2193. // drop request; the problem with that is some SPs complete
  2194. // the drop request *before* they set the call state to
  2195. // IDLE, and our call to lineDeallocateCall would fail
  2196. // since TAPI won't let a call owner deallocate a call if
  2197. // it's not IDLE.)
  2198. //
  2199. if (dwNumPendingDrops &&
  2200. (Param1 == LINECALLSTATE_IDLE) &&
  2201. pCall->lDropReqID)
  2202. {
  2203. dwNumPendingDrops--;
  2204. ShowStr(
  2205. "Deallocating hCall x%lx " \
  2206. "(REPLY for requestID x%lx might be filtered)",
  2207. pCall->hCall,
  2208. pCall->lDropReqID
  2209. );
  2210. lResult = lineDeallocateCall (pCall->hCall);
  2211. ShowLineFuncResult ("lineDeallocateCall", lResult);
  2212. if (lResult == 0)
  2213. {
  2214. FreeCall (pCall);
  2215. break;
  2216. }
  2217. else
  2218. {
  2219. pCall->lDropReqID = 0;
  2220. }
  2221. }
  2222. pCall->dwCallState = (DWORD) Param1;
  2223. UpdateWidgetListCall (pCall);
  2224. }
  2225. //
  2226. // If here this is the first we've heard of this this call,
  2227. // so find out which line it's on & create a call widget
  2228. // for it
  2229. //
  2230. else if (Param3 != 0)
  2231. {
  2232. LINECALLINFO callInfo;
  2233. memset (&callInfo, 0, sizeof(LINECALLINFO));
  2234. callInfo.dwTotalSize = sizeof(LINECALLINFO);
  2235. lResult = lineGetCallInfo ((HCALL)hDevice, &callInfo);
  2236. ShowStr(
  2237. "%slineGetCallInfo returned x%lx, hLine=x%lx",
  2238. szTab,
  2239. lResult,
  2240. callInfo.hLine
  2241. );
  2242. if (lResult == 0)
  2243. {
  2244. if ((pLine = GetLine (callInfo.hLine)))
  2245. {
  2246. if ((pCall = AllocCall (pLine)))
  2247. {
  2248. pCall->hCall = (HCALL) hDevice;
  2249. pCall->dwCallState = (DWORD) Param1;
  2250. pCall->bMonitor = (Param3 ==
  2251. LINECALLPRIVILEGE_MONITOR ? TRUE : FALSE);
  2252. UpdateWidgetListCall (pCall);
  2253. }
  2254. }
  2255. }
  2256. }
  2257. break;
  2258. }
  2259. case LINE_GATHERDIGITS:
  2260. {
  2261. PMYCALL pCall;
  2262. if ((pCall = GetCall ((HCALL) hDevice)) && pCall->lpsGatheredDigits)
  2263. {
  2264. ShowStr ("%sGathered digits:", szTab);
  2265. ShowBytes (pCall->dwNumGatheredDigits, pCall->lpsGatheredDigits, 2);
  2266. free (pCall->lpsGatheredDigits);
  2267. pCall->lpsGatheredDigits = NULL;
  2268. }
  2269. break;
  2270. }
  2271. case LINE_REPLY:
  2272. if (dwNumPendingMakeCalls)
  2273. {
  2274. //
  2275. // Check to see if this is a reply for a lineMakeCall request
  2276. //
  2277. PMYWIDGET pWidget = aWidgets;
  2278. while (pWidget && (pWidget->dwType != WT_PHONEAPP))
  2279. {
  2280. if (pWidget->dwType == WT_CALL)
  2281. {
  2282. PMYCALL pCall = (PMYCALL) pWidget;
  2283. if ((DWORD)pCall->lMakeCallReqID == Param1)
  2284. {
  2285. //
  2286. // The reply id matches the make call req id
  2287. //
  2288. dwNumPendingMakeCalls--;
  2289. if (Param2 || !pCall->hCall)
  2290. {
  2291. //
  2292. // Request error or no call created, so free
  2293. // up the struct & update the hCalls listbox
  2294. //
  2295. if (Param2 == 0)
  2296. {
  2297. ShowStr(
  2298. " NOTE: *lphCall==NULL, "\
  2299. "freeing call data structure"
  2300. );
  2301. }
  2302. pWidget = pWidget->pNext;
  2303. FreeCall (pCall);
  2304. continue;
  2305. }
  2306. else
  2307. {
  2308. //
  2309. // Reset this field so we don't run into
  2310. // problems later with another of the same
  2311. // request id
  2312. //
  2313. pCall->lMakeCallReqID = 0;
  2314. UpdateWidgetListCall (pCall);
  2315. }
  2316. }
  2317. }
  2318. pWidget = pWidget->pNext;
  2319. }
  2320. }
  2321. if (Param2)
  2322. {
  2323. //
  2324. // Dump the error in a readable format
  2325. //
  2326. if (Param2 > LAST_LINEERR)
  2327. {
  2328. ShowStr ("inval err code (x%lx)", Param2);
  2329. }
  2330. else
  2331. {
  2332. ShowStr(
  2333. " %s%s",
  2334. "LINEERR_", // ...to shrink the aszLineErrs array
  2335. aszLineErrs[LOWORD(Param2)]
  2336. );
  2337. }
  2338. }
  2339. break;
  2340. case PHONE_REPLY:
  2341. if (Param2)
  2342. {
  2343. //
  2344. // Dump the error in a readable format
  2345. //
  2346. ErrorAlert();
  2347. if (Param2 > PHONEERR_REINIT)
  2348. {
  2349. ShowStr ("inval err code (x%lx)", Param2);
  2350. }
  2351. else
  2352. {
  2353. ShowStr(
  2354. " %s%s",
  2355. "PHONEERR_", // ...to shrink the aszPhoneErrs array
  2356. aszPhoneErrs[LOWORD(Param2)]
  2357. );
  2358. }
  2359. }
  2360. break;
  2361. case LINE_CLOSE:
  2362. FreeLine (GetLine ((HLINE) hDevice));
  2363. break;
  2364. case PHONE_CLOSE:
  2365. FreePhone (GetPhone ((HPHONE) hDevice));
  2366. break;
  2367. #if TAPI_2_0
  2368. case LINE_APPNEWCALL:
  2369. {
  2370. PMYLINE pLine;
  2371. PMYCALL pCall;
  2372. if ((pLine = GetLine ((HLINE) hDevice)))
  2373. {
  2374. if ((pCall = AllocCall (pLine)))
  2375. {
  2376. pCall->hCall = (HCALL) Param2;
  2377. pCall->dwCallState = LINECALLSTATE_UNKNOWN;
  2378. pCall->bMonitor = (Param3 ==
  2379. LINECALLPRIVILEGE_MONITOR ? TRUE : FALSE);
  2380. UpdateWidgetListCall (pCall);
  2381. }
  2382. }
  2383. break;
  2384. }
  2385. case LINE_PROXYREQUEST:
  2386. {
  2387. LPLINEPROXYREQUEST pRequest = (LPLINEPROXYREQUEST) Param1;
  2388. STRUCT_FIELD fields[] =
  2389. {
  2390. { szdwSize, FT_DWORD, pRequest->dwSize, NULL },
  2391. { "dwClientMachineNameSize", FT_SIZE, pRequest->dwClientMachineNameSize, NULL },
  2392. { "dwClientMachineNameOffset", FT_OFFSET, pRequest->dwClientMachineNameOffset, NULL },
  2393. { "dwClientUserNameSize", FT_SIZE, pRequest->dwClientUserNameSize, NULL },
  2394. { "dwClientUserNameOffset", FT_OFFSET, pRequest->dwClientUserNameOffset, NULL },
  2395. { "dwClientAppAPIVersion", FT_DWORD, pRequest->dwClientAppAPIVersion, NULL },
  2396. { "dwRequestType", FT_ORD, pRequest->dwRequestType, aProxyRequests }
  2397. };
  2398. STRUCT_FIELD_HEADER fieldHeader =
  2399. {
  2400. pRequest,
  2401. "LINEPROXYREQUEST",
  2402. 7,
  2403. fields
  2404. };
  2405. ShowStructByField (&fieldHeader, TRUE);
  2406. switch (pRequest->dwRequestType)
  2407. {
  2408. case LINEPROXYREQUEST_SETAGENTGROUP:
  2409. {
  2410. STRUCT_FIELD fields[] =
  2411. {
  2412. { szdwAddressID, FT_DWORD, pRequest->SetAgentGroup.dwAddressID, NULL }
  2413. // BUGBUG LINE_PROXYREQUEST: dump agent grp list
  2414. };
  2415. STRUCT_FIELD_HEADER fieldHeader =
  2416. {
  2417. pRequest,
  2418. "SetAgentGroup",
  2419. 1,
  2420. fields
  2421. };
  2422. ShowStructByField (&fieldHeader, TRUE);
  2423. break;
  2424. }
  2425. case LINEPROXYREQUEST_SETAGENTSTATE:
  2426. {
  2427. STRUCT_FIELD fields[] =
  2428. {
  2429. { szdwAddressID, FT_DWORD, pRequest->SetAgentState.dwAddressID, NULL },
  2430. { "dwAgentState", FT_ORD, pRequest->SetAgentState.dwAgentState, aAgentStates },
  2431. { "dwNextAgentState", FT_ORD, pRequest->SetAgentState.dwNextAgentState, aAgentStates }
  2432. };
  2433. STRUCT_FIELD_HEADER fieldHeader =
  2434. {
  2435. pRequest,
  2436. "SetAgentState",
  2437. 3,
  2438. fields
  2439. };
  2440. ShowStructByField (&fieldHeader, TRUE);
  2441. break;
  2442. }
  2443. case LINEPROXYREQUEST_SETAGENTACTIVITY:
  2444. {
  2445. STRUCT_FIELD fields[] =
  2446. {
  2447. { szdwAddressID, FT_DWORD, pRequest->SetAgentActivity.dwAddressID, NULL },
  2448. { "dwActivityID", FT_DWORD, pRequest->SetAgentActivity.dwActivityID, NULL }
  2449. };
  2450. STRUCT_FIELD_HEADER fieldHeader =
  2451. {
  2452. pRequest,
  2453. "SetAgentActivity",
  2454. 2,
  2455. fields
  2456. };
  2457. ShowStructByField (&fieldHeader, TRUE);
  2458. break;
  2459. }
  2460. case LINEPROXYREQUEST_GETAGENTCAPS:
  2461. {
  2462. STRUCT_FIELD fields[] =
  2463. {
  2464. { szdwAddressID, FT_DWORD, pRequest->GetAgentCaps.dwAddressID, NULL }
  2465. };
  2466. STRUCT_FIELD_HEADER fieldHeader =
  2467. {
  2468. pRequest,
  2469. "GetAgentCaps",
  2470. 1,
  2471. fields
  2472. };
  2473. // BUGBUG LINE_PROXYREQUEST: fill in agent caps?
  2474. ShowStructByField (&fieldHeader, TRUE);
  2475. break;
  2476. }
  2477. case LINEPROXYREQUEST_GETAGENTSTATUS:
  2478. {
  2479. STRUCT_FIELD fields[] =
  2480. {
  2481. { szdwAddressID, FT_DWORD, pRequest->GetAgentStatus.dwAddressID, NULL }
  2482. };
  2483. STRUCT_FIELD_HEADER fieldHeader =
  2484. {
  2485. pRequest,
  2486. "GetAgentStatus",
  2487. 1,
  2488. fields
  2489. };
  2490. ShowStructByField (&fieldHeader, TRUE);
  2491. break;
  2492. }
  2493. case LINEPROXYREQUEST_AGENTSPECIFIC:
  2494. {
  2495. STRUCT_FIELD fields[] =
  2496. {
  2497. { szdwAddressID, FT_DWORD, (DWORD) pRequest->AgentSpecific.dwAddressID, NULL },
  2498. { "dwAgentExtensionIDIndex", FT_DWORD, (DWORD) pRequest->AgentSpecific.dwAgentExtensionIDIndex, NULL },
  2499. { szdwSize, FT_SIZE, (DWORD) pRequest->AgentSpecific.dwSize, NULL },
  2500. { "Params", FT_OFFSET, (DWORD) (pRequest->AgentSpecific.Params - (LPBYTE) pRequest), NULL }
  2501. };
  2502. STRUCT_FIELD_HEADER fieldHeader =
  2503. {
  2504. pRequest,
  2505. "AgentSpecific",
  2506. 4,
  2507. fields
  2508. };
  2509. ShowStructByField (&fieldHeader, TRUE);
  2510. break;
  2511. }
  2512. case LINEPROXYREQUEST_GETAGENTACTIVITYLIST:
  2513. {
  2514. STRUCT_FIELD fields[] =
  2515. {
  2516. { szdwAddressID, FT_DWORD, pRequest->GetAgentActivityList.dwAddressID, NULL }
  2517. };
  2518. STRUCT_FIELD_HEADER fieldHeader =
  2519. {
  2520. pRequest,
  2521. "GetAgentActivityList",
  2522. 1,
  2523. fields
  2524. };
  2525. // BUGBUG LINE_PROXYREQUEST: fill in agent activity list?
  2526. ShowStructByField (&fieldHeader, TRUE);
  2527. break;
  2528. }
  2529. case LINEPROXYREQUEST_GETAGENTGROUPLIST:
  2530. {
  2531. STRUCT_FIELD fields[] =
  2532. {
  2533. { szdwAddressID, FT_DWORD, pRequest->GetAgentGroupList.dwAddressID, NULL }
  2534. };
  2535. STRUCT_FIELD_HEADER fieldHeader =
  2536. {
  2537. pRequest,
  2538. "GetAgentGroupList",
  2539. 1,
  2540. fields
  2541. };
  2542. // BUGBUG LINE_PROXYREQUEST: fill in agent grp list?
  2543. ShowStructByField (&fieldHeader, TRUE);
  2544. break;
  2545. }
  2546. } // switch (pRequest->dwRequestType)
  2547. break;
  2548. }
  2549. #endif
  2550. }
  2551. }
  2552. INT_PTR
  2553. CALLBACK
  2554. ParamsDlgProc(
  2555. HWND hwnd,
  2556. UINT msg,
  2557. WPARAM wParam,
  2558. LPARAM lParam
  2559. )
  2560. {
  2561. DWORD i;
  2562. typedef struct _DLG_INST_DATA
  2563. {
  2564. PFUNC_PARAM_HEADER pParamsHeader;
  2565. LRESULT lLastSel;
  2566. char szComboText[MAX_STRING_PARAM_SIZE];
  2567. } DLG_INST_DATA, *PDLG_INST_DATA;
  2568. PDLG_INST_DATA pDlgInstData = (PDLG_INST_DATA)
  2569. GetWindowLongPtr (hwnd, GWLP_USERDATA);
  2570. static int icxList2, icyList2, icyEdit1;
  2571. switch (msg)
  2572. {
  2573. case WM_INITDIALOG:
  2574. {
  2575. //
  2576. // Alloc a dlg instance data struct, init it, & save a ptr to it
  2577. //
  2578. pDlgInstData = (PDLG_INST_DATA) malloc (sizeof(DLG_INST_DATA));
  2579. // BUGBUG if (!pDlgInstData)
  2580. pDlgInstData->pParamsHeader = (PFUNC_PARAM_HEADER) lParam;
  2581. pDlgInstData->lLastSel = -1;
  2582. SetWindowLongPtr (hwnd, GWLP_USERDATA, (LONG_PTR) pDlgInstData);
  2583. //
  2584. // Stick all the param names in the listbox, & for each PT_DWORD
  2585. // param save it's default value
  2586. //
  2587. for (i = 0; i < pDlgInstData->pParamsHeader->dwNumParams; i++)
  2588. {
  2589. SendDlgItemMessage(
  2590. hwnd,
  2591. IDC_LIST1,
  2592. LB_INSERTSTRING,
  2593. (WPARAM) -1,
  2594. (LPARAM) pDlgInstData->pParamsHeader->aParams[i].szName
  2595. );
  2596. if (pDlgInstData->pParamsHeader->aParams[i].dwType == PT_DWORD)
  2597. {
  2598. pDlgInstData->pParamsHeader->aParams[i].u.dwDefValue =
  2599. pDlgInstData->pParamsHeader->aParams[i].dwValue;
  2600. }
  2601. }
  2602. //
  2603. // Set the dlg title as appropriate
  2604. //
  2605. // help if (pDlgInstData->pParamsHeader->FuncIndex == DefValues)
  2606. // help {
  2607. // help EnableWindow (GetDlgItem (hwnd, IDC_TB_HELP), FALSE);
  2608. // help }
  2609. SetWindowText(
  2610. hwnd,
  2611. aFuncNames[pDlgInstData->pParamsHeader->FuncIndex]
  2612. );
  2613. //
  2614. // Limit the max text length for the combobox's edit field
  2615. // (NOTE: A combobox ctrl actually has two child windows: a
  2616. // edit ctrl & a listbox. We need to get the hwnd of the
  2617. // child edit ctrl & send it the LIMITTEXT msg.)
  2618. //
  2619. {
  2620. HWND hwndChild =
  2621. GetWindow (GetDlgItem (hwnd, IDC_COMBO1), GW_CHILD);
  2622. while (hwndChild)
  2623. {
  2624. char buf[8];
  2625. GetClassName (hwndChild, buf, 7);
  2626. if (_stricmp (buf, "edit") == 0)
  2627. {
  2628. break;
  2629. }
  2630. hwndChild = GetWindow (hwndChild, GW_HWNDNEXT);
  2631. }
  2632. SendMessage(
  2633. hwndChild,
  2634. EM_LIMITTEXT,
  2635. (WPARAM) (gbWideStringParams ?
  2636. (MAX_STRING_PARAM_SIZE/2 - 1) : MAX_STRING_PARAM_SIZE - 1),
  2637. 0
  2638. );
  2639. }
  2640. {
  2641. RECT rect;
  2642. GetWindowRect (GetDlgItem (hwnd, IDC_LIST2), &rect);
  2643. SetWindowPos(
  2644. GetDlgItem (hwnd, IDC_LIST2),
  2645. NULL,
  2646. 0,
  2647. 0,
  2648. 0,
  2649. 0,
  2650. SWP_NOMOVE | SWP_NOZORDER
  2651. );
  2652. icxList2 = rect.right - rect.left;
  2653. icyList2 = rect.bottom - rect.top;
  2654. GetWindowRect (GetDlgItem (hwnd, 58), &rect);
  2655. icyEdit1 = icyList2 - (rect.bottom - rect.top);
  2656. }
  2657. SendDlgItemMessage(
  2658. hwnd,
  2659. IDC_EDIT1,
  2660. WM_SETFONT,
  2661. (WPARAM) ghFixedFont,
  2662. 0
  2663. );
  2664. break;
  2665. }
  2666. case WM_COMMAND:
  2667. {
  2668. LRESULT lLastSel = pDlgInstData->lLastSel;
  2669. char far *lpszComboText = pDlgInstData->szComboText;
  2670. PFUNC_PARAM_HEADER pParamsHeader = pDlgInstData->pParamsHeader;
  2671. switch (LOWORD(wParam))
  2672. {
  2673. case IDC_EDIT1:
  2674. {
  2675. if (HIWORD(wParam) == EN_CHANGE)
  2676. {
  2677. //
  2678. // Don't allow the user to enter characters other than
  2679. // 0-9, a-f, or A-F in the edit control (do this by
  2680. // hiliting other letters and cutting them).
  2681. //
  2682. HWND hwndEdit = GetDlgItem (hwnd, IDC_EDIT1);
  2683. DWORD dwLength, j;
  2684. BYTE *p;
  2685. dwLength = (DWORD) GetWindowTextLength (hwndEdit);
  2686. if (dwLength && (p = malloc (dwLength + 1)))
  2687. {
  2688. GetWindowText (hwndEdit, p, dwLength + 1);
  2689. for (i = j = 0; i < dwLength ; i++, j++)
  2690. {
  2691. if (aHex[p[i]] == 255)
  2692. {
  2693. SendMessage(
  2694. hwndEdit,
  2695. EM_SETSEL,
  2696. (WPARAM) j,
  2697. (LPARAM) j + 1 // 0xfffffffe
  2698. );
  2699. SendMessage (hwndEdit, EM_REPLACESEL, 0, (LPARAM) "");
  2700. SendMessage (hwndEdit, EM_SCROLLCARET, 0, 0);
  2701. j--;
  2702. }
  2703. }
  2704. free (p);
  2705. }
  2706. }
  2707. break;
  2708. }
  2709. case IDOK:
  2710. if (lLastSel != -1)
  2711. {
  2712. //
  2713. // Save val of currently selected param
  2714. //
  2715. char buf[MAX_STRING_PARAM_SIZE];
  2716. i = GetDlgItemText (hwnd, IDC_COMBO1, buf, MAX_STRING_PARAM_SIZE-1);
  2717. switch (pParamsHeader->aParams[lLastSel].dwType)
  2718. {
  2719. case PT_STRING:
  2720. {
  2721. LRESULT lComboSel;
  2722. lComboSel = SendDlgItemMessage(
  2723. hwnd,
  2724. IDC_COMBO1,
  2725. CB_GETCURSEL,
  2726. 0,
  2727. 0
  2728. );
  2729. if (lComboSel == 0) // "NULL pointer"
  2730. {
  2731. pParamsHeader->aParams[lLastSel].dwValue = (ULONG_PTR) 0;
  2732. }
  2733. else if (lComboSel == 2) // "Invalid string pointer"
  2734. {
  2735. pParamsHeader->aParams[lLastSel].dwValue = (ULONG_PTR)
  2736. -1;
  2737. }
  2738. else // "Valid string pointer"
  2739. {
  2740. strncpy(
  2741. pParamsHeader->aParams[lLastSel].u.buf,
  2742. buf,
  2743. MAX_STRING_PARAM_SIZE - 1
  2744. );
  2745. pParamsHeader->aParams[lLastSel].u.buf[MAX_STRING_PARAM_SIZE-1] = 0;
  2746. pParamsHeader->aParams[lLastSel].dwValue = (ULONG_PTR)
  2747. pParamsHeader->aParams[lLastSel].u.buf;
  2748. }
  2749. break;
  2750. }
  2751. case PT_POINTER:
  2752. {
  2753. //
  2754. // If there is any text in the "Buffer byte editor"
  2755. // window then retrieve it, convert it to hexadecimal,
  2756. // and copy it to the buffer
  2757. //
  2758. DWORD dwLength;
  2759. BYTE *p, *p2,
  2760. *pBuf = pParamsHeader->aParams[lLastSel].u.ptr;
  2761. HWND hwndEdit = GetDlgItem (hwnd,IDC_EDIT1);
  2762. dwLength = (DWORD) GetWindowTextLength (hwndEdit);
  2763. if (dwLength && (p = malloc (dwLength + 1)))
  2764. {
  2765. GetWindowText (hwndEdit, p, dwLength + 1);
  2766. SetWindowText (hwndEdit, "");
  2767. p2 = p;
  2768. p[dwLength] = (BYTE) '0';
  2769. dwLength = (dwLength + 1) & 0xfffffffe;
  2770. for (i = 0; i < dwLength; i++, i++)
  2771. {
  2772. BYTE b;
  2773. b = aHex[*p] << 4;
  2774. p++;
  2775. b |= aHex[*p];
  2776. p++;
  2777. *pBuf = b;
  2778. pBuf++;
  2779. }
  2780. free (p2);
  2781. }
  2782. // fall thru to code below
  2783. }
  2784. case PT_DWORD:
  2785. case PT_FLAGS:
  2786. case PT_CALLPARAMS: // ??? BUGBUG
  2787. case PT_FORWARDLIST: // ??? BUGBUG
  2788. case PT_ORDINAL:
  2789. {
  2790. if (!sscanf(
  2791. buf,
  2792. "%08lx",
  2793. &pParamsHeader->aParams[lLastSel].dwValue
  2794. ))
  2795. {
  2796. //
  2797. // Default to 0
  2798. //
  2799. pParamsHeader->aParams[lLastSel].dwValue = 0;
  2800. }
  2801. break;
  2802. }
  2803. } // switch
  2804. }
  2805. free (pDlgInstData);
  2806. EndDialog (hwnd, TRUE);
  2807. break;
  2808. case IDCANCEL:
  2809. free (pDlgInstData);
  2810. EndDialog (hwnd, FALSE);
  2811. break;
  2812. // help case IDC_TB_HELP:
  2813. // help
  2814. // help MyWinHelp(
  2815. // help hwnd,
  2816. // help TRUE,
  2817. // help HELP_PARTIALKEY,
  2818. // help (DWORD) aFuncNames[pParamsHeader->FuncIndex]
  2819. // help );
  2820. // help
  2821. // help break;
  2822. case IDC_LIST1:
  2823. #ifdef WIN32
  2824. if (HIWORD(wParam) == LBN_SELCHANGE)
  2825. #else
  2826. if (HIWORD(lParam) == LBN_SELCHANGE)
  2827. #endif
  2828. {
  2829. char buf[MAX_STRING_PARAM_SIZE] = "";
  2830. LPCSTR lpstr = buf;
  2831. LRESULT lSel =
  2832. SendDlgItemMessage (hwnd, IDC_LIST1, LB_GETCURSEL, 0, 0);
  2833. if (lLastSel != -1)
  2834. {
  2835. //
  2836. // Save the old param value
  2837. //
  2838. i = GetDlgItemText(
  2839. hwnd,
  2840. IDC_COMBO1,
  2841. buf,
  2842. MAX_STRING_PARAM_SIZE - 1
  2843. );
  2844. switch (pParamsHeader->aParams[lLastSel].dwType)
  2845. {
  2846. case PT_STRING:
  2847. {
  2848. LRESULT lComboSel;
  2849. lComboSel = SendDlgItemMessage(
  2850. hwnd,
  2851. IDC_COMBO1,
  2852. CB_GETCURSEL,
  2853. 0,
  2854. 0
  2855. );
  2856. if (lComboSel == 0) // "NULL pointer"
  2857. {
  2858. pParamsHeader->aParams[lLastSel].dwValue =
  2859. (ULONG_PTR) 0;
  2860. }
  2861. else if (lComboSel == 2) // "Invalid string pointer"
  2862. {
  2863. pParamsHeader->aParams[lLastSel].dwValue =
  2864. (ULONG_PTR) -1;
  2865. }
  2866. else // "Valid string pointer" or no sel
  2867. {
  2868. strncpy(
  2869. pParamsHeader->aParams[lLastSel].u.buf,
  2870. buf,
  2871. MAX_STRING_PARAM_SIZE - 1
  2872. );
  2873. pParamsHeader->aParams[lLastSel].u.buf[MAX_STRING_PARAM_SIZE - 1] = 0;
  2874. pParamsHeader->aParams[lLastSel].dwValue =
  2875. (ULONG_PTR)
  2876. pParamsHeader->aParams[lLastSel].u.buf;
  2877. }
  2878. break;
  2879. }
  2880. case PT_POINTER:
  2881. {
  2882. //
  2883. // If there is any text in the "Buffer byte editor"
  2884. // window then retrieve it, convert it to hexadecimal,
  2885. // and copy it to the buffer
  2886. //
  2887. DWORD dwLength;
  2888. BYTE *p, *p2,
  2889. *pBuf = pParamsHeader->aParams[lLastSel].u.ptr;
  2890. HWND hwndEdit = GetDlgItem (hwnd,IDC_EDIT1);
  2891. dwLength = (DWORD) GetWindowTextLength (hwndEdit);
  2892. if (dwLength && (p = malloc (dwLength + 1)))
  2893. {
  2894. GetWindowText (hwndEdit, p, dwLength + 1);
  2895. SetWindowText (hwndEdit, "");
  2896. p2 = p;
  2897. p[dwLength] = (BYTE) '0';
  2898. dwLength = (dwLength + 1) & 0xfffffffe;
  2899. for (i = 0; i < dwLength; i+= 2)
  2900. {
  2901. BYTE b;
  2902. b = aHex[*p] << 4;
  2903. p++;
  2904. b |= aHex[*p];
  2905. p++;
  2906. *pBuf = b;
  2907. pBuf++;
  2908. }
  2909. free (p2);
  2910. }
  2911. // fall thru to code below
  2912. }
  2913. case PT_DWORD:
  2914. case PT_FLAGS:
  2915. case PT_CALLPARAMS: // ??? BUGBUG
  2916. case PT_FORWARDLIST: // ??? BUGBUG
  2917. case PT_ORDINAL:
  2918. {
  2919. if (!sscanf(
  2920. buf,
  2921. "%08lx",
  2922. &pParamsHeader->aParams[lLastSel].dwValue
  2923. ))
  2924. {
  2925. //
  2926. // Default to 0
  2927. //
  2928. pParamsHeader->aParams[lLastSel].dwValue = 0;
  2929. }
  2930. break;
  2931. }
  2932. } // switch
  2933. }
  2934. SendDlgItemMessage (hwnd, IDC_LIST2, LB_RESETCONTENT, 0, 0);
  2935. SendDlgItemMessage (hwnd, IDC_COMBO1, CB_RESETCONTENT, 0, 0);
  2936. {
  2937. int icxL2 = 0, icyL2 = 0, icxE1 = 0, icyE1 = 0;
  2938. char FAR *pszS1 = NULL, *pszS2 = NULL;
  2939. static char szBitFlags[] = "Bit flags:";
  2940. static char szOrdinalValues[] = "Ordinal values:";
  2941. static char szBufByteEdit[] =
  2942. "Buffer byte editor (use 0-9, a-f, A-F)";
  2943. switch (pParamsHeader->aParams[lSel].dwType)
  2944. {
  2945. case PT_FLAGS:
  2946. icxL2 = icxList2;
  2947. icyL2 = icyList2;
  2948. pszS1 = szBitFlags;
  2949. break;
  2950. case PT_POINTER:
  2951. icxE1 = icxList2;
  2952. icyE1 = icyEdit1;;
  2953. pszS1 = szBufByteEdit;
  2954. pszS2 = gszEnterAs;
  2955. break;
  2956. case PT_ORDINAL:
  2957. icxL2 = icxList2;
  2958. icyL2 = icyList2;
  2959. pszS1 = szOrdinalValues;
  2960. break;
  2961. default:
  2962. break;
  2963. }
  2964. SetWindowPos(
  2965. GetDlgItem (hwnd, IDC_LIST2),
  2966. NULL,
  2967. 0,
  2968. 0,
  2969. icxL2,
  2970. icyL2,
  2971. SWP_NOMOVE | SWP_NOZORDER
  2972. );
  2973. SetWindowPos(
  2974. GetDlgItem (hwnd, IDC_EDIT1),
  2975. NULL,
  2976. 0,
  2977. 0,
  2978. icxE1,
  2979. icyE1,
  2980. SWP_NOMOVE | SWP_NOZORDER
  2981. );
  2982. SetDlgItemText (hwnd, 57, pszS1);
  2983. SetDlgItemText (hwnd, 58, pszS2);
  2984. }
  2985. switch (pParamsHeader->aParams[lSel].dwType)
  2986. {
  2987. case PT_STRING:
  2988. {
  2989. char * aszOptions[] =
  2990. {
  2991. "NULL pointer",
  2992. "Valid string pointer",
  2993. "Invalid string pointer"
  2994. };
  2995. for (i = 0; i < 3; i++)
  2996. {
  2997. SendDlgItemMessage(
  2998. hwnd,
  2999. IDC_COMBO1,
  3000. CB_INSERTSTRING,
  3001. (WPARAM) -1,
  3002. (LPARAM) aszOptions[i]
  3003. );
  3004. }
  3005. if (pParamsHeader->aParams[lSel].dwValue == 0)
  3006. {
  3007. i = 0;
  3008. buf[0] = 0;
  3009. }
  3010. else if (pParamsHeader->aParams[lSel].dwValue !=
  3011. (ULONG_PTR) -1)
  3012. {
  3013. i = 1;
  3014. lpstr = (LPCSTR) pParamsHeader->aParams[lSel].dwValue;
  3015. }
  3016. else
  3017. {
  3018. i = 2;
  3019. buf[0] = 0;
  3020. }
  3021. SendDlgItemMessage(
  3022. hwnd,
  3023. IDC_COMBO1,
  3024. CB_SETCURSEL,
  3025. (WPARAM) i,
  3026. 0
  3027. );
  3028. break;
  3029. }
  3030. case PT_POINTER:
  3031. case PT_CALLPARAMS: // ??? BUGBUG
  3032. case PT_FORWARDLIST: // ??? BUGBUG
  3033. {
  3034. SendDlgItemMessage(
  3035. hwnd,
  3036. IDC_COMBO1,
  3037. CB_INSERTSTRING,
  3038. (WPARAM) -1,
  3039. (LPARAM) "00000000"
  3040. );
  3041. sprintf(
  3042. buf,
  3043. "%08lx (valid pointer)",
  3044. pParamsHeader->aParams[lSel].u.dwDefValue
  3045. );
  3046. SendDlgItemMessage(
  3047. hwnd,
  3048. IDC_COMBO1,
  3049. CB_INSERTSTRING,
  3050. (WPARAM) -1,
  3051. (LPARAM) buf
  3052. );
  3053. SendDlgItemMessage(
  3054. hwnd,
  3055. IDC_COMBO1,
  3056. CB_INSERTSTRING,
  3057. (WPARAM) -1,
  3058. (LPARAM) "ffffffff"
  3059. );
  3060. sprintf(
  3061. buf,
  3062. "%08lx",
  3063. pParamsHeader->aParams[lSel].dwValue
  3064. );
  3065. break;
  3066. }
  3067. case PT_DWORD:
  3068. {
  3069. SendDlgItemMessage(
  3070. hwnd,
  3071. IDC_COMBO1,
  3072. CB_INSERTSTRING,
  3073. (WPARAM) -1,
  3074. (LPARAM) "0000000"
  3075. );
  3076. if (pParamsHeader->aParams[lSel].u.dwDefValue)
  3077. {
  3078. //
  3079. // Add the default val string to the combo
  3080. //
  3081. sprintf(
  3082. buf,
  3083. "%08lx",
  3084. pParamsHeader->aParams[lSel].u.dwDefValue
  3085. );
  3086. SendDlgItemMessage(
  3087. hwnd,
  3088. IDC_COMBO1,
  3089. CB_INSERTSTRING,
  3090. (WPARAM) -1,
  3091. (LPARAM) buf
  3092. );
  3093. }
  3094. SendDlgItemMessage(
  3095. hwnd,
  3096. IDC_COMBO1,
  3097. CB_INSERTSTRING,
  3098. (WPARAM) -1,
  3099. (LPARAM) "ffffffff"
  3100. );
  3101. sprintf(
  3102. buf,
  3103. "%08lx",
  3104. pParamsHeader->aParams[lSel].dwValue
  3105. );
  3106. break;
  3107. }
  3108. case PT_FLAGS:
  3109. {
  3110. //
  3111. // Stick the bit flag strings in the list box
  3112. //
  3113. PLOOKUP pLookup = (PLOOKUP)
  3114. pParamsHeader->aParams[lSel].u.pLookup;
  3115. for (i = 0; pLookup[i].dwVal != 0xffffffff; i++)
  3116. {
  3117. SendDlgItemMessage(
  3118. hwnd,
  3119. IDC_LIST2,
  3120. LB_INSERTSTRING,
  3121. (WPARAM) -1,
  3122. (LPARAM) pLookup[i].lpszVal
  3123. );
  3124. if (pParamsHeader->aParams[lSel].dwValue &
  3125. pLookup[i].dwVal)
  3126. {
  3127. SendDlgItemMessage(
  3128. hwnd,
  3129. IDC_LIST2,
  3130. LB_SETSEL,
  3131. (WPARAM) TRUE,
  3132. (LPARAM) MAKELPARAM((WORD)i,0)
  3133. );
  3134. }
  3135. }
  3136. SendDlgItemMessage(
  3137. hwnd,
  3138. IDC_COMBO1,
  3139. CB_INSERTSTRING,
  3140. (WPARAM) -1,
  3141. (LPARAM) "select none"
  3142. );
  3143. SendDlgItemMessage(
  3144. hwnd,
  3145. IDC_COMBO1,
  3146. CB_INSERTSTRING,
  3147. (WPARAM) -1,
  3148. (LPARAM) "select all"
  3149. );
  3150. sprintf(
  3151. buf,
  3152. "%08lx",
  3153. pParamsHeader->aParams[lSel].dwValue
  3154. );
  3155. break;
  3156. }
  3157. case PT_ORDINAL:
  3158. {
  3159. //
  3160. // Stick the bit flag strings in the list box
  3161. //
  3162. HWND hwndList2 = GetDlgItem (hwnd, IDC_LIST2);
  3163. PLOOKUP pLookup = (PLOOKUP)
  3164. pParamsHeader->aParams[lSel].u.pLookup;
  3165. for (i = 0; pLookup[i].dwVal != 0xffffffff; i++)
  3166. {
  3167. SendMessage(
  3168. hwndList2,
  3169. LB_INSERTSTRING,
  3170. (WPARAM) -1,
  3171. (LPARAM) pLookup[i].lpszVal
  3172. );
  3173. if (pParamsHeader->aParams[lSel].dwValue ==
  3174. pLookup[i].dwVal)
  3175. {
  3176. SendMessage(
  3177. hwndList2,
  3178. LB_SETSEL,
  3179. (WPARAM) TRUE,
  3180. (LPARAM) MAKELPARAM((WORD)i,0)
  3181. );
  3182. }
  3183. }
  3184. SendDlgItemMessage(
  3185. hwnd,
  3186. IDC_COMBO1,
  3187. CB_INSERTSTRING,
  3188. (WPARAM) -1,
  3189. (LPARAM) (char far *) "select none"
  3190. );
  3191. wsprintf(
  3192. buf,
  3193. "%08lx",
  3194. pParamsHeader->aParams[lSel].dwValue
  3195. );
  3196. break;
  3197. }
  3198. } //switch
  3199. SetDlgItemText (hwnd, IDC_COMBO1, lpstr);
  3200. pDlgInstData->lLastSel = lSel;
  3201. }
  3202. break;
  3203. case IDC_LIST2:
  3204. #ifdef WIN32
  3205. if (HIWORD(wParam) == LBN_SELCHANGE)
  3206. #else
  3207. if (HIWORD(lParam) == LBN_SELCHANGE)
  3208. #endif
  3209. {
  3210. PLOOKUP pLookup = (PLOOKUP)
  3211. pParamsHeader->aParams[lLastSel].u.pLookup;
  3212. char buf[16];
  3213. DWORD dwValue = 0;
  3214. int far *ai;
  3215. LONG i;
  3216. LRESULT lSelCount =
  3217. SendDlgItemMessage (hwnd, IDC_LIST2, LB_GETSELCOUNT, 0, 0);
  3218. if (lSelCount)
  3219. {
  3220. ai = (int far *) malloc ((size_t)lSelCount * sizeof(int));
  3221. SendDlgItemMessage(
  3222. hwnd,
  3223. IDC_LIST2,
  3224. LB_GETSELITEMS,
  3225. (WPARAM) lSelCount,
  3226. (LPARAM) ai
  3227. );
  3228. if (pParamsHeader->aParams[lLastSel].dwType == PT_FLAGS)
  3229. {
  3230. for (i = 0; i < lSelCount; i++)
  3231. {
  3232. dwValue |= pLookup[ai[i]].dwVal;
  3233. }
  3234. }
  3235. else // if (.dwType == PT_ORDINAL)
  3236. {
  3237. if (lSelCount == 1)
  3238. {
  3239. dwValue = pLookup[ai[0]].dwVal;
  3240. }
  3241. else if (lSelCount == 2)
  3242. {
  3243. //
  3244. // Figure out which item we need to de-select,
  3245. // since we're doing ords & only want 1 item
  3246. // selected at a time
  3247. //
  3248. GetDlgItemText (hwnd, IDC_COMBO1, buf, 16);
  3249. if (sscanf (buf, "%lx", &dwValue))
  3250. {
  3251. if (pLookup[ai[0]].dwVal == dwValue)
  3252. {
  3253. SendDlgItemMessage(
  3254. hwnd,
  3255. IDC_LIST2,
  3256. LB_SETSEL,
  3257. 0,
  3258. (LPARAM) ai[0]
  3259. );
  3260. dwValue = pLookup[ai[1]].dwVal;
  3261. }
  3262. else
  3263. {
  3264. SendDlgItemMessage(
  3265. hwnd,
  3266. IDC_LIST2,
  3267. LB_SETSEL,
  3268. 0,
  3269. (LPARAM) ai[1]
  3270. );
  3271. dwValue = pLookup[ai[0]].dwVal;
  3272. }
  3273. }
  3274. else
  3275. {
  3276. // BUGBUG de-select items???
  3277. dwValue = 0;
  3278. }
  3279. }
  3280. }
  3281. free (ai);
  3282. }
  3283. sprintf (buf, "%08lx", dwValue);
  3284. SetDlgItemText (hwnd, IDC_COMBO1, buf);
  3285. }
  3286. break;
  3287. case IDC_COMBO1:
  3288. #ifdef WIN32
  3289. switch (HIWORD(wParam))
  3290. #else
  3291. switch (HIWORD(lParam))
  3292. #endif
  3293. {
  3294. case CBN_SELCHANGE:
  3295. {
  3296. LRESULT lSel =
  3297. SendDlgItemMessage (hwnd, IDC_COMBO1, CB_GETCURSEL, 0, 0);
  3298. switch (pParamsHeader->aParams[lLastSel].dwType)
  3299. {
  3300. case PT_POINTER:
  3301. {
  3302. if (lSel == 1)
  3303. {
  3304. //
  3305. // Strip off the "(valid pointer)" in the edit ctrl
  3306. //
  3307. wsprintf(
  3308. lpszComboText,
  3309. "%08lx",
  3310. pParamsHeader->aParams[lLastSel].u.ptr
  3311. );
  3312. PostMessage (hwnd, WM_USER+55, 0, 0);
  3313. }
  3314. break;
  3315. }
  3316. case PT_FLAGS:
  3317. {
  3318. BOOL bSelect = (lSel ? TRUE : FALSE);
  3319. SendDlgItemMessage(
  3320. hwnd,
  3321. IDC_LIST2,
  3322. LB_SETSEL,
  3323. (WPARAM) bSelect,
  3324. (LPARAM) -1
  3325. );
  3326. if (bSelect)
  3327. {
  3328. PLOOKUP pLookup = (PLOOKUP)
  3329. pParamsHeader->aParams[lLastSel].u.pLookup;
  3330. DWORD dwValue = 0;
  3331. int far *ai;
  3332. LONG i;
  3333. LRESULT lSelCount =
  3334. SendDlgItemMessage (hwnd, IDC_LIST2, LB_GETSELCOUNT, 0, 0);
  3335. if (lSelCount)
  3336. {
  3337. ai = (int far *) malloc ((size_t)lSelCount * sizeof(int));
  3338. SendDlgItemMessage(
  3339. hwnd,
  3340. IDC_LIST2,
  3341. LB_GETSELITEMS,
  3342. (WPARAM) lSelCount,
  3343. (LPARAM) ai
  3344. );
  3345. for (i = 0; i < lSelCount; i++)
  3346. {
  3347. dwValue |= pLookup[ai[i]].dwVal;
  3348. }
  3349. free (ai);
  3350. }
  3351. sprintf (lpszComboText, "%08lx", dwValue);
  3352. }
  3353. else
  3354. {
  3355. strcpy (lpszComboText, "00000000");
  3356. }
  3357. PostMessage (hwnd, WM_USER+55, 0, 0);
  3358. break;
  3359. }
  3360. case PT_STRING:
  3361. if (lSel == 1)
  3362. {
  3363. strncpy(
  3364. lpszComboText,
  3365. pParamsHeader->aParams[lLastSel].u.buf,
  3366. MAX_STRING_PARAM_SIZE
  3367. );
  3368. lpszComboText[MAX_STRING_PARAM_SIZE-1] = 0;
  3369. }
  3370. else
  3371. {
  3372. lpszComboText[0] = 0;
  3373. }
  3374. PostMessage (hwnd, WM_USER+55, 0, 0);
  3375. break;
  3376. case PT_DWORD:
  3377. break;
  3378. case PT_CALLPARAMS:
  3379. {
  3380. if (lSel == 1)
  3381. {
  3382. #if TAPI_2_0
  3383. LPLINECALLPARAMS lpCP = (gbWideStringParams ?
  3384. lpCallParamsW : lpCallParams);
  3385. #else
  3386. LPLINECALLPARAMS lpCP = lpCallParams;
  3387. #endif
  3388. char *p = (char *) lpCP;
  3389. #if TAPI_2_0
  3390. char asz[14][MAX_STRING_PARAM_SIZE];
  3391. LPDWORD pdwProxyRequests = (LPDWORD) (((LPBYTE) lpCP) +
  3392. lpCP->dwDevSpecificOffset);
  3393. #else
  3394. char asz[7][MAX_STRING_PARAM_SIZE];
  3395. #endif
  3396. FUNC_PARAM params[] =
  3397. {
  3398. { "dwBearerMode", PT_FLAGS, (ULONG_PTR) lpCP->dwBearerMode, aBearerModes },
  3399. { "dwMinRate", PT_DWORD, (ULONG_PTR) lpCP->dwMinRate, NULL },
  3400. { "dwMaxRate", PT_DWORD, (ULONG_PTR) lpCP->dwMaxRate, NULL },
  3401. { "dwMediaMode", PT_FLAGS, (ULONG_PTR) lpCP->dwMediaMode, aMediaModes },
  3402. { "dwCallParamFlags", PT_FLAGS, (ULONG_PTR) lpCP->dwCallParamFlags, aCallParamFlags },
  3403. { "dwAddressMode", PT_ORDINAL,(ULONG_PTR) lpCP->dwAddressMode, aAddressModes },
  3404. { "dwAddressID", PT_DWORD, (ULONG_PTR) lpCP->dwAddressID, NULL },
  3405. { "DIALPARAMS.dwDialPause", PT_DWORD, (ULONG_PTR) lpCP->DialParams.dwDialPause, NULL },
  3406. { "DIALPARAMS.dwDialSpeed", PT_DWORD, (ULONG_PTR) lpCP->DialParams.dwDialSpeed, NULL },
  3407. { "DIALPARAMS.dwDigitDuration", PT_DWORD, (ULONG_PTR) lpCP->DialParams.dwDigitDuration, NULL },
  3408. { "DIALPARAMS.dwWaitForDialtone", PT_DWORD, (ULONG_PTR) lpCP->DialParams.dwWaitForDialtone, NULL },
  3409. { "szOrigAddress", PT_STRING, (ULONG_PTR) asz[0], asz[0] },
  3410. { "szDisplayableAddress", PT_STRING, (ULONG_PTR) asz[1], asz[1] },
  3411. { "szCalledParty", PT_STRING, (ULONG_PTR) asz[2], asz[2] },
  3412. { "szComment", PT_STRING, (ULONG_PTR) asz[3], asz[3] },
  3413. { "szUserUserInfo", PT_STRING, (ULONG_PTR) asz[4], asz[4] },
  3414. { "szHighLevelComp", PT_STRING, (ULONG_PTR) asz[5], asz[5] },
  3415. { "szLowLevelComp", PT_STRING, (ULONG_PTR) asz[6], asz[6] }
  3416. #if TAPI_2_0
  3417. ,
  3418. { "dwPredictiveAutoTransferStates", PT_FLAGS, (ULONG_PTR) lpCP->dwPredictiveAutoTransferStates, aCallStates },
  3419. { "szTargetAddress", PT_STRING, (ULONG_PTR) asz[7], asz[7] },
  3420. { "szSendingFlowspec", PT_STRING, (ULONG_PTR) asz[8], asz[8] },
  3421. { "szReceivingFlowspec", PT_STRING, (ULONG_PTR) asz[9], asz[9] },
  3422. { "szDeviceClass", PT_STRING, (ULONG_PTR) asz[10], asz[10] },
  3423. { "szDeviceConfig", PT_STRING, (ULONG_PTR) asz[11], asz[11] },
  3424. { "szCallData", PT_STRING, (ULONG_PTR) asz[12], asz[12] },
  3425. { "dwNoAnswerTimeout", PT_DWORD, (ULONG_PTR) lpCP->dwNoAnswerTimeout, NULL },
  3426. { "szCallingPartyID", PT_STRING, (ULONG_PTR) asz[13], asz[13] },
  3427. { "NumProxyRequests", PT_DWORD, (ULONG_PTR) lpCP->dwDevSpecificSize / 4, NULL },
  3428. { " ProxyRequest1", PT_ORDINAL,(ULONG_PTR) *pdwProxyRequests, aProxyRequests },
  3429. { " ProxyRequest2", PT_ORDINAL,(ULONG_PTR) *(pdwProxyRequests + 1), aProxyRequests },
  3430. { " ProxyRequest3", PT_ORDINAL,(ULONG_PTR) *(pdwProxyRequests + 2), aProxyRequests },
  3431. { " ProxyRequest4", PT_ORDINAL,(ULONG_PTR) *(pdwProxyRequests + 3), aProxyRequests },
  3432. { " ProxyRequest5", PT_ORDINAL,(ULONG_PTR) *(pdwProxyRequests + 4), aProxyRequests },
  3433. { " ProxyRequest6", PT_ORDINAL,(ULONG_PTR) *(pdwProxyRequests + 5), aProxyRequests },
  3434. { " ProxyRequest7", PT_ORDINAL,(ULONG_PTR) *(pdwProxyRequests + 6), aProxyRequests },
  3435. { " ProxyRequest8", PT_ORDINAL,(ULONG_PTR) *(pdwProxyRequests + 7), aProxyRequests }
  3436. #endif
  3437. };
  3438. FUNC_PARAM_HEADER paramsHeader =
  3439. { 0, lCallParams, params, NULL };
  3440. int i;
  3441. LPDWORD apXxxSize[] =
  3442. {
  3443. &lpCP->dwOrigAddressSize,
  3444. &lpCP->dwDisplayableAddressSize,
  3445. &lpCP->dwCalledPartySize,
  3446. &lpCP->dwCommentSize,
  3447. &lpCP->dwUserUserInfoSize,
  3448. &lpCP->dwHighLevelCompSize,
  3449. &lpCP->dwLowLevelCompSize,
  3450. #if TAPI_2_0
  3451. &lpCP->dwTargetAddressSize,
  3452. &lpCP->dwSendingFlowspecSize,
  3453. &lpCP->dwReceivingFlowspecSize,
  3454. &lpCP->dwDeviceClassSize,
  3455. &lpCP->dwDeviceConfigSize,
  3456. &lpCP->dwCallDataSize,
  3457. &lpCP->dwCallingPartyIDSize,
  3458. #endif
  3459. NULL
  3460. };
  3461. static DWORD dwAPIVersion, adwStrParamIndices[] =
  3462. {
  3463. 11, 12, 13, 14, 15, 16, 17,
  3464. #if TAPI_2_0
  3465. 19, 20, 21, 22, 23, 24, 26,
  3466. #endif
  3467. 0
  3468. };
  3469. //
  3470. // Init the tmp string params
  3471. //
  3472. for (i = 0; apXxxSize[i]; i++)
  3473. {
  3474. if (*apXxxSize[i])
  3475. {
  3476. #if TAPI_2_0
  3477. if (gbWideStringParams)
  3478. {
  3479. WideCharToMultiByte(
  3480. CP_ACP,
  3481. 0,
  3482. (LPCWSTR) (p + *(apXxxSize[i] + 1)),
  3483. -1,
  3484. asz[i],
  3485. MAX_STRING_PARAM_SIZE,
  3486. NULL,
  3487. NULL
  3488. );
  3489. }
  3490. else
  3491. {
  3492. strcpy (asz[i], p + *(apXxxSize[i] + 1));
  3493. }
  3494. #else
  3495. strcpy (asz[i], p + *(apXxxSize[i] + 1));
  3496. #endif
  3497. }
  3498. else
  3499. {
  3500. asz[i][0] = 0;
  3501. }
  3502. }
  3503. if (pDlgInstData->pParamsHeader->FuncIndex == lOpen)
  3504. {
  3505. dwAPIVersion = (DWORD) pDlgInstData->
  3506. pParamsHeader->aParams[3].dwValue;
  3507. }
  3508. else
  3509. {
  3510. #if TAPI_2_0
  3511. dwAPIVersion = 0x00020000;
  3512. #else
  3513. dwAPIVersion = 0x00010004;
  3514. #endif
  3515. }
  3516. if (dwAPIVersion < 0x00020000)
  3517. {
  3518. paramsHeader.dwNumParams = 18;
  3519. apXxxSize[8] = NULL;
  3520. }
  3521. #if TAPI_2_0
  3522. else if (pDlgInstData->pParamsHeader->FuncIndex ==
  3523. lOpen)
  3524. {
  3525. paramsHeader.dwNumParams = 36;
  3526. }
  3527. else
  3528. {
  3529. paramsHeader.dwNumParams = 27;
  3530. }
  3531. #endif
  3532. if (DialogBoxParam(
  3533. ghInst,
  3534. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG2),
  3535. hwnd,
  3536. (DLGPROC) ParamsDlgProc,
  3537. (LPARAM) &paramsHeader
  3538. ))
  3539. {
  3540. LPDWORD lpdwXxx = &lpCP->dwBearerMode;
  3541. //
  3542. // Save the DWORD params
  3543. //
  3544. for (i = 0; i < 11; i++)
  3545. {
  3546. *(lpdwXxx + i) = (DWORD) params[i].dwValue;
  3547. }
  3548. #if TAPI_2_0
  3549. if (paramsHeader.dwNumParams > 18)
  3550. {
  3551. lpCP->dwPredictiveAutoTransferStates = (DWORD)
  3552. params[18].dwValue;
  3553. lpCP->dwNoAnswerTimeout = (DWORD)
  3554. params[25].dwValue;
  3555. if (paramsHeader.dwNumParams > 27)
  3556. {
  3557. lpCP->dwDevSpecificSize = (DWORD)
  3558. (4 * params[27].dwValue);
  3559. for (i = 0; i < 8; i++)
  3560. {
  3561. *(pdwProxyRequests + i) = (DWORD)
  3562. params[28+i].dwValue;
  3563. }
  3564. }
  3565. }
  3566. #endif
  3567. //
  3568. // Save the string params
  3569. //
  3570. for (i = 0; apXxxSize[i]; i++)
  3571. {
  3572. DWORD length, index = adwStrParamIndices[i];
  3573. if (params[index].dwValue &&
  3574. (params[index].dwValue != (ULONG_PTR) -1))
  3575. {
  3576. #if TAPI_2_0
  3577. if (gbWideStringParams)
  3578. {
  3579. length = MultiByteToWideChar(
  3580. CP_ACP,
  3581. MB_PRECOMPOSED,
  3582. (LPCSTR) asz[i],
  3583. -1,
  3584. (LPWSTR) (p + *(apXxxSize[i] + 1)),
  3585. // offset
  3586. MAX_STRING_PARAM_SIZE/2
  3587. );
  3588. length *= sizeof (WCHAR);
  3589. }
  3590. else
  3591. {
  3592. strcpy(
  3593. p + *(apXxxSize[i] + 1), // offset
  3594. asz[i]
  3595. );
  3596. length = (DWORD) strlen (asz[i]) + 1;
  3597. }
  3598. #else
  3599. strcpy(
  3600. p + *(apXxxSize[i] + 1), // offset
  3601. asz[i]
  3602. );
  3603. length = (DWORD) strlen (asz[i]) + 1;
  3604. #endif
  3605. }
  3606. else
  3607. {
  3608. length = 0;
  3609. }
  3610. *apXxxSize[i] = length;
  3611. }
  3612. }
  3613. //
  3614. // Strip off the "(valid pointer)" in the edit ctrl
  3615. //
  3616. wsprintf (lpszComboText, "%08lx", lpCP);
  3617. PostMessage (hwnd, WM_USER+55, 0, 0);
  3618. pParamsHeader->aParams[lLastSel].dwValue =
  3619. (ULONG_PTR) lpCP;
  3620. }
  3621. break;
  3622. }
  3623. case PT_FORWARDLIST:
  3624. {
  3625. if (lSel == 1)
  3626. {
  3627. char asz[MAX_LINEFORWARD_ENTRIES][2][MAX_STRING_PARAM_SIZE];
  3628. FUNC_PARAM params[] =
  3629. {
  3630. { "dwNumEntries", PT_DWORD, 0, 0 },
  3631. { "[0].dwFowardMode", PT_FLAGS, 0, aForwardModes },
  3632. { "[0].lpszCallerAddress", PT_STRING, 0, asz[0][0] },
  3633. { "[0].dwDestCountryCode", PT_DWORD, 0, 0 },
  3634. { "[0].lpszDestAddress", PT_STRING, 0, asz[0][1] },
  3635. { "[1].dwFowardMode", PT_FLAGS, 0, aForwardModes },
  3636. { "[1].lpszCallerAddress", PT_STRING, 0, asz[1][0] },
  3637. { "[1].dwDestCountryCode", PT_DWORD, 0, 0 },
  3638. { "[1].lpszDestAddress", PT_STRING, 0, asz[1][1] },
  3639. { "[2].dwFowardMode", PT_FLAGS, 0, aForwardModes },
  3640. { "[2].lpszCallerAddress", PT_STRING, 0, asz[2][0] },
  3641. { "[2].dwDestCountryCode", PT_DWORD, 0, 0 },
  3642. { "[2].lpszDestAddress", PT_STRING, 0, asz[2][1] },
  3643. { "[3].dwFowardMode", PT_FLAGS, 0, aForwardModes },
  3644. { "[3].lpszCallerAddress", PT_STRING, 0, asz[3][0] },
  3645. { "[3].dwDestCountryCode", PT_DWORD, 0, 0 },
  3646. { "[3].lpszDestAddress", PT_STRING, 0, asz[3][1] },
  3647. { "[4].dwFowardMode", PT_FLAGS, 0, aForwardModes },
  3648. { "[4].lpszCallerAddress", PT_STRING, 0, asz[4][0] },
  3649. { "[4].dwDestCountryCode", PT_DWORD, 0, 0 },
  3650. { "[4].lpszDestAddress", PT_STRING, 0, asz[4][1] },
  3651. };
  3652. FUNC_PARAM_HEADER paramsHeader =
  3653. { 21, lForwardList, params, NULL };
  3654. memset(
  3655. asz,
  3656. 0,
  3657. MAX_LINEFORWARD_ENTRIES*2*MAX_STRING_PARAM_SIZE
  3658. );
  3659. if (DialogBoxParam(
  3660. ghInst,
  3661. (LPCSTR)MAKEINTRESOURCE(IDD_DIALOG2),
  3662. hwnd,
  3663. (DLGPROC) ParamsDlgProc,
  3664. (LPARAM) &paramsHeader
  3665. ))
  3666. {
  3667. LPLINEFORWARDLIST lpForwardList =
  3668. (LPLINEFORWARDLIST)
  3669. pParamsHeader->aParams[lLastSel].u.ptr;
  3670. LPLINEFORWARD lpEntry = lpForwardList->ForwardList;
  3671. DWORD dwNumEntriesToInit =
  3672. (params[0].dwValue > MAX_LINEFORWARD_ENTRIES ?
  3673. MAX_LINEFORWARD_ENTRIES :
  3674. (DWORD) params[0].dwValue);
  3675. DWORD i, dwFixedSize = sizeof(LINEFORWARDLIST) +
  3676. (MAX_LINEFORWARD_ENTRIES-1)*sizeof(LINEFORWARD);
  3677. lpForwardList->dwNumEntries = (DWORD)
  3678. params[0].dwValue;
  3679. for (i = 0; i < dwNumEntriesToInit; i++)
  3680. {
  3681. lpEntry->dwForwardMode = (DWORD)
  3682. params[1 + 4*i].dwValue;
  3683. if (params[2 + 4*i].dwValue &&
  3684. params[2 + 4*i].dwValue != (ULONG_PTR) -1)
  3685. {
  3686. lpEntry->dwCallerAddressSize =
  3687. strlen (asz[i][0]) + 1;
  3688. lpEntry->dwCallerAddressOffset =
  3689. dwFixedSize +
  3690. 2*i*MAX_STRING_PARAM_SIZE;
  3691. #if TAPI_2_0
  3692. if (gbWideStringParams)
  3693. {
  3694. lpEntry->dwCallerAddressSize *=
  3695. sizeof (WCHAR);
  3696. MultiByteToWideChar(
  3697. CP_ACP,
  3698. MB_PRECOMPOSED,
  3699. (LPCSTR) asz[i][0],
  3700. -1,
  3701. (LPWSTR) ((char *) lpForwardList +
  3702. lpEntry->dwCallerAddressOffset),
  3703. MAX_STRING_PARAM_SIZE / 2
  3704. );
  3705. }
  3706. else
  3707. {
  3708. strcpy(
  3709. (char *) lpForwardList +
  3710. lpEntry->dwCallerAddressOffset,
  3711. asz[i][0]
  3712. );
  3713. }
  3714. #else
  3715. strcpy(
  3716. (char *) lpForwardList +
  3717. lpEntry->dwCallerAddressOffset,
  3718. asz[i][0]
  3719. );
  3720. #endif
  3721. }
  3722. lpEntry->dwDestCountryCode = (DWORD)
  3723. params[3 + 4*i].dwValue;
  3724. if (params[4 + 4*i].dwValue &&
  3725. params[4 + 4*i].dwValue != (ULONG_PTR) -1)
  3726. {
  3727. lpEntry->dwDestAddressSize =
  3728. strlen (asz[i][1]) + 1;
  3729. lpEntry->dwDestAddressOffset =
  3730. dwFixedSize +
  3731. (2*i + 1)*MAX_STRING_PARAM_SIZE;
  3732. #if TAPI_2_0
  3733. if (gbWideStringParams)
  3734. {
  3735. lpEntry->dwDestAddressSize *=
  3736. sizeof (WCHAR);
  3737. MultiByteToWideChar(
  3738. CP_ACP,
  3739. MB_PRECOMPOSED,
  3740. (LPCSTR) asz[i][1],
  3741. -1,
  3742. (LPWSTR) ((char *) lpForwardList +
  3743. lpEntry->dwDestAddressOffset),
  3744. MAX_STRING_PARAM_SIZE / 2
  3745. );
  3746. }
  3747. else
  3748. {
  3749. strcpy(
  3750. (char *) lpForwardList +
  3751. lpEntry->dwDestAddressOffset,
  3752. asz[i][1]
  3753. );
  3754. }
  3755. #else
  3756. strcpy(
  3757. (char *) lpForwardList +
  3758. lpEntry->dwDestAddressOffset,
  3759. asz[i][1]
  3760. );
  3761. #endif
  3762. }
  3763. lpEntry++;
  3764. }
  3765. }
  3766. //
  3767. // Strip off the "(valid pointer)" in the edit ctrl
  3768. //
  3769. wsprintf(
  3770. lpszComboText,
  3771. "%08lx",
  3772. pParamsHeader->aParams[lLastSel].u.ptr
  3773. );
  3774. PostMessage (hwnd, WM_USER+55, 0, 0);
  3775. }
  3776. break;
  3777. }
  3778. case PT_ORDINAL:
  3779. //
  3780. // The only option here is "select none"
  3781. //
  3782. strcpy (lpszComboText, "00000000");
  3783. PostMessage (hwnd, WM_USER+55, 0, 0);
  3784. break;
  3785. } // switch
  3786. break;
  3787. }
  3788. case CBN_EDITCHANGE:
  3789. {
  3790. //
  3791. // If user entered text in the edit field then copy the
  3792. // text to our buffer
  3793. //
  3794. if (pParamsHeader->aParams[lLastSel].dwType == PT_STRING)
  3795. {
  3796. char buf[MAX_STRING_PARAM_SIZE];
  3797. GetDlgItemText(
  3798. hwnd,
  3799. IDC_COMBO1,
  3800. buf,
  3801. MAX_STRING_PARAM_SIZE
  3802. );
  3803. strncpy(
  3804. pParamsHeader->aParams[lLastSel].u.buf,
  3805. buf,
  3806. MAX_STRING_PARAM_SIZE
  3807. );
  3808. pParamsHeader->aParams[lLastSel].u.buf
  3809. [MAX_STRING_PARAM_SIZE-1] = 0;
  3810. }
  3811. break;
  3812. }
  3813. } // switch
  3814. } // switch
  3815. break;
  3816. }
  3817. case WM_USER+55:
  3818. SetDlgItemText (hwnd, IDC_COMBO1, pDlgInstData->szComboText);
  3819. break;
  3820. #ifdef WIN32
  3821. case WM_CTLCOLORSTATIC:
  3822. SetBkColor ((HDC) wParam, RGB (192,192,192));
  3823. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  3824. #else
  3825. case WM_CTLCOLOR:
  3826. {
  3827. if (HIWORD(lParam) == CTLCOLOR_STATIC)
  3828. {
  3829. SetBkColor ((HDC) wParam, RGB (192,192,192));
  3830. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  3831. }
  3832. break;
  3833. }
  3834. #endif
  3835. case WM_PAINT:
  3836. {
  3837. PAINTSTRUCT ps;
  3838. BeginPaint (hwnd, &ps);
  3839. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  3840. EndPaint (hwnd, &ps);
  3841. break;
  3842. }
  3843. } // switch
  3844. return 0;
  3845. }
  3846. INT_PTR
  3847. CALLBACK
  3848. IconDlgProc(
  3849. HWND hwnd,
  3850. UINT msg,
  3851. WPARAM wParam,
  3852. LPARAM lParam
  3853. )
  3854. {
  3855. static HICON hIcon;
  3856. switch (msg)
  3857. {
  3858. case WM_INITDIALOG:
  3859. hIcon = (HICON) lParam;
  3860. break;
  3861. case WM_COMMAND:
  3862. switch (LOWORD(wParam))
  3863. {
  3864. case IDOK:
  3865. EndDialog (hwnd, 0);
  3866. break;
  3867. }
  3868. break;
  3869. case WM_PAINT:
  3870. {
  3871. PAINTSTRUCT ps;
  3872. BeginPaint (hwnd, &ps);
  3873. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  3874. #ifdef WIN32
  3875. MoveToEx (ps.hdc, 6, 6, (LPPOINT) NULL);
  3876. #else
  3877. MoveTo (ps.hdc, 6, 6);
  3878. #endif
  3879. LineTo (ps.hdc, 42, 6);
  3880. LineTo (ps.hdc, 42, 42);
  3881. LineTo (ps.hdc, 6, 42);
  3882. LineTo (ps.hdc, 6, 6);
  3883. DrawIcon (ps.hdc, 8, 8, hIcon);
  3884. EndPaint (hwnd, &ps);
  3885. break;
  3886. }
  3887. }
  3888. return 0;
  3889. }
  3890. INT_PTR
  3891. CALLBACK
  3892. UserButtonsDlgProc(
  3893. HWND hwnd,
  3894. UINT msg,
  3895. WPARAM wParam,
  3896. LPARAM lParam
  3897. )
  3898. {
  3899. static int iButtonIndex;
  3900. switch (msg)
  3901. {
  3902. case WM_INITDIALOG:
  3903. {
  3904. int i;
  3905. char buf[32];
  3906. if (lParam)
  3907. {
  3908. //
  3909. // The dlg was invoked because someone pressed a user button
  3910. // that was uninitialized, so only allow chgs on this button
  3911. //
  3912. iButtonIndex = *((int *) lParam);
  3913. _itoa (iButtonIndex + 1, buf, 10);
  3914. SendDlgItemMessage(
  3915. hwnd,
  3916. IDC_LIST1,
  3917. LB_INSERTSTRING,
  3918. (WPARAM) -1,
  3919. (LPARAM) buf
  3920. );
  3921. }
  3922. else
  3923. {
  3924. //
  3925. // The dlg was invoked because the user chose a menuitem,
  3926. // so allow chgs on all buttons
  3927. //
  3928. iButtonIndex = MAX_USER_BUTTONS;
  3929. for (i = 1; i <= MAX_USER_BUTTONS; i++)
  3930. {
  3931. _itoa (i, buf, 10);
  3932. SendDlgItemMessage(
  3933. hwnd,
  3934. IDC_LIST1,
  3935. LB_INSERTSTRING,
  3936. (WPARAM) -1,
  3937. (LPARAM) buf
  3938. );
  3939. }
  3940. }
  3941. SendDlgItemMessage(
  3942. hwnd,
  3943. IDC_LIST1,
  3944. LB_SETCURSEL,
  3945. (WPARAM) 0,
  3946. 0
  3947. );
  3948. for (i = 0; aFuncNames[i]; i++)
  3949. {
  3950. SendDlgItemMessage(
  3951. hwnd,
  3952. IDC_LIST2,
  3953. LB_INSERTSTRING,
  3954. (WPARAM) -1,
  3955. (LPARAM) aFuncNames[i]
  3956. );
  3957. }
  3958. SendDlgItemMessage(
  3959. hwnd,
  3960. IDC_LIST2,
  3961. LB_INSERTSTRING,
  3962. (WPARAM) -1,
  3963. (LPARAM) "<none>"
  3964. );
  3965. if (!lParam)
  3966. {
  3967. #ifdef WIN32
  3968. wParam = (WPARAM) MAKELONG (0, LBN_SELCHANGE);
  3969. #else
  3970. lParam = (LPARAM) MAKELONG (0, LBN_SELCHANGE);
  3971. #endif
  3972. goto IDC_LIST1_selchange;
  3973. }
  3974. break;
  3975. }
  3976. case WM_COMMAND:
  3977. switch (LOWORD(wParam))
  3978. {
  3979. case IDOK:
  3980. {
  3981. LRESULT lFuncSel;
  3982. lFuncSel = SendDlgItemMessage(hwnd, IDC_LIST2, LB_GETCURSEL, 0, 0);
  3983. if (lFuncSel == LB_ERR)
  3984. {
  3985. MessageBox (hwnd, "Select a function", "", MB_OK);
  3986. break;
  3987. }
  3988. if (iButtonIndex == MAX_USER_BUTTONS)
  3989. {
  3990. iButtonIndex = (int) SendDlgItemMessage(
  3991. hwnd,
  3992. IDC_LIST1,
  3993. LB_GETCURSEL,
  3994. 0,
  3995. 0
  3996. );
  3997. }
  3998. aUserButtonFuncs[iButtonIndex] = (DWORD) lFuncSel;
  3999. if (lFuncSel == MiscBegin)
  4000. {
  4001. //
  4002. // User selected "<none>" option so nullify string
  4003. //
  4004. aUserButtonsText[iButtonIndex][0] = 0;
  4005. }
  4006. else
  4007. {
  4008. GetDlgItemText(
  4009. hwnd,
  4010. IDC_EDIT1,
  4011. (LPSTR) &aUserButtonsText[iButtonIndex],
  4012. MAX_USER_BUTTON_TEXT_SIZE - 1
  4013. );
  4014. aUserButtonsText[iButtonIndex][MAX_USER_BUTTON_TEXT_SIZE - 1] =
  4015. 0;
  4016. }
  4017. SetDlgItemText(
  4018. ghwndMain,
  4019. IDC_BUTTON13 + iButtonIndex,
  4020. (LPSTR) &aUserButtonsText[iButtonIndex]
  4021. );
  4022. // Fall thru to IDCANCEL code
  4023. }
  4024. case IDCANCEL:
  4025. EndDialog (hwnd, FALSE);
  4026. break;
  4027. case IDC_LIST1:
  4028. IDC_LIST1_selchange:
  4029. #ifdef WIN32
  4030. if (HIWORD(wParam) == LBN_SELCHANGE)
  4031. #else
  4032. if (HIWORD(lParam) == LBN_SELCHANGE)
  4033. #endif
  4034. {
  4035. LRESULT lButtonSel =
  4036. SendDlgItemMessage(hwnd, IDC_LIST1, LB_GETCURSEL, 0, 0);
  4037. SendDlgItemMessage(
  4038. hwnd,
  4039. IDC_LIST2,
  4040. LB_SETCURSEL,
  4041. (WPARAM) aUserButtonFuncs[lButtonSel],
  4042. 0
  4043. );
  4044. SetDlgItemText(
  4045. hwnd,
  4046. IDC_EDIT1,
  4047. aUserButtonsText[lButtonSel]
  4048. );
  4049. }
  4050. break;
  4051. } // switch
  4052. break;
  4053. #ifdef WIN32
  4054. case WM_CTLCOLORSTATIC:
  4055. SetBkColor ((HDC) wParam, RGB (192,192,192));
  4056. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  4057. #else
  4058. case WM_CTLCOLOR:
  4059. {
  4060. if (HIWORD(lParam) == CTLCOLOR_STATIC)
  4061. {
  4062. SetBkColor ((HDC) wParam, RGB (192,192,192));
  4063. return (INT_PTR) GetStockObject (LTGRAY_BRUSH);
  4064. }
  4065. break;
  4066. }
  4067. #endif
  4068. case WM_PAINT:
  4069. {
  4070. PAINTSTRUCT ps;
  4071. BeginPaint (hwnd, &ps);
  4072. FillRect (ps.hdc, &ps.rcPaint, GetStockObject (LTGRAY_BRUSH));
  4073. EndPaint (hwnd, &ps);
  4074. break;
  4075. }
  4076. } // switch
  4077. return 0;
  4078. }