home *** CD-ROM | disk | FTP | other *** search
/ Microsoft Programmer's Library 1.3 / Microsoft-Programers-Library-v1.3.iso / books / o2sc.db < prev    next >
Encoding:
Text File  |  1991-03-01  |  3.5 MB  |  90,571 lines

Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
  1. %@1@%%@AH@%OS/2 v1.2 Sample Code%@EH@%%@AE@%
  2. %@NL@%
  3. %@NL@%
  4. %@2@%%@AH@%ACCEL.C%@AE@%%@EH@%%@NL@%
  5. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\ACCEL\ACCEL.C%@AE@%%@NL@%
  6. %@NL@%
  7. %@AB@%/*%@NL@%
  8. %@AB@% *  ACCEL.C -- Sample demonstrating calls included with INCL_WINACCELERATORS%@NL@%
  9. %@AB@% *%@NL@%
  10. %@AB@% *  Overview:%@NL@%
  11. %@AB@% *        Accelerators are used to reduce the number of keystrokes needed to%@NL@%
  12. %@AB@% *  execute a command (hence "accelerating" a user's processing time)%@NL@%
  13. %@AB@% *%@NL@%
  14. %@AB@% *  Strategy:%@NL@%
  15. %@AB@% *        This application allows the user to experiment with various settings,%@NL@%
  16. %@AB@% *  by popping up a dialog box in which the user can specify an accelerator.%@NL@%
  17. %@AB@% *  One possible modification to this program is to have the user hit the%@NL@%
  18. %@AB@% *  desired key sequence, and to use KbdCharIn() to figure out what the key%@NL@%
  19. %@AB@% *  sequence is, and then set the accelerator.  Another is to implement the%@NL@%
  20. %@AB@% *  "Delete" operation, by perhaps listing the accelerators in a list box.%@NL@%
  21. %@AB@% *  This wasn't done primarily because that would require reorganization%@NL@%
  22. %@AB@% *  (compression) of the accelerator table:  it could not be easily done with%@NL@%
  23. %@AB@% *  a WinDeleteAccel call (because such a call does not exist).%@NL@%
  24. %@AB@% */%@AE@%%@NL@%
  25. %@AI@%#define %@AE@%INCL_WINACCELERATORS %@NL@%
  26. %@AI@%#define %@AE@%       INCL_WINBUTTONS                        // Needed for checkboxes in dialogs %@NL@%
  27. %@AI@%#define %@AE@%       INCL_WINDIALOGS %@NL@%
  28. %@AI@%#define %@AE@%       INCL_WINMESSAGEMGR %@NL@%
  29. %@AI@%#define %@AE@%       INCL_WINFRAMEMGR                // for SC_MINIMIZE constant %@NL@%
  30. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  31. %@AI@%#include %@AE@%<os2.h> %@NL@%
  32. %@NL@%
  33. %@AI@%#include %@AE@%<malloc.h>                        // Needed for dynamic memory allocation %@NL@%
  34. %@AI@%#include %@AE@%<stdio.h>                        // Needed for sscanf() call %@NL@%
  35. %@AI@%#include %@AE@%"accel.h"                        // Needed for resource IDs %@NL@%
  36. %@AB@%/*%@NL@%
  37. %@AB@% * Globals%@NL@%
  38. %@AB@% */%@AE@%%@NL@%
  39. char        ach[8];                         // Temporary:  used to store Key: field%@NL@%
  40. char        szAppName[]        = "ACCEL.EXE";%@NL@%
  41. char        szClassName[]        = "Accelerator";%@NL@%
  42. char        szMessage[]        = " - Accelerator Table Example";%@NL@%
  43. int        cbSize;                         // Size of Accel. Table in bytes%@NL@%
  44. int        iTemp;                                // Used to store Key: value, if number%@NL@%
  45. void        *pTemp;                         // Used so free() won't give warnings%@NL@%
  46. HAB        hab;%@NL@%
  47. HACCEL        haccSystem;                        // Handle to system accelerator table%@NL@%
  48. HACCEL        haccTable;                        // Handle to app-local acceltable%@NL@%
  49. HMQ     hmqAccel;%@NL@%
  50. HWND        hwndAccel;                        // Client window%@NL@%
  51. HWND        hwndAccelFrame;                 // Frame window%@NL@%
  52. PACCELTABLE        pacctTable;                // Points to table with ACCEL entries%@NL@%
  53. %@AB@%/*%@NL@%
  54. %@AB@%    Macros%@NL@%
  55. %@AB@%*/%@AE@%%@NL@%
  56. %@AI@%#define %@AE@%Message(s) WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, s, \ %@NL@%
  57.                         szAppName, 0, MB_OK | MB_ICONEXCLAMATION)%@NL@%
  58. %@AI@%#define %@AE@%       Check(b)   WinSendDlgItemMsg(hwndDlg, b, \ %@NL@%
  59.                         BM_SETCHECK, MPFROMSHORT(1), 0L)%@NL@%
  60. %@AI@%#define %@AE@%Checked(b) WinSendDlgItemMsg(hwndDlg, b, BM_QUERYCHECK, 0L, 0L) %@NL@%
  61. %@AB@%/*%@NL@%
  62. %@AB@%    Internals%@NL@%
  63. %@AB@%*/%@AE@%%@NL@%
  64. BOOL InitializeAccelTable(void);%@NL@%
  65. %@AB@%/*%@NL@%
  66. %@AB@% * Main routine...initializes window and message queue%@NL@%
  67. %@AB@% */%@AE@%%@NL@%
  68. void cdecl main(void) {%@NL@%
  69.     QMSG qmsg;%@NL@%
  70.     ULONG ctldata;%@NL@%
  71. %@NL@%
  72.     %@AB@%/* Initialize a PM application */%@AE@%%@NL@%
  73.     hab = WinInitialize(0);%@NL@%
  74.     hmqAccel = WinCreateMsgQueue(hab, 0);%@NL@%
  75. %@NL@%
  76.     %@AB@%/* Register the main window's class */%@AE@%%@NL@%
  77.     if (!WinRegisterClass(hab, szClassName, AccelWndProc, CS_SIZEREDRAW, 0))%@NL@%
  78.         return;%@NL@%
  79.     %@AB@%/*%@NL@%
  80. %@AB@%        Create the window%@NL@%
  81. %@AB@%        We create it without an accelerator table, but we'll load one later%@NL@%
  82. %@AB@%    */%@AE@%%@NL@%
  83.     ctldata = FCF_STANDARD & ~FCF_ACCELTABLE;%@NL@%
  84.     hwndAccelFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &ctldata,%@NL@%
  85.         szClassName, szMessage, WS_VISIBLE, (HMODULE) NULL, IDR_ACCEL, &hwndAccel);%@NL@%
  86.     WinShowWindow(hwndAccelFrame, TRUE);%@NL@%
  87.     %@AB@%/*%@NL@%
  88. %@AB@%        Load the accelerator tables%@NL@%
  89. %@AB@%    */%@AE@%%@NL@%
  90.     if (!InitializeAccelTable()) {%@NL@%
  91.         Message("Accelerator table not initialized!");%@NL@%
  92.         return;%@NL@%
  93.     }%@NL@%
  94. %@NL@%
  95.     %@AB@%/* Poll messages from event queue */%@AE@%%@NL@%
  96.     while(WinGetMsg(hab, (PQMSG)&qmsg, (HWND)NULL, 0, 0))%@NL@%
  97.         WinDispatchMsg(hab, (PQMSG)&qmsg);%@NL@%
  98. %@NL@%
  99.     %@AB@%/* Clean up */%@AE@%%@NL@%
  100.     if (!WinDestroyAccelTable(haccTable))%@NL@%
  101.         Message("Could not destroy ACCELTABLE");%@NL@%
  102.     WinDestroyWindow(hwndAccelFrame);%@NL@%
  103.     WinDestroyMsgQueue(hmqAccel);%@NL@%
  104.     WinTerminate(hab);%@NL@%
  105. }%@NL@%
  106. %@NL@%
  107. MRESULT CALLBACK AccelWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  108. %@AB@%/*%@NL@%
  109. %@AB@% * This routine processes WM_PAINT.  It passes%@NL@%
  110. %@AB@% * everything else to the Default Window Procedure.%@NL@%
  111. %@AB@% */%@AE@%%@NL@%
  112.     HPS                hPS;%@NL@%
  113.     RECTL        rcl;%@NL@%
  114. %@NL@%
  115.     switch (msg) {%@NL@%
  116. %@NL@%
  117.         case WM_HELP:%@NL@%
  118.             %@AB@%/* If WM_HELP, pop up Help dialog box */%@AE@%%@NL@%
  119.             WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, (HMODULE) NULL, IDD_HELP, NULL);%@NL@%
  120.             break;%@NL@%
  121. %@NL@%
  122.         case WM_COMMAND:%@NL@%
  123.             switch (COMMANDMSG(&msg)->cmd) {%@NL@%
  124. %@NL@%
  125.                 %@AB@%/* On most WM_COMMAND messages, give the About... box */%@AE@%%@NL@%
  126.                 case IDM_ABOUT:%@NL@%
  127.                     WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc,%@NL@%
  128.                               (HMODULE) NULL, IDD_ABOUT, NULL);%@NL@%
  129.                     break;%@NL@%
  130. %@NL@%
  131.                 %@AB@%/* Create your own accelerator dialog */%@AE@%%@NL@%
  132.                 case IDM_CREATE:%@NL@%
  133.                     WinDlgBox(HWND_DESKTOP, hwnd, CreateDlgProc,%@NL@%
  134.                               (HMODULE) NULL, IDD_CREATE, NULL);%@NL@%
  135. %@NL@%
  136.                 default: break;%@NL@%
  137.             }%@NL@%
  138.             break;%@NL@%
  139. %@NL@%
  140.         case WM_PAINT:%@NL@%
  141.             %@AB@%/* Open the presentation space */%@AE@%%@NL@%
  142.             hPS = WinBeginPaint(hwnd, NULL, &rcl);%@NL@%
  143. %@NL@%
  144.             %@AB@%/* Fill the background with Dark Blue */%@AE@%%@NL@%
  145.             WinFillRect(hPS, &rcl, CLR_DARKBLUE);%@NL@%
  146. %@NL@%
  147.             %@AB@%/* Finish painting */%@AE@%%@NL@%
  148.             WinEndPaint(hPS);%@NL@%
  149.             break;%@NL@%
  150. %@NL@%
  151.         default: return WinDefWindowProc(hwnd, msg, mp1, mp2); break;%@NL@%
  152.     }%@NL@%
  153.     return 0L;%@NL@%
  154. }%@NL@%
  155. %@NL@%
  156. MRESULT CALLBACK AboutDlgProc(hwndDlg, msg, mp1, mp2)%@NL@%
  157. %@AB@%/*%@NL@%
  158. %@AB@%    About... dialog procedure%@NL@%
  159. %@AB@%*/%@AE@%%@NL@%
  160. HWND hwndDlg;%@NL@%
  161. USHORT msg;%@NL@%
  162. MPARAM mp1;%@NL@%
  163. MPARAM mp2;%@NL@%
  164. {%@NL@%
  165.     switch(msg) {%@NL@%
  166.         case WM_COMMAND:%@NL@%
  167.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  168.                 case DID_OK: WinDismissDlg(hwndDlg, TRUE);%@NL@%
  169.                 default: break;%@NL@%
  170.             }%@NL@%
  171.         default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);%@NL@%
  172.     }%@NL@%
  173.     return FALSE;%@NL@%
  174. }%@NL@%
  175. %@NL@%
  176. MRESULT CALLBACK CreateDlgProc(hwndDlg, msg, mp1, mp2)%@NL@%
  177. %@AB@%/*%@NL@%
  178. %@AB@%    Create Accelerator dialog procedure%@NL@%
  179. %@AB@%*/%@AE@%%@NL@%
  180. HWND hwndDlg;%@NL@%
  181. USHORT msg;%@NL@%
  182. MPARAM mp1;%@NL@%
  183. MPARAM mp2;%@NL@%
  184. {%@NL@%
  185.     switch(msg) {%@NL@%
  186.         case WM_INITDLG:%@NL@%
  187.             %@AB@%/* Set the defaults */%@AE@%%@NL@%
  188.             Check(IDD_CHAR); Check(IDD_CMD);%@NL@%
  189.             break;%@NL@%
  190. %@NL@%
  191.         case WM_COMMAND:%@NL@%
  192.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  193.                 case DID_OK:%@NL@%
  194.                     %@AB@%/* Get the accelerator table (allocate an extra space) */%@AE@%%@NL@%
  195.                     cbSize = WinCopyAccelTable(haccTable, NULL, 0);%@NL@%
  196.                     pTemp = (void *) malloc(cbSize + sizeof(ACCEL));%@NL@%
  197.                     pacctTable = (PACCELTABLE) pTemp;%@NL@%
  198.                     cbSize = WinCopyAccelTable(haccTable, pacctTable, cbSize);%@NL@%
  199.                     %@NL@%
  200. %@AI@%#define %@AE@%accNew        pacctTable->aaccel[pacctTable->cAccel] %@NL@%
  201. %@NL@%
  202.                     %@AB@%/*%@NL@%
  203. %@AB@%                        Command:%@NL@%
  204. %@AB@%                            if SYSCOMMAND, make the window minimize.%@NL@%
  205. %@AB@%                            if HELP, we'll pop up a dialog box.%@NL@%
  206. %@AB@%                            otherwise, pop up the About... dialog box.%@NL@%
  207. %@AB@%                    */%@AE@%%@NL@%
  208.                     if (Checked(IDD_SYSCMD)) accNew.cmd = SC_MINIMIZE;%@NL@%
  209.                     else accNew.cmd = IDM_ABOUT;%@NL@%
  210. %@NL@%
  211.                     %@AB@%/* Get the states from the dialog box */%@AE@%%@NL@%
  212.                     accNew.fs = 0;%@NL@%
  213.                     if (Checked(IDD_ALT))        accNew.fs |= AF_ALT;%@NL@%
  214.                     if (Checked(IDD_CHAR))        accNew.fs |= AF_CHAR;%@NL@%
  215.                     if (Checked(IDD_CONTROL))        accNew.fs |= AF_CONTROL;%@NL@%
  216.                     if (Checked(IDD_FHELP))        accNew.fs |= AF_HELP;%@NL@%
  217.                     if (Checked(IDD_LONEKEY))        accNew.fs |= AF_LONEKEY;%@NL@%
  218.                     if (Checked(IDD_SCANCODE))        accNew.fs |= AF_SCANCODE;%@NL@%
  219.                     if (Checked(IDD_SHIFT))        accNew.fs |= AF_SHIFT;%@NL@%
  220.                     if (Checked(IDD_SYSCMD))        accNew.fs |= AF_SYSCOMMAND;%@NL@%
  221.                     if (Checked(IDD_VKEY))        accNew.fs |= AF_VIRTUALKEY;%@NL@%
  222. %@NL@%
  223.                     %@AB@%/* Get the key to be defined */%@AE@%%@NL@%
  224.                     WinQueryDlgItemText(hwndDlg, IDD_ENTRY, 8, ach);%@NL@%
  225.                     if (('0' <= ach[0]) && (ach[0] <= '9')) {%@NL@%
  226.                         sscanf(ach, "%i", &iTemp);%@NL@%
  227.                         accNew.key = (USHORT) iTemp;%@NL@%
  228.                     }%@NL@%
  229.                     else accNew.key = (USHORT) ach[0];%@NL@%
  230. %@NL@%
  231.                     %@AB@%/* Increment the count of accelerator records */%@AE@%%@NL@%
  232.                     pacctTable->cAccel++;%@NL@%
  233. %@NL@%
  234.                     %@AB@%/* Cleanup, then create a new accelerator table */%@AE@%%@NL@%
  235.                     WinDestroyAccelTable(haccTable);%@NL@%
  236.                     haccTable = WinCreateAccelTable(hab, pacctTable);%@NL@%
  237. %@NL@%
  238.                     %@AB@%/* Set the new accelerator table, and clean up */%@AE@%%@NL@%
  239.                     WinSetAccelTable(hab, haccTable, hwndAccelFrame);%@NL@%
  240.                     free(pTemp);%@NL@%
  241. %@NL@%
  242.                 case DID_CANCEL:%@NL@%
  243.                     WinDismissDlg(hwndDlg, TRUE);%@NL@%
  244. %@NL@%
  245.                 default: break;%@NL@%
  246.             }%@NL@%
  247.         default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);%@NL@%
  248.     }%@NL@%
  249.     return FALSE;%@NL@%
  250. }%@NL@%
  251. %@NL@%
  252. BOOL InitializeAccelTable(void) {%@NL@%
  253.     %@AB@%/*%@NL@%
  254. %@AB@%        Initialize the accelerator table by loading it from the%@NL@%
  255. %@AB@%        resource file.        Note that you can load an accelerator%@NL@%
  256. %@AB@%        table from a DLL, if you change the NULL parameter.%@NL@%
  257. %@AB@%        The system accelerator table is accessible after this%@NL@%
  258. %@AB@%        call:  one possible use for this would be a List...%@NL@%
  259. %@AB@%        dialog box, which would list all system & app. accelerators.%@NL@%
  260. %@AB@%    */%@AE@%%@NL@%
  261.     haccSystem = WinQueryAccelTable(hab, NULL);%@NL@%
  262.     haccTable = WinLoadAccelTable(hab, 0, IDR_ACCEL);%@NL@%
  263.     return WinSetAccelTable(hab, haccTable, hwndAccelFrame);%@NL@%
  264. }%@NL@%
  265. %@NL@%
  266. %@NL@%
  267. %@2@%%@AH@%APP.C%@AE@%%@EH@%%@NL@%
  268. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\MDI\APP.C%@AE@%%@NL@%
  269. %@NL@%
  270. %@AB@%/***************************************************************************\%@NL@%
  271. %@AB@%* app.c - MDI Sample application%@NL@%
  272. %@AB@%*%@NL@%
  273. %@AB@%* Created by Microsoft Corporation, 1989%@NL@%
  274. %@AB@%*%@NL@%
  275. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  276. %@NL@%
  277. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  278. %@AI@%#define %@AE@%INCL_WINCOMMON %@NL@%
  279. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  280. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  281. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  282. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  283. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  284. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  285. %@AI@%#define %@AE@%INCL_WINRECTANGLES %@NL@%
  286. %@AI@%#define %@AE@%INCL_WINHEAP %@NL@%
  287. %@AI@%#define %@AE@%INCL_WINSCROLLBARS %@NL@%
  288. %@AI@%#define %@AE@%INCL_GPIPRIMITIVES %@NL@%
  289. %@NL@%
  290. %@AI@%#include %@AE@%<os2.h> %@NL@%
  291. %@AI@%#include %@AE@%"app.h" %@NL@%
  292. %@AI@%#include %@AE@%"appdata.h" %@NL@%
  293. %@AI@%#include %@AE@%"mdi.h" %@NL@%
  294. %@AI@%#include %@AE@%"mdidata.h" %@NL@%
  295. %@NL@%
  296. %@NL@%
  297. %@AB@%/*%@NL@%
  298. %@AB@%    Function prototypes%@NL@%
  299. %@AB@%*/%@AE@%%@NL@%
  300. BOOL AppInit(VOID);%@NL@%
  301. BOOL MDIInit(VOID);%@NL@%
  302. VOID AppTerminate(VOID);%@NL@%
  303. VOID MDITerminate(VOID);%@NL@%
  304. BOOL AppNewDocument(USHORT, PSZ);%@NL@%
  305. VOID TrackSplitbars(HWND, USHORT, SHORT, SHORT);%@NL@%
  306. VOID MDIDesktopSize(HWND, MPARAM, MPARAM);%@NL@%
  307. VOID MDIDesktopSetFocus(HWND, MPARAM); %@NL@%
  308. VOID MDIDesktopActivateDoc(SHORT idMenuitem);%@NL@%
  309. BOOL AppNewDocument(USHORT, PSZ);%@NL@%
  310. NPDOC MDINewDocument(USHORT fsStyle, PSZ pszClassName);%@NL@%
  311. VOID MDISetInitialDocPos(HWND hwndNewFrame);%@NL@%
  312. %@NL@%
  313. VOID AddToWindowMenu(NPDOC);%@NL@%
  314. %@NL@%
  315. %@NL@%
  316. %@NL@%
  317. int cdecl main(void)%@NL@%
  318. {%@NL@%
  319.     QMSG qmsg;%@NL@%
  320.     %@AB@%/*%@NL@%
  321. %@AB@%     * Initialize the application globals%@NL@%
  322. %@AB@%     * and create the main window.%@NL@%
  323. %@AB@%     */%@AE@%%@NL@%
  324.     if (AppInit() == FALSE) {%@NL@%
  325.         WinAlarm(HWND_DESKTOP, WA_ERROR);%@NL@%
  326.         return(0);%@NL@%
  327.     }%@NL@%
  328. %@NL@%
  329.     %@AB@%/*%@NL@%
  330. %@AB@%     * Initialize the MDI globals etc..%@NL@%
  331. %@AB@%     */%@AE@%%@NL@%
  332.     if (MDIInit() == FALSE) {%@NL@%
  333.         WinAlarm(HWND_DESKTOP, WA_ERROR);%@NL@%
  334.         WinAlarm(HWND_DESKTOP, WA_ERROR);%@NL@%
  335.         return(0);%@NL@%
  336.     }%@NL@%
  337. %@NL@%
  338.     %@AB@%/*%@NL@%
  339. %@AB@%     * Create an initial, untitled document.%@NL@%
  340. %@AB@%     */%@AE@%%@NL@%
  341.     AppNewDocument(DS_HORZSPLITBAR | DS_VERTSPLITBAR, szDocClass);%@NL@%
  342. %@NL@%
  343.     while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) {%@NL@%
  344.         WinDispatchMsg(NULL, (PQMSG)&qmsg);%@NL@%
  345.     }%@NL@%
  346. %@NL@%
  347.     %@AB@%/*%@NL@%
  348. %@AB@%     * Do the clean-up of the MDI code.%@NL@%
  349. %@AB@%     */%@AE@%%@NL@%
  350.     MDITerminate();%@NL@%
  351. %@NL@%
  352.     %@AB@%/*%@NL@%
  353. %@AB@%     * Do the clean-up of the Application.%@NL@%
  354. %@AB@%     */%@AE@%%@NL@%
  355.     AppTerminate();%@NL@%
  356. %@NL@%
  357.     DosExit(EXIT_PROCESS, 0);%@NL@%
  358. }%@NL@%
  359. %@NL@%
  360. %@NL@%
  361. MRESULT EXPENTRY MDIWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  362. {%@NL@%
  363.     HPS hps;%@NL@%
  364.     RECTL rclPaint, rclWindow;%@NL@%
  365.     POINTL ptlPatternRef;%@NL@%
  366. %@NL@%
  367.     switch (msg) {%@NL@%
  368. %@NL@%
  369.     case WM_PAINT:%@NL@%
  370.         hps = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);%@NL@%
  371. %@NL@%
  372.         %@AB@%/*%@NL@%
  373. %@AB@%         * Set the pattern to be at the top-left%@NL@%
  374. %@AB@%         * since we're top-left aligning the bits.%@NL@%
  375. %@AB@%         */%@AE@%%@NL@%
  376.         WinQueryWindowRect(hwnd, (PRECTL)&rclWindow);%@NL@%
  377.         ptlPatternRef.x = rclWindow.xLeft;%@NL@%
  378.         ptlPatternRef.y = rclWindow.yTop;%@NL@%
  379.         GpiSetPatternRefPoint(hps, &ptlPatternRef);%@NL@%
  380. %@NL@%
  381.         WinFillRect(hps, &rclPaint, SYSCLR_APPWORKSPACE);%@NL@%
  382. %@NL@%
  383.         WinEndPaint(hps);%@NL@%
  384.         break;%@NL@%
  385. %@NL@%
  386. %@AI@%#if %@AE@%0 %@NL@%
  387.     case WM_SIZE:%@NL@%
  388. %@NL@%
  389.         %@AB@%/* HACK -- only reposition the windows if it is not going to or coming%@NL@%
  390. %@AB@%        from a minimized position, it would be better to what%@NL@%
  391. %@AB@%        WM_WINDOWPOSCHANGED and pay attention to the fs fields of the SWP%@NL@%
  392. %@AB@%        structure */%@AE@%%@NL@%
  393. %@NL@%
  394.         if ( SHORT1FROMMP(mp1) && SHORT2FROMMP(mp1) &&%@NL@%
  395.              SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2) ) {%@NL@%
  396.             MDIDesktopSize ( hwnd, mp1, mp2 );%@NL@%
  397.         }%@NL@%
  398.     break;%@NL@%
  399. %@NL@%
  400. %@AI@%#else %@AE@%%@NL@%
  401.     case WM_SIZE:%@NL@%
  402.         MDIDesktopSize ( hwnd, mp1, mp2 );%@NL@%
  403.         break;%@NL@%
  404. %@AI@%#endif %@AE@%%@NL@%
  405. %@NL@%
  406.     case WM_SETFOCUS:%@NL@%
  407.         MDIDesktopSetFocus(hwnd, mp2);%@NL@%
  408.         break;%@NL@%
  409. %@NL@%
  410.     case WM_COMMAND:%@NL@%
  411.         switch (SHORT1FROMMP(mp1)) {%@NL@%
  412. %@NL@%
  413.         %@AB@%/*%@NL@%
  414. %@AB@%         * Pass these accelerators onto the active document's%@NL@%
  415. %@AB@%         * frame so it can process it.%@NL@%
  416. %@AB@%         *%@NL@%
  417. %@AB@%         * These are the CMD_ values from the document system%@NL@%
  418. %@AB@%         * menu.%@NL@%
  419. %@AB@%         */%@AE@%%@NL@%
  420.         case CMD_DOCRESTORE:%@NL@%
  421.             WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_RESTORE, mp2);%@NL@%
  422.             break;%@NL@%
  423. %@NL@%
  424.         case CMD_DOCNEXT:%@NL@%
  425.             WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_NEXT, mp2);%@NL@%
  426.             break;%@NL@%
  427. %@NL@%
  428.         case CMD_DOCMINIMIZE:%@NL@%
  429.             WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_MINIMIZE, mp2);%@NL@%
  430.             break;%@NL@%
  431. %@NL@%
  432.         case CMD_DOCCLOSE:%@NL@%
  433.             WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_CLOSE, mp2);%@NL@%
  434.             break;%@NL@%
  435. %@NL@%
  436.         case CMD_DOCSPLIT:%@NL@%
  437.             %@AB@%/*%@NL@%
  438. %@AB@%             * Call TrackSplitbars() with -1 for xMouse to tell%@NL@%
  439. %@AB@%             * it to reposition the pointer to where the%@NL@%
  440. %@AB@%             * splitbars currently are.%@NL@%
  441. %@AB@%             */%@AE@%%@NL@%
  442.             WinSetPointer(HWND_DESKTOP, hptrHVSplit);%@NL@%
  443.             TrackSplitbars(WinWindowFromID(hwndActiveDoc, FID_CLIENT),%@NL@%
  444.                     SPS_VERT | SPS_HORZ, -1, -1);%@NL@%
  445.             WinSetPointer(HWND_DESKTOP, hptrArrow);%@NL@%
  446.             break;%@NL@%
  447. %@NL@%
  448.         case CMD_NEW:%@NL@%
  449.             if (AppNewDocument(DS_HORZSPLITBAR | DS_VERTSPLITBAR, szDocClass) == FALSE)%@NL@%
  450.                 WinAlarm(HWND_DESKTOP, WA_ERROR);%@NL@%
  451.             break;%@NL@%
  452. %@NL@%
  453.         case CMD_CLOSE:%@NL@%
  454.             %@AB@%/*%@NL@%
  455. %@AB@%             * Close the active document.%@NL@%
  456. %@AB@%             */%@AE@%%@NL@%
  457.             if (hwndActiveDoc)%@NL@%
  458.                 WinSendMsg(hwndActiveDoc, WM_CLOSE, 0L, 0L);%@NL@%
  459.             break;%@NL@%
  460. %@NL@%
  461.         case CMD_ABOUT:%@NL@%
  462.             %@AB@%/*%@NL@%
  463. %@AB@%             * Put up the About... dialog box%@NL@%
  464. %@AB@%             */%@AE@%%@NL@%
  465.             WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, NULL, IDD_ABOUT, NULL);%@NL@%
  466.             break;%@NL@%
  467.         %@NL@%
  468.         case CMD_EXIT:%@NL@%
  469.             WinPostMsg(hwnd, WM_QUIT, 0L, 0L);%@NL@%
  470.             break;%@NL@%
  471. %@NL@%
  472.         case CMD_ARRANGETILED:%@NL@%
  473.             ArrangeWindows(AWP_TILED);%@NL@%
  474.             break;%@NL@%
  475. %@NL@%
  476.         case CMD_ARRANGECASCADED:%@NL@%
  477.             ArrangeWindows(AWP_CASCADED);%@NL@%
  478.             break;%@NL@%
  479. %@NL@%
  480.         default:%@NL@%
  481.             %@AB@%/*%@NL@%
  482. %@AB@%             * The means a window title was selected from%@NL@%
  483. %@AB@%             * the window menu.  Have the MDI code activate%@NL@%
  484. %@AB@%             * the correct window based on the menuitem ID.%@NL@%
  485. %@AB@%             *%@NL@%
  486. %@AB@%             * WARNING: Be sure to keep you applications%@NL@%
  487. %@AB@%             * menuitem IDs < CMD_WINDOWITEMS.%@NL@%
  488. %@AB@%             */%@AE@%%@NL@%
  489. %@NL@%
  490.             %@AB@%/* MULTIPLEMENU */%@AE@%%@NL@%
  491.             %@AB@%/*  Also in here we need to pass document unique WM_COMMAND%@NL@%
  492. %@AB@%                messages on down to the document's client procs */%@AE@%%@NL@%
  493. %@NL@%
  494.             if (SHORT1FROMMP(mp1) >= CMD_WINDOWITEMS)%@NL@%
  495.                 MDIDesktopActivateDoc(SHORT1FROMMP(mp1));%@NL@%
  496.             break;%@NL@%
  497.         }%@NL@%
  498.         break;%@NL@%
  499. %@NL@%
  500.     default:%@NL@%
  501.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  502.         break;%@NL@%
  503.     }%@NL@%
  504. %@NL@%
  505.     return (0L);%@NL@%
  506. }%@NL@%
  507. %@NL@%
  508. %@NL@%
  509. BOOL AppNewDocument(USHORT fsStyle, PSZ pszClassName)%@NL@%
  510. {%@NL@%
  511.     register NPDOC npdocNew;%@NL@%
  512.     HWND hwndFrame, hwndClient;%@NL@%
  513.     HWND hwndHScroll, hwndVScroll;%@NL@%
  514. %@NL@%
  515.     npdocNew = MDINewDocument(fsStyle, pszClassName);%@NL@%
  516. %@NL@%
  517.     npdocNew->clrBackground = clrNext++;%@NL@%
  518.     if (clrNext > CLR_PALEGRAY)%@NL@%
  519.         clrNext = CLR_BACKGROUND;%@NL@%
  520. %@NL@%
  521.     hwndFrame = npdocNew->hwndFrame;%@NL@%
  522.     hwndClient = WinWindowFromID(hwndFrame, FID_CLIENT);%@NL@%
  523. %@NL@%
  524.     %@AB@%/*%@NL@%
  525. %@AB@%     * Setup the scrollbars.%@NL@%
  526. %@AB@%     */%@AE@%%@NL@%
  527.     hwndHScroll = WinWindowFromID(hwndFrame, FID_HORZSCROLL);%@NL@%
  528.     WinSendMsg(hwndHScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),%@NL@%
  529.             MPFROM2SHORT(0, 600));%@NL@%
  530.     hwndHScroll = WinWindowFromID(hwndFrame, ID_HORZSCROLL2);%@NL@%
  531.     WinSendMsg(hwndHScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),%@NL@%
  532.             MPFROM2SHORT(0, 600));%@NL@%
  533. %@NL@%
  534.     hwndVScroll = WinWindowFromID(hwndFrame, FID_VERTSCROLL);%@NL@%
  535.     WinSendMsg(hwndVScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),%@NL@%
  536.             MPFROM2SHORT(0, 600));%@NL@%
  537.     hwndVScroll = WinWindowFromID(hwndFrame, ID_VERTSCROLL2);%@NL@%
  538.     WinSendMsg(hwndVScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),%@NL@%
  539.             MPFROM2SHORT(0, 600));%@NL@%
  540. %@NL@%
  541.     %@AB@%/*%@NL@%
  542. %@AB@%     * Set the focus the client so the new window will be%@NL@%
  543. %@AB@%     * active when we show it.%@NL@%
  544. %@AB@%     */%@AE@%%@NL@%
  545.     WinSetFocus(HWND_DESKTOP, hwndClient);%@NL@%
  546. %@NL@%
  547.     AddToWindowMenu(npdocNew);    %@AB@%/* Moved here from end of%@NL@%
  548. %@AB@%                                  MdiNewDocument routine so that the doc has%@NL@%
  549. %@AB@%                                  been activated, and therefore the main%@NL@%
  550. %@AB@%                                  window has a menu before attempting to add%@NL@%
  551. %@AB@%                                  the doc to the main window's menu */%@AE@%%@NL@%
  552. %@NL@%
  553. %@NL@%
  554.     %@AB@%/*%@NL@%
  555. %@AB@%     * Set the initial position of the frame window and make it visible.%@NL@%
  556. %@AB@%     */%@AE@%%@NL@%
  557.     MDISetInitialDocPos(hwndFrame);%@NL@%
  558. %@NL@%
  559.     return (TRUE);%@NL@%
  560. }%@NL@%
  561. %@NL@%
  562. MRESULT EXPENTRY AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  563. %@AB@%/*%@NL@%
  564. %@AB@%    About... dialog procedure%@NL@%
  565. %@AB@%*/%@AE@%%@NL@%
  566. {%@NL@%
  567.     switch(msg) {%@NL@%
  568.         case WM_COMMAND:%@NL@%
  569.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  570.                 case DID_OK: WinDismissDlg(hDlg, TRUE); break;%@NL@%
  571.                 default: break;%@NL@%
  572.             }%@NL@%
  573.         default: return WinDefDlgProc(hDlg, msg, mp1, mp2);%@NL@%
  574.     }%@NL@%
  575.     return FALSE;%@NL@%
  576. }%@NL@%
  577. %@NL@%
  578. %@NL@%
  579. %@2@%%@AH@%APPDATA.C%@AE@%%@EH@%%@NL@%
  580. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\MDI\APPDATA.C%@AE@%%@NL@%
  581. %@NL@%
  582. %@NL@%
  583. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  584. %@AI@%#define %@AE@%INCL_WINCOMMON %@NL@%
  585. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  586. %@AI@%#define %@AE@%INCL_WINACCELERATORS %@NL@%
  587. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  588. %@AI@%#define %@AE@%INCL_WINHEAP %@NL@%
  589. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  590. %@NL@%
  591. %@AI@%#include %@AE@%<os2.h> %@NL@%
  592. %@AI@%#include %@AE@%"app.h" %@NL@%
  593. %@AI@%#include %@AE@%"mdi.h" %@NL@%
  594. %@NL@%
  595. char szMDIClass[] = "PM MDI Sample App";%@NL@%
  596. char szDocClass[] = "PM MDI Document";%@NL@%
  597. USHORT cxBorder, cyBorder, cyHScroll, cxVScroll, cyVScrollArrow;%@NL@%
  598. USHORT cxScreen, cyScreen, cyIcon, cxByteAlign, cyByteAlign;%@NL@%
  599. USHORT cxSizeBorder, cySizeBorder;%@NL@%
  600. ULONG clrNext = CLR_BACKGROUND;%@NL@%
  601. LONG rglDevCaps[(CAPS_VERTICAL_FONT_RES - CAPS_FAMILY)];%@NL@%
  602. %@NL@%
  603. %@AB@%/* Main globals */%@AE@%%@NL@%
  604. HAB  hab;%@NL@%
  605. HHEAP hHeap;%@NL@%
  606. HMQ  hmqMDI;%@NL@%
  607. HWND hwndMDI, hwndMDIFrame;%@NL@%
  608. HWND hwndActiveDoc;%@NL@%
  609. FONTMETRICS fmSystemFont;%@NL@%
  610. NPDOC npdocFirst = NULL;%@NL@%
  611. %@NL@%
  612. %@AB@%/* Menu globals */%@AE@%%@NL@%
  613. %@NL@%
  614. %@NL@%
  615. HWND hwndSysMenu;%@NL@%
  616. %@NL@%
  617. %@NL@%
  618. %@2@%%@AH@%APPDOC.C%@AE@%%@EH@%%@NL@%
  619. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\MDI\APPDOC.C%@AE@%%@NL@%
  620. %@NL@%
  621. %@AB@%/*%@NL@%
  622. %@AB@%    appdoc.c - MDI application%@NL@%
  623. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  624. %@AB@%*/%@AE@%%@NL@%
  625. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  626. %@AI@%#define %@AE@%INCL_WINCOMMON %@NL@%
  627. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  628. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  629. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  630. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  631. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  632. %@AI@%#define %@AE@%INCL_WINACCELERATORS %@NL@%
  633. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  634. %@AI@%#define %@AE@%INCL_WINHEAP %@NL@%
  635. %@AI@%#define %@AE@%INCL_WINSCROLLBARS %@NL@%
  636. %@AI@%#define %@AE@%INCL_WINRECTANGLES %@NL@%
  637. %@AI@%#define %@AE@%INCL_WINCOUNTRY %@NL@%
  638. %@AI@%#define %@AE@%INCL_GPIPRIMITIVES %@NL@%
  639. %@AI@%#define %@AE@%INCL_GPILOGCOLORTABLE %@NL@%
  640. %@NL@%
  641. %@AI@%#include %@AE@%<os2.h> %@NL@%
  642. %@AI@%#include %@AE@%<string.h> %@NL@%
  643. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  644. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  645. %@AI@%#include %@AE@%"app.h" %@NL@%
  646. %@AI@%#include %@AE@%"appdata.h" %@NL@%
  647. %@AI@%#include %@AE@%"mdi.h" %@NL@%
  648. %@AI@%#include %@AE@%"mdidata.h" %@NL@%
  649. %@NL@%
  650. %@AB@%/* Function prototypes */%@AE@%%@NL@%
  651. VOID AppHScroll(HWND hwnd, MPARAM mp1, MPARAM mp2);%@NL@%
  652. VOID AppVScroll(HWND hwnd, MPARAM mp1, MPARAM mp2);%@NL@%
  653. VOID AppEraseBackground(HWND hwnd, HPS hps);%@NL@%
  654. VOID AppPaint(HWND hwnd);%@NL@%
  655. VOID MDIClose(HWND hwndClient);%@NL@%
  656. BOOL MDICreate(HWND);%@NL@%
  657. BOOL MDIDestroy(HWND);%@NL@%
  658. BOOL MDIActivate(HWND, BOOL);%@NL@%
  659. %@NL@%
  660. %@AB@%/*%@NL@%
  661. %@AB@% * The array of RGB values for the rounded%@NL@%
  662. %@AB@% * rectangles.%@NL@%
  663. %@AB@% */%@AE@%%@NL@%
  664. LONG aclrRGB[16] = {%@NL@%
  665.     RGB_RED, RGB_WHITE, RGB_GREEN, RGB_BLACK,%@NL@%
  666.     RGB_BLUE, RGB_WHITE, RGB_YELLOW, RGB_BLACK,%@NL@%
  667.     RGB_CYAN, RGB_BLACK, RGB_PINK, RGB_BLACK,%@NL@%
  668.     RGB_WHITE, RGB_PINK, RGB_BLACK, RGB_RED%@NL@%
  669. };%@NL@%
  670. %@NL@%
  671. %@NL@%
  672. %@NL@%
  673. MRESULT EXPENTRY DocWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  674. {%@NL@%
  675. %@NL@%
  676.     switch (msg) {%@NL@%
  677. %@NL@%
  678.     case WM_COMMAND:%@NL@%
  679.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  680.         break;%@NL@%
  681. %@NL@%
  682.     case WM_CREATE:%@NL@%
  683.         if (MDICreate(hwnd) == FALSE)%@NL@%
  684.             return ( (MRESULT) TRUE);%@NL@%
  685.         break;%@NL@%
  686. %@NL@%
  687.     case WM_DESTROY:%@NL@%
  688.         MDIDestroy(hwnd);%@NL@%
  689.         break;%@NL@%
  690. %@NL@%
  691.     case WM_CLOSE:%@NL@%
  692.         MDIClose(hwnd);%@NL@%
  693.         break;%@NL@%
  694. %@NL@%
  695.     case WM_HSCROLL:%@NL@%
  696.         AppHScroll(hwnd, mp1, mp2);%@NL@%
  697.         break;%@NL@%
  698. %@NL@%
  699.     case WM_VSCROLL:%@NL@%
  700.         AppVScroll(hwnd, mp1, mp2);%@NL@%
  701.         break;%@NL@%
  702. %@NL@%
  703.     case WM_ERASEBACKGROUND:%@NL@%
  704.         AppEraseBackground(hwnd, (HPS)mp1);%@NL@%
  705.         break;%@NL@%
  706. %@NL@%
  707.     case WM_PAINT:%@NL@%
  708.         AppPaint(hwnd);%@NL@%
  709.         break;%@NL@%
  710. %@NL@%
  711.     case WM_ACTIVATE:%@NL@%
  712.         MDIActivate(hwnd, (BOOL)SHORT1FROMMP(mp1));%@NL@%
  713.         break;%@NL@%
  714. %@NL@%
  715.     default:%@NL@%
  716.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  717.         break;%@NL@%
  718.     }%@NL@%
  719. %@NL@%
  720.     return (0L);%@NL@%
  721. }%@NL@%
  722. %@NL@%
  723. %@NL@%
  724. VOID AppEraseBackground(HWND hwnd, HPS hps)%@NL@%
  725. {%@NL@%
  726.     RECTL rclPaint;%@NL@%
  727.     HWND hwndFrame, hwndClient;%@NL@%
  728.     register NPDOC npdoc;%@NL@%
  729. %@NL@%
  730.     npdoc = NPDOCFROMCLIENT(hwnd);%@NL@%
  731.     hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);%@NL@%
  732. %@NL@%
  733.     %@AB@%/*%@NL@%
  734. %@AB@%     * We know the main client is around so%@NL@%
  735. %@AB@%     * go ahead and erase it.%@NL@%
  736. %@AB@%     */%@AE@%%@NL@%
  737.     WinQueryWindowRect(hwnd, &rclPaint);%@NL@%
  738.     WinMapWindowPoints(hwnd, hwndFrame, (PPOINTL)&rclPaint, 2);%@NL@%
  739.     WinFillRect(hps, &rclPaint, npdoc->clrBackground);%@NL@%
  740. %@NL@%
  741.     %@AB@%/*%@NL@%
  742. %@AB@%     * Now check to see which of the other client windows%@NL@%
  743. %@AB@%     * are around and erase them.%@NL@%
  744. %@AB@%     *%@NL@%
  745. %@AB@%     * We do all this to avoid erasing the splitbars.%@NL@%
  746. %@AB@%     */%@AE@%%@NL@%
  747.     if (npdoc->fs & DF_SPLITVERT) {%@NL@%
  748. %@NL@%
  749.         hwndClient = WinWindowFromID(hwndFrame, ID_CLIENT2);%@NL@%
  750.         %@AB@%/*%@NL@%
  751. %@AB@%         * If it became invisible due to the frame%@NL@%
  752. %@AB@%         * window getting too small, then don't%@NL@%
  753. %@AB@%         * bother drawing.%@NL@%
  754. %@AB@%         */%@AE@%%@NL@%
  755.         if (WinIsWindowVisible(hwndClient) != FALSE) {%@NL@%
  756.             WinQueryWindowRect(hwndClient, &rclPaint);%@NL@%
  757.             WinMapWindowPoints(hwndClient, hwndFrame,%@NL@%
  758.                     (PPOINTL)&rclPaint, 2);%@NL@%
  759.             WinFillRect(hps, &rclPaint, npdoc->clrBackground);%@NL@%
  760.         }%@NL@%
  761.     }%@NL@%
  762. %@NL@%
  763.     if (npdoc->fs & DF_SPLITHORZ) {%@NL@%
  764. %@NL@%
  765.         hwndClient = WinWindowFromID(hwndFrame, ID_CLIENT3);%@NL@%
  766.         if (WinIsWindowVisible(hwndClient) != FALSE) {%@NL@%
  767.             WinQueryWindowRect(hwndClient, &rclPaint);%@NL@%
  768.             WinMapWindowPoints(hwndClient, hwndFrame,%@NL@%
  769.                     (PPOINTL)&rclPaint, 2);%@NL@%
  770.             WinFillRect(hps, &rclPaint, npdoc->clrBackground);%@NL@%
  771.         }%@NL@%
  772.     }%@NL@%
  773. %@NL@%
  774.     %@AB@%/*%@NL@%
  775. %@AB@%     * If we're split in both directions, then there's%@NL@%
  776. %@AB@%     * a ID_CLIENT4 window.%@NL@%
  777. %@AB@%     */%@AE@%%@NL@%
  778.     if ((npdoc->fs & (DF_SPLITHORZ | DF_SPLITVERT)) ==%@NL@%
  779.             (DF_SPLITHORZ | DF_SPLITVERT)) {%@NL@%
  780. %@NL@%
  781.         hwndClient = WinWindowFromID(hwndFrame, ID_CLIENT4);%@NL@%
  782.         if (WinIsWindowVisible(hwndClient) != FALSE) {%@NL@%
  783.             WinQueryWindowRect(hwndClient, &rclPaint);%@NL@%
  784.             WinMapWindowPoints(hwndClient, hwndFrame,%@NL@%
  785.                     (PPOINTL)&rclPaint, 2);%@NL@%
  786.             WinFillRect(hps, &rclPaint, npdoc->clrBackground);%@NL@%
  787.         }%@NL@%
  788.     }%@NL@%
  789. }%@NL@%
  790. %@NL@%
  791. %@NL@%
  792. VOID AppHScroll(HWND hwnd, MPARAM mp1, MPARAM mp2)%@NL@%
  793. {%@NL@%
  794.     HWND hwndFrame;%@NL@%
  795.     NPDOC npdoc;%@NL@%
  796.     RECTL rclPaintBottom, rclPaintTop;%@NL@%
  797.     RECTL rclWindowBottom, rclWindowTop;%@NL@%
  798.     HWND hwndClientBottom, hwndClientTop;%@NL@%
  799.     HWND hwndScrollbar;%@NL@%
  800.     register NPVIEW npviewBottom, npviewTop;%@NL@%
  801.     SHORT posSlider, xOriginOld;%@NL@%
  802.     USHORT cmd, idScrollbar;%@NL@%
  803. %@NL@%
  804.     hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);%@NL@%
  805.     npdoc = NPDOCFROMCLIENT(hwnd);%@NL@%
  806. %@NL@%
  807.     idScrollbar = SHORT1FROMMP(mp1);%@NL@%
  808. %@NL@%
  809.     switch (idScrollbar) {%@NL@%
  810. %@NL@%
  811.     case FID_HORZSCROLL:%@NL@%
  812.         hwndClientTop = hwnd;%@NL@%
  813.         if (npdoc->fs & DF_SPLITHORZ) {%@NL@%
  814.             hwndClientBottom = WinWindowFromID(hwndFrame, ID_CLIENT3);%@NL@%
  815.         } else {%@NL@%
  816.             hwndClientBottom = NULL;%@NL@%
  817.         }%@NL@%
  818.         break;%@NL@%
  819. %@NL@%
  820.     case ID_HORZSCROLL2:%@NL@%
  821.         hwndClientTop = WinWindowFromID(hwndFrame, ID_CLIENT2);%@NL@%
  822.         if (npdoc->fs & DF_SPLITHORZ) {%@NL@%
  823.             hwndClientBottom = WinWindowFromID(hwndFrame, ID_CLIENT4);%@NL@%
  824.         } else {%@NL@%
  825.             hwndClientBottom = NULL;%@NL@%
  826.         }%@NL@%
  827.         break;%@NL@%
  828.     }%@NL@%
  829. %@NL@%
  830.     hwndScrollbar = WinWindowFromID(hwndFrame, idScrollbar);%@NL@%
  831. %@NL@%
  832.     npviewTop = NPVIEWFROMCLIENT(hwndClientTop);%@NL@%
  833.     WinQueryWindowRect(hwndClientTop, &rclWindowTop);%@NL@%
  834. %@NL@%
  835.     if (hwndClientBottom != NULL) {%@NL@%
  836.         npviewBottom = NPVIEWFROMCLIENT(hwndClientBottom);%@NL@%
  837.         WinQueryWindowRect(hwndClientBottom, &rclWindowBottom);%@NL@%
  838.     }%@NL@%
  839. %@NL@%
  840.     posSlider = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERYPOS, NULL, NULL);%@NL@%
  841. %@NL@%
  842.     cmd = SHORT2FROMMP(mp2);%@NL@%
  843.     switch (cmd) {%@NL@%
  844. %@NL@%
  845.     case SB_LINELEFT:%@NL@%
  846.         posSlider -= 16;%@NL@%
  847.         break;%@NL@%
  848. %@NL@%
  849.     case SB_LINERIGHT:%@NL@%
  850.         posSlider += 16;%@NL@%
  851.         break;%@NL@%
  852. %@NL@%
  853.     case SB_PAGELEFT:%@NL@%
  854.         posSlider -= ((SHORT)rclWindowTop.xRight - 16);%@NL@%
  855.         break;%@NL@%
  856. %@NL@%
  857.     case SB_PAGERIGHT:%@NL@%
  858.         posSlider += ((SHORT)rclWindowTop.xRight - 16);%@NL@%
  859.         break;%@NL@%
  860. %@NL@%
  861.     case SB_SLIDERPOSITION:%@NL@%
  862.         posSlider = SHORT1FROMMP(mp2);%@NL@%
  863.         break;%@NL@%
  864.     }%@NL@%
  865. %@NL@%
  866.     WinSendMsg(hwndScrollbar, SBM_SETPOS, MPFROMSHORT(posSlider), NULL);%@NL@%
  867. %@NL@%
  868.     xOriginOld = npviewTop->xOrigin;%@NL@%
  869.     npviewTop->xOrigin = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERYPOS, NULL, NULL);%@NL@%
  870.     WinScrollWindow(hwndClientTop, xOriginOld - npviewTop->xOrigin, 0,%@NL@%
  871.             NULL, NULL, NULL, &rclPaintTop, NULL);%@NL@%
  872. %@NL@%
  873.     if (hwndClientBottom != NULL) {%@NL@%
  874.         xOriginOld = npviewBottom->xOrigin;%@NL@%
  875.         npviewBottom->xOrigin = npviewTop->xOrigin;%@NL@%
  876.         WinScrollWindow(hwndClientBottom, xOriginOld - npviewBottom->xOrigin,%@NL@%
  877.                 0, NULL, NULL, NULL, &rclPaintBottom, NULL);%@NL@%
  878.     }%@NL@%
  879. %@NL@%
  880.     WinMapWindowPoints(hwndClientTop, hwndFrame, (PPOINTL)&rclPaintTop, 2);%@NL@%
  881.     WinInvalidateRect(hwndFrame, &rclPaintTop, TRUE);%@NL@%
  882. %@NL@%
  883.     if (hwndClientBottom != NULL) {%@NL@%
  884.         WinMapWindowPoints(hwndClientBottom, hwndFrame, (PPOINTL)&rclPaintBottom, 2);%@NL@%
  885.         WinInvalidateRect(hwndFrame, &rclPaintBottom, TRUE);%@NL@%
  886.     }%@NL@%
  887. }%@NL@%
  888. %@NL@%
  889. %@NL@%
  890. VOID AppVScroll(HWND hwnd, MPARAM mp1, MPARAM mp2)%@NL@%
  891. {%@NL@%
  892.     HWND hwndFrame;%@NL@%
  893.     NPDOC npdoc;%@NL@%
  894.     RECTL rclPaintRight, rclPaintLeft;%@NL@%
  895.     RECTL rclWindowRight, rclWindowLeft;%@NL@%
  896.     HWND hwndClientRight, hwndClientLeft;%@NL@%
  897.     HWND hwndScrollbar;%@NL@%
  898.     register NPVIEW npviewRight, npviewLeft;%@NL@%
  899.     SHORT posSlider, yOriginOld;%@NL@%
  900.     USHORT cmd, idScrollbar;%@NL@%
  901. %@NL@%
  902.     hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);%@NL@%
  903.     npdoc = NPDOCFROMCLIENT(hwnd);%@NL@%
  904. %@NL@%
  905.     idScrollbar = SHORT1FROMMP(mp1);%@NL@%
  906. %@NL@%
  907.     switch (idScrollbar) {%@NL@%
  908. %@NL@%
  909.     case FID_VERTSCROLL:%@NL@%
  910.         hwndClientLeft = hwnd;%@NL@%
  911.         if (npdoc->fs & DF_SPLITVERT) {%@NL@%
  912.             hwndClientRight = WinWindowFromID(hwndFrame, ID_CLIENT2);%@NL@%
  913.         } else {%@NL@%
  914.             hwndClientRight = NULL;%@NL@%
  915.         }%@NL@%
  916.         break;%@NL@%
  917. %@NL@%
  918.     case ID_VERTSCROLL2:%@NL@%
  919.         hwndClientLeft = WinWindowFromID(hwndFrame, ID_CLIENT3);%@NL@%
  920.         if (npdoc->fs & DF_SPLITVERT) {%@NL@%
  921.             hwndClientRight = WinWindowFromID(hwndFrame, ID_CLIENT4);%@NL@%
  922.         } else {%@NL@%
  923.             hwndClientRight = NULL;%@NL@%
  924.         }%@NL@%
  925.         break;%@NL@%
  926.     }%@NL@%
  927. %@NL@%
  928.     hwndScrollbar = WinWindowFromID(hwndFrame, idScrollbar);%@NL@%
  929. %@NL@%
  930.     npviewLeft = NPVIEWFROMCLIENT(hwndClientLeft);%@NL@%
  931.     WinQueryWindowRect(hwndClientLeft, &rclWindowLeft);%@NL@%
  932. %@NL@%
  933.     if (hwndClientRight != NULL) {%@NL@%
  934.         npviewRight = NPVIEWFROMCLIENT(hwndClientRight);%@NL@%
  935.         WinQueryWindowRect(hwndClientRight, &rclWindowRight);%@NL@%
  936.     }%@NL@%
  937. %@NL@%
  938.     posSlider = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERYPOS, NULL, NULL);%@NL@%
  939. %@NL@%
  940.     cmd = SHORT2FROMMP(mp2);%@NL@%
  941.     switch (cmd) {%@NL@%
  942. %@NL@%
  943.     case SB_LINEUP:%@NL@%
  944.         posSlider -= 16;%@NL@%
  945.         break;%@NL@%
  946. %@NL@%
  947.     case SB_LINEDOWN:%@NL@%
  948.         posSlider += 16;%@NL@%
  949.         break;%@NL@%
  950. %@NL@%
  951.     case SB_PAGEUP:%@NL@%
  952.         posSlider -= ((SHORT)rclWindowLeft.yTop - 16);%@NL@%
  953.         break;%@NL@%
  954. %@NL@%
  955.     case SB_PAGEDOWN:%@NL@%
  956.         posSlider += ((SHORT)rclWindowLeft.yTop - 16);%@NL@%
  957.         break;%@NL@%
  958. %@NL@%
  959.     case SB_SLIDERPOSITION:%@NL@%
  960.         posSlider = SHORT1FROMMP(mp2);%@NL@%
  961.         break;%@NL@%
  962.     }%@NL@%
  963. %@NL@%
  964.     WinSendMsg(hwndScrollbar, SBM_SETPOS, MPFROMSHORT(posSlider), NULL);%@NL@%
  965. %@NL@%
  966.     yOriginOld = npviewLeft->yOrigin;%@NL@%
  967.     npviewLeft->yOrigin = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERYPOS, NULL, NULL);%@NL@%
  968.     WinScrollWindow(hwndClientLeft, 0,  npviewLeft->yOrigin - yOriginOld,%@NL@%
  969.             NULL, NULL, NULL, &rclPaintLeft, NULL);%@NL@%
  970. %@NL@%
  971.     if (hwndClientRight != NULL) {%@NL@%
  972.         yOriginOld = npviewRight->yOrigin;%@NL@%
  973.         npviewRight->yOrigin = npviewLeft->yOrigin;%@NL@%
  974.         WinScrollWindow(hwndClientRight, 0, npviewRight->yOrigin - yOriginOld,%@NL@%
  975.                 NULL, NULL, NULL, &rclPaintRight, NULL);%@NL@%
  976.     }%@NL@%
  977. %@NL@%
  978.     WinMapWindowPoints(hwndClientLeft, hwndFrame, (PPOINTL)&rclPaintLeft, 2);%@NL@%
  979.     WinInvalidateRect(hwndFrame, &rclPaintLeft, TRUE);%@NL@%
  980. %@NL@%
  981.     if (hwndClientRight != NULL) {%@NL@%
  982.         WinMapWindowPoints(hwndClientRight, hwndFrame, (PPOINTL)&rclPaintRight, 2);%@NL@%
  983.         WinInvalidateRect(hwndFrame, &rclPaintRight, TRUE);%@NL@%
  984.     }%@NL@%
  985. }%@NL@%
  986. %@NL@%
  987. %@NL@%
  988. VOID AppPaint(HWND hwnd)%@NL@%
  989. {%@NL@%
  990.     HPS hps;%@NL@%
  991.     RECTL rclPaint, rclWindow, rclTest, rclDst;%@NL@%
  992.     POINTL ptl, ptlPatternRef;%@NL@%
  993.     register NPVIEW npview;%@NL@%
  994.     AREABUNDLE abnd;%@NL@%
  995.     LONG clrStart, clrEnd, clrInc, clr;%@NL@%
  996.     SHORT i, j;%@NL@%
  997. %@NL@%
  998.     hps = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);%@NL@%
  999. %@NL@%
  1000.     %@AB@%/*%@NL@%
  1001. %@AB@%     * Go into RGB mode.%@NL@%
  1002. %@AB@%     */%@AE@%%@NL@%
  1003.     GpiCreateLogColorTable(hps, 0L, LCOLF_RGB, 0L, 0L, NULL);%@NL@%
  1004. %@NL@%
  1005.     %@AB@%/*%@NL@%
  1006. %@AB@%     * Make rclPaint an inclusive-inclusive rectangle%@NL@%
  1007. %@AB@%     * since that's how GpiBox() will be output.%@NL@%
  1008. %@AB@%     */%@AE@%%@NL@%
  1009.     rclPaint.xLeft--;%@NL@%
  1010.     rclPaint.yBottom--;%@NL@%
  1011. %@NL@%
  1012.     npview = NPVIEWFROMCLIENT(hwnd);%@NL@%
  1013. %@NL@%
  1014.     %@AB@%/*%@NL@%
  1015. %@AB@%     * Set the pattern to be at the top-left%@NL@%
  1016. %@AB@%     * since we're top-left aligning the bits.%@NL@%
  1017. %@AB@%     */%@AE@%%@NL@%
  1018.     WinQueryWindowRect(hwnd, (PRECTL)&rclWindow);%@NL@%
  1019.     ptlPatternRef.x = rclWindow.xLeft - npview->xOrigin;%@NL@%
  1020.     ptlPatternRef.y = rclWindow.yTop + npview->yOrigin;%@NL@%
  1021.     GpiSetPatternRefPoint(hps, &ptlPatternRef);%@NL@%
  1022. %@NL@%
  1023.     for (i = 0; i < 8; i++) {%@NL@%
  1024. %@NL@%
  1025.         clr = clrStart = aclrRGB[i * 2];%@NL@%
  1026.         clrEnd = aclrRGB[(i * 2) + 1];%@NL@%
  1027.         clrInc = (clrEnd - clrStart) / 8;%@NL@%
  1028. %@NL@%
  1029.         for (j = 0; j < 8; j++) {%@NL@%
  1030.             abnd.lColor = clr + (j * clrInc);%@NL@%
  1031.             GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR, 0L, (PBUNDLE)&abnd);%@NL@%
  1032. %@NL@%
  1033.             %@AB@%/*%@NL@%
  1034. %@AB@%             * Only draw the box if it's going to%@NL@%
  1035. %@AB@%             * be visible in the update region.%@NL@%
  1036. %@AB@%             */%@AE@%%@NL@%
  1037.             WinSetRect(NULL, &rclTest, 10 + (i * 75),%@NL@%
  1038.                     (SHORT)rclWindow.yTop - 75 - (j * 75), 75 + (i * 75),%@NL@%
  1039.                     (SHORT)rclWindow.yTop - 10 - (j * 75));%@NL@%
  1040. %@NL@%
  1041.             WinOffsetRect(NULL, &rclTest, -npview->xOrigin, npview->yOrigin);%@NL@%
  1042. %@NL@%
  1043.             if (WinIntersectRect(NULL, &rclDst, &rclTest, &rclPaint)) {%@NL@%
  1044. %@NL@%
  1045.                 ptl.x = rclTest.xLeft;%@NL@%
  1046.                 ptl.y = rclTest.yTop;%@NL@%
  1047.                 GpiSetCurrentPosition(hps, (PPOINTL)&ptl);%@NL@%
  1048. %@NL@%
  1049.                 ptl.x = rclTest.xRight;%@NL@%
  1050.                 ptl.y = rclTest.yBottom;%@NL@%
  1051.                 GpiBox(hps, DRO_OUTLINEFILL, (PPOINTL)&ptl, 40L, 40L);%@NL@%
  1052.             }%@NL@%
  1053.         }%@NL@%
  1054.     }%@NL@%
  1055. %@NL@%
  1056.     WinEndPaint(hps);%@NL@%
  1057. }%@NL@%
  1058. %@NL@%
  1059. %@NL@%
  1060. %@2@%%@AH@%APPINIT.C%@AE@%%@EH@%%@NL@%
  1061. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\MDI\APPINIT.C%@AE@%%@NL@%
  1062. %@NL@%
  1063. %@AB@%/*%@NL@%
  1064. %@AB@%    mdiinit.c - MDI initialization funtions.%@NL@%
  1065. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  1066. %@AB@%*/%@AE@%%@NL@%
  1067. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  1068. %@AI@%#define %@AE@%INCL_WINCOMMON %@NL@%
  1069. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  1070. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  1071. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  1072. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  1073. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  1074. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  1075. %@AI@%#define %@AE@%INCL_WINRECTANGLES %@NL@%
  1076. %@AI@%#define %@AE@%INCL_WINHEAP %@NL@%
  1077. %@AI@%#define %@AE@%INCL_GPIBITMAPS %@NL@%
  1078. %@AI@%#define %@AE@%INCL_GPILCIDS %@NL@%
  1079. %@AI@%#define %@AE@%INCL_DEV %@NL@%
  1080. %@NL@%
  1081. %@AI@%#include %@AE@%<os2.h> %@NL@%
  1082. %@AI@%#include %@AE@%"app.h" %@NL@%
  1083. %@AI@%#include %@AE@%"appdata.h" %@NL@%
  1084. %@AI@%#include %@AE@%"mdi.h" %@NL@%
  1085. %@AI@%#include %@AE@%"mdidata.h" %@NL@%
  1086. %@NL@%
  1087. %@NL@%
  1088. %@AB@%/* Function prototypes */%@AE@%%@NL@%
  1089. BOOL RegisterWindowClasses(VOID);%@NL@%
  1090. VOID InitSysValues(VOID);%@NL@%
  1091. %@NL@%
  1092. %@NL@%
  1093. BOOL AppInit(VOID)%@NL@%
  1094. {%@NL@%
  1095.     ULONG ctlData;%@NL@%
  1096.     HPS hps;%@NL@%
  1097.     HDC hdc;%@NL@%
  1098. %@NL@%
  1099.     hab = WinInitialize(0);%@NL@%
  1100. %@NL@%
  1101.     hmqMDI = WinCreateMsgQueue(hab, 0);%@NL@%
  1102. %@NL@%
  1103.     if (!RegisterWindowClasses())%@NL@%
  1104.         return(FALSE);%@NL@%
  1105. %@NL@%
  1106.     ctlData = FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU |%@NL@%
  1107.               FCF_MENU | FCF_TASKLIST | FCF_SHELLPOSITION | FCF_ICON;%@NL@%
  1108. %@NL@%
  1109.     hwndMDIFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,%@NL@%
  1110.             (VOID FAR *)&ctlData, szMDIClass, (PSZ)NULL,%@NL@%
  1111.             WS_VISIBLE | WS_CLIPCHILDREN, NULL, IDR_MDI,%@NL@%
  1112.             (HWND FAR *)&hwndMDI);%@NL@%
  1113. %@NL@%
  1114. %@NL@%
  1115.     if (hwndMDIFrame == NULL)%@NL@%
  1116.         return(FALSE);%@NL@%
  1117. %@NL@%
  1118. %@AB@%/* MULTIPLEMENU */%@AE@%%@NL@%
  1119. %@NL@%
  1120.     %@AB@%/* Remember the first menu so we can put it back when all the documents are%@NL@%
  1121. %@AB@%       closed */%@AE@%%@NL@%
  1122.     hwndFirstMenu=WinWindowFromID(hwndMDIFrame, FID_MENU);%@NL@%
  1123. %@NL@%
  1124.     hHeap = WinCreateHeap(0, 0, 0, 0, 0, 0);%@NL@%
  1125. %@NL@%
  1126.     if (hHeap == NULL)%@NL@%
  1127.         return(FALSE);%@NL@%
  1128. %@NL@%
  1129.     hps = WinGetPS(hwndMDI);%@NL@%
  1130. %@NL@%
  1131.     hdc = GpiQueryDevice(hps);%@NL@%
  1132.     DevQueryCaps(hdc, CAPS_FAMILY, CAPS_VERTICAL_FONT_RES, (PLONG)rglDevCaps);%@NL@%
  1133. %@NL@%
  1134.     WinReleasePS(hps);%@NL@%
  1135. %@NL@%
  1136.     InitSysValues();%@NL@%
  1137. %@NL@%
  1138.     return(TRUE);%@NL@%
  1139. }%@NL@%
  1140. %@NL@%
  1141. %@NL@%
  1142. VOID InitSysValues(VOID)%@NL@%
  1143. {%@NL@%
  1144.     cyTitlebar = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);%@NL@%
  1145.     cyIcon = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYICON);%@NL@%
  1146. %@NL@%
  1147.     cxBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);%@NL@%
  1148.     cyBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);%@NL@%
  1149. %@NL@%
  1150.     cxSizeBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);%@NL@%
  1151.     cySizeBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);%@NL@%
  1152. %@NL@%
  1153.     cxByteAlign = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBYTEALIGN);%@NL@%
  1154.     cyByteAlign = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBYTEALIGN);%@NL@%
  1155. %@NL@%
  1156.     cxVScroll = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);%@NL@%
  1157.     cyVScrollArrow = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW);%@NL@%
  1158.     cyHScroll = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);%@NL@%
  1159. %@NL@%
  1160.     cxScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);%@NL@%
  1161.     cyScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);%@NL@%
  1162. %@NL@%
  1163.     cxMinmaxButton = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXMINMAXBUTTON);%@NL@%
  1164. }%@NL@%
  1165. %@NL@%
  1166. %@NL@%
  1167. BOOL RegisterWindowClasses(VOID)%@NL@%
  1168. {%@NL@%
  1169.     if (!WinRegisterClass(NULL, szMDIClass, (PFNWP)MDIWndProc,%@NL@%
  1170.             CS_SYNCPAINT, 0))%@NL@%
  1171.         return(FALSE);%@NL@%
  1172. %@NL@%
  1173.     if (!WinRegisterClass(NULL, szDocClass, (PFNWP)DocWndProc,%@NL@%
  1174.             0L, sizeof(NPVIEW)))%@NL@%
  1175.         return(FALSE);%@NL@%
  1176. %@NL@%
  1177.     return(TRUE);%@NL@%
  1178. }%@NL@%
  1179. %@NL@%
  1180. %@NL@%
  1181. VOID AppTerminate(VOID)%@NL@%
  1182. {%@NL@%
  1183.     WinDestroyWindow(hwndMDIFrame);%@NL@%
  1184. %@NL@%
  1185.     WinDestroyHeap(hHeap);%@NL@%
  1186. %@NL@%
  1187.     WinDestroyMsgQueue(hmqMDI);%@NL@%
  1188. %@NL@%
  1189.     WinTerminate(hab);%@NL@%
  1190. }%@NL@%
  1191. %@NL@%
  1192. %@NL@%
  1193. %@2@%%@AH@%ARRANGE.C%@AE@%%@EH@%%@NL@%
  1194. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\MDI\ARRANGE.C%@AE@%%@NL@%
  1195. %@NL@%
  1196. %@AB@%/***************************************************************************\%@NL@%
  1197. %@AB@%* ARRANGE.c - This file contains code to do window arrangment.%@NL@%
  1198. %@AB@%*%@NL@%
  1199. %@AB@%* Created by Microsoft Corporation, 1989%@NL@%
  1200. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1201. %@NL@%
  1202. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  1203. %@AI@%#define %@AE@%INCL_WINCOMMON %@NL@%
  1204. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  1205. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  1206. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  1207. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  1208. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  1209. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  1210. %@AI@%#define %@AE@%INCL_WINRECTANGLES %@NL@%
  1211. %@AI@%#define %@AE@%INCL_WINHEAP %@NL@%
  1212. %@AI@%#include %@AE@%<os2.h> %@NL@%
  1213. %@AI@%#include %@AE@%"app.h" %@NL@%
  1214. %@AI@%#include %@AE@%"appdata.h" %@NL@%
  1215. %@AI@%#include %@AE@%"mdi.h" %@NL@%
  1216. %@AI@%#include %@AE@%"mdidata.h" %@NL@%
  1217. %@NL@%
  1218. %@NL@%
  1219. MINMAXFIX  %@AB@%/* add hack to keep the min/max icons in sync with reality */%@AE@%%@NL@%
  1220. %@NL@%
  1221. %@AB@%/* internal function prototypes */%@AE@%%@NL@%
  1222. BOOL SetTilePositions(PRECTL prc, SHORT cWnd, PSWP aswp);%@NL@%
  1223. SHORT CeilSquareRoot(USHORT us);%@NL@%
  1224. BOOL SetCascadePositions(PRECTL prc, SHORT cWnd, PSWP aswp);%@NL@%
  1225. BOOL SetCascadeParams(PRECTL prc, SHORT *pxEdge, SHORT *pyEdge,%@NL@%
  1226.                       SHORT *pxDelta, SHORT *pyDelta, SHORT *cMaxWnd);%@NL@%
  1227. BOOL GetArrangeSwp(USHORT *, SWP *, USHORT *, SWP *);%@NL@%
  1228. BOOL GetArrangeRectangle(PRECTL, BOOL);%@NL@%
  1229. BOOL ArrangeIconPositions(USHORT, PSWP);%@NL@%
  1230. %@NL@%
  1231. %@AB@%/* internal constants */%@AE@%%@NL@%
  1232. %@AI@%#define %@AE@%CASC_EDGE_NUM       2 %@NL@%
  1233. %@AI@%#define %@AE@%CASC_EDGE_DENOM     3 %@NL@%
  1234. %@NL@%
  1235. %@AB@%/* local constants */%@AE@%%@NL@%
  1236. %@AI@%#define %@AE@%ICON_PARK_NUM       5 %@NL@%
  1237. %@AI@%#define %@AE@%ICON_PARK_DENOM     3 %@NL@%
  1238. %@AI@%#define %@AE@%CLASS_NAME_LENGTH   8 %@NL@%
  1239. %@NL@%
  1240. %@AB@%/***************************************************************************\%@NL@%
  1241. %@AB@%* ArrangeWindowPositions%@NL@%
  1242. %@AB@%*%@NL@%
  1243. %@AB@%* This function sets positions for arranging windows nicely in a rectangle.%@NL@%
  1244. %@AB@%* The hwnd field of each SWP structure should be set by the user, either%@NL@%
  1245. %@AB@%* before or after calling this function.  The function sets all other%@NL@%
  1246. %@AB@%* fields.  The SWP array can then be passed to WinSetMultWindowPos() to do%@NL@%
  1247. %@AB@%* the physical arrangement.  There are two arrangement styles available,%@NL@%
  1248. %@AB@%* AWP_TILED and AWP_CASCADED.%@NL@%
  1249. %@AB@%*%@NL@%
  1250. %@AB@%* AWP_TILED:%@NL@%
  1251. %@AB@%*%@NL@%
  1252. %@AB@%* The tiles are generated by rows, top left (first) to bottom right (last).%@NL@%
  1253. %@AB@%* Each row has the same number of tiles.  The number of tiles in each%@NL@%
  1254. %@AB@%* column will differ by at most one, with each column containing one fewer%@NL@%
  1255. %@AB@%* tile to the left of the other columns.%@NL@%
  1256. %@AB@%*%@NL@%
  1257. %@AB@%* AWP_CASCADED:%@NL@%
  1258. %@AB@%*%@NL@%
  1259. %@AB@%* The windows are generated bottom right (first) to top left (last).%@NL@%
  1260. %@AB@%*%@NL@%
  1261. %@AB@%* Parameters:%@NL@%
  1262. %@AB@%*   prc:    rectangle to contain the tiled windows%@NL@%
  1263. %@AB@%*   cWnd:   number of windows to tile%@NL@%
  1264. %@AB@%*   aswp:   array of SWP structures, one for each tile window%@NL@%
  1265. %@AB@%*   fStyle: the style to arrange the windows%@NL@%
  1266. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1267. %@NL@%
  1268. BOOL ArrangeWindowPositions(PRECTL prc, SHORT cWnd, PSWP aswp, USHORT fStyle)%@NL@%
  1269. {%@NL@%
  1270.     %@AB@%/* check validity of input rectangle */%@AE@%%@NL@%
  1271.     if ((prc->xRight - prc->xLeft < 1) || (prc->yTop - prc->yBottom < 1)) {%@NL@%
  1272.         return FALSE;%@NL@%
  1273.     }%@NL@%
  1274. %@NL@%
  1275.     %@AB@%/* set window positions */%@AE@%%@NL@%
  1276.     switch (fStyle) {%@NL@%
  1277.     case AWP_TILED:%@NL@%
  1278.         return SetTilePositions(prc, cWnd, aswp);%@NL@%
  1279.     case AWP_CASCADED:%@NL@%
  1280.         return SetCascadePositions(prc, cWnd, aswp);%@NL@%
  1281.     default:%@NL@%
  1282.         return FALSE;%@NL@%
  1283.     }%@NL@%
  1284. }%@NL@%
  1285. %@NL@%
  1286. %@NL@%
  1287. %@AB@%/***************************************************************************\%@NL@%
  1288. %@AB@%* SetTilePositions%@NL@%
  1289. %@AB@%*%@NL@%
  1290. %@AB@%* This function sets positions for tiling windows in a rectangle.%@NL@%
  1291. %@AB@%*%@NL@%
  1292. %@AB@%* NOTE:%@NL@%
  1293. %@AB@%*   There are a few subtleties to this code:%@NL@%
  1294. %@AB@%*%@NL@%
  1295. %@AB@%*   The algorithm lays tiles in a modified NxN grid.  It can be shown%@NL@%
  1296. %@AB@%*   that any positive number of tiles can be laid out in such a grid of%@NL@%
  1297. %@AB@%*   N columns so that each column has at least N-2 tiles and no column%@NL@%
  1298. %@AB@%*   has more than one tile more than any other.  Proof left to the%@NL@%
  1299. %@AB@%*   interested reader.%@NL@%
  1300. %@AB@%*%@NL@%
  1301. %@AB@%*   The tiles coordinates are not generated by stepping over a fixed%@NL@%
  1302. %@AB@%*   interval since this will not usually fill the rectangle completely.%@NL@%
  1303. %@AB@%*   Thus the offset at each step is calculated from the previous tile%@NL@%
  1304. %@AB@%*   to the correct fractional position within the whole rectangle.%@NL@%
  1305. %@AB@%*%@NL@%
  1306. %@AB@%*   Since the last "row" of tiles may not have any members in the beginning%@NL@%
  1307. %@AB@%*   columns, these tiles are addressed differently in the SWP array to%@NL@%
  1308. %@AB@%*   account for the "missing" tiles.%@NL@%
  1309. %@AB@%*%@NL@%
  1310. %@AB@%* Parameters:%@NL@%
  1311. %@AB@%*   prc:        rectangle to contain the tiled windows%@NL@%
  1312. %@AB@%*   cWnd:        number of windows to tile the rectangle with%@NL@%
  1313. %@AB@%*   aswp:        array of SWP structures, one for each tile window%@NL@%
  1314. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1315. %@NL@%
  1316. BOOL SetTilePositions(PRECTL prc, SHORT cWnd, PSWP aswp)%@NL@%
  1317. {%@NL@%
  1318.     register SHORT usRoot;%@NL@%
  1319.     register SHORT cExtras;%@NL@%
  1320.     SHORT iChange;%@NL@%
  1321.     SHORT cDiff;%@NL@%
  1322.     SHORT x, y, cx, cy;%@NL@%
  1323.     SHORT iRow, iCol;%@NL@%
  1324. %@NL@%
  1325.     %@AB@%/* get grid dimensions */%@AE@%%@NL@%
  1326.     usRoot = CeilSquareRoot(cWnd);%@NL@%
  1327.     cExtras = usRoot * usRoot - cWnd;%@NL@%
  1328. %@NL@%
  1329.     %@AB@%/* find column where number of rows increases and find initial%@NL@%
  1330. %@AB@%       difference of rows versus columns */%@AE@%%@NL@%
  1331.     if (cExtras >= usRoot) {%@NL@%
  1332.         iChange = cExtras - usRoot;%@NL@%
  1333.         cDiff = 2;%@NL@%
  1334.     } else {%@NL@%
  1335.         iChange = cExtras;%@NL@%
  1336.         cDiff = 1;%@NL@%
  1337.     }%@NL@%
  1338. %@NL@%
  1339.     %@AB@%/* assign x coordinates */%@AE@%%@NL@%
  1340.     x = (SHORT)prc->xLeft;%@NL@%
  1341.     cx = 0;%@NL@%
  1342.     for (iCol = 0; iCol < usRoot; iCol++) {%@NL@%
  1343.         x += cx - cxBorder;%@NL@%
  1344.         cx = ((SHORT)prc->xLeft) +%@NL@%
  1345.              (((SHORT)(prc->xRight - prc->xLeft)) * (iCol + 1)) / usRoot -%@NL@%
  1346.              x + cxBorder;%@NL@%
  1347.         for (iRow = 0; iRow < usRoot - cDiff; iRow++) {%@NL@%
  1348.             aswp[iRow * usRoot + iCol].x = x;%@NL@%
  1349.             aswp[iRow * usRoot + iCol].cx = cx;%@NL@%
  1350.             aswp[iRow * usRoot + iCol].fs = SWP_SIZE | SWP_MOVE;%@NL@%
  1351.         }%@NL@%
  1352.         %@AB@%/* assign "extra" row */%@AE@%%@NL@%
  1353.         if (iCol >= iChange) {%@NL@%
  1354.             aswp[iRow * usRoot + iCol - iChange].x = x;%@NL@%
  1355.             aswp[iRow * usRoot + iCol - iChange].cx = cx;%@NL@%
  1356.             aswp[iRow * usRoot + iCol - iChange].fs = SWP_SIZE | SWP_MOVE;%@NL@%
  1357.         }%@NL@%
  1358.     }%@NL@%
  1359. %@NL@%
  1360.     %@AB@%/* assign y coordinates, columns without extra row */%@AE@%%@NL@%
  1361.     y = (SHORT)prc->yBottom;%@NL@%
  1362.     cy = 0;%@NL@%
  1363.     for (iRow = usRoot - cDiff - 1; iRow >= 0; iRow--) {%@NL@%
  1364.         y += cy - cyBorder;%@NL@%
  1365.         cy = ((SHORT)prc->yBottom) +%@NL@%
  1366.              (((SHORT)(prc->yTop - prc->yBottom)) * (usRoot - cDiff - iRow)) /%@NL@%
  1367.                 (usRoot - cDiff) - y + cyBorder;%@NL@%
  1368.         for (iCol = 0; iCol < iChange; iCol++) {%@NL@%
  1369.             aswp[iRow * usRoot + iCol].y = y;%@NL@%
  1370.             aswp[iRow * usRoot + iCol].cy = cy;%@NL@%
  1371.         }%@NL@%
  1372.     }%@NL@%
  1373. %@NL@%
  1374.     %@AB@%/* assign y coordinates, columns with extra row */%@AE@%%@NL@%
  1375.     %@AB@%/* do last row first (different offsets) */%@AE@%%@NL@%
  1376.     y = (SHORT)prc->yBottom - cyBorder;%@NL@%
  1377.     cy = ((SHORT)(prc->yTop - prc->yBottom)) / (usRoot - cDiff + 1) +%@NL@%
  1378.          2 * cyBorder;%@NL@%
  1379.     for (iCol = iChange; iCol < usRoot; iCol++) {%@NL@%
  1380.         aswp[usRoot * (usRoot - cDiff) + iCol - iChange].y = y;%@NL@%
  1381.         aswp[usRoot * (usRoot - cDiff) + iCol - iChange].cy = cy;%@NL@%
  1382.     }%@NL@%
  1383.     for (iRow = usRoot - cDiff - 1; iRow >= 0; iRow--) {%@NL@%
  1384.         y += cy - cyBorder;%@NL@%
  1385.         cy = ((SHORT)(prc->yBottom)) +%@NL@%
  1386.                 (((SHORT)(prc->yTop - prc->yBottom)) * (usRoot - cDiff - iRow + 1))%@NL@%
  1387.                 / (usRoot - cDiff + 1) - y + cyBorder;%@NL@%
  1388.         for (iCol = iChange; iCol < usRoot; iCol++) {%@NL@%
  1389.             aswp[iRow * usRoot + iCol].y = y;%@NL@%
  1390.             aswp[iRow * usRoot + iCol].cy = cy;%@NL@%
  1391.         }%@NL@%
  1392.     }%@NL@%
  1393. %@NL@%
  1394.     return TRUE;%@NL@%
  1395. }%@NL@%
  1396. %@NL@%
  1397. %@NL@%
  1398. %@AB@%/***************************************************************************\%@NL@%
  1399. %@AB@%* CeilSquareRoot%@NL@%
  1400. %@AB@%*%@NL@%
  1401. %@AB@%* This function returns the smallest integer greater or equal to the square%@NL@%
  1402. %@AB@%* root of an unsigned 16 bit integer.%@NL@%
  1403. %@AB@%*%@NL@%
  1404. %@AB@%* Parameter:%@NL@%
  1405. %@AB@%*   us: value to take the root of%@NL@%
  1406. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1407. %@NL@%
  1408. SHORT CeilSquareRoot(register USHORT us)%@NL@%
  1409. {%@NL@%
  1410.     register SHORT i;%@NL@%
  1411. %@NL@%
  1412.     %@AB@%/* prevent overflow of large numbers */%@AE@%%@NL@%
  1413.     if (us > 0xFE * 0xFE)%@NL@%
  1414.         return 0xFF;%@NL@%
  1415. %@NL@%
  1416.     %@AB@%/* iterate up past root */%@AE@%%@NL@%
  1417.     for (i = 0; i*i < (SHORT) us; i++)%@NL@%
  1418.         ;%@NL@%
  1419.     return i;%@NL@%
  1420. }%@NL@%
  1421. %@NL@%
  1422. %@NL@%
  1423. %@AB@%/***************************************************************************\%@NL@%
  1424. %@AB@%* SetCascadePositions%@NL@%
  1425. %@AB@%*%@NL@%
  1426. %@AB@%* This function sets positions for cascading windows in a rectangle.%@NL@%
  1427. %@AB@%*%@NL@%
  1428. %@AB@%* Parameters:%@NL@%
  1429. %@AB@%*   prc:        rectangle to contain the cascaded windows%@NL@%
  1430. %@AB@%*   cWnd:        number of windows to cascade%@NL@%
  1431. %@AB@%*   aswp:        array of SWP structures, one for each cascaded window%@NL@%
  1432. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1433. %@NL@%
  1434. BOOL SetCascadePositions(PRECTL prc, SHORT cWnd, PSWP aswp)%@NL@%
  1435. {%@NL@%
  1436.     SHORT xEdge, yEdge;%@NL@%
  1437.     SHORT xDelta, yDelta;%@NL@%
  1438.     SHORT cMaxWnd;%@NL@%
  1439.     register SHORT x, y;%@NL@%
  1440.     SHORT i, j;%@NL@%
  1441.     RECTL rc;%@NL@%
  1442. %@NL@%
  1443.     %@AB@%/* set cascade parameters */%@AE@%%@NL@%
  1444.     rc.xLeft = prc->xLeft - cxBorder;%@NL@%
  1445.     rc.xRight = prc->xRight + cyBorder;%@NL@%
  1446.     rc.yBottom = prc->yBottom - cyBorder;%@NL@%
  1447.     rc.yTop = prc->yTop + cyBorder;%@NL@%
  1448.     if (!SetCascadeParams((PRECTL)&rc, &xEdge, &yEdge, &xDelta, &yDelta,%@NL@%
  1449.                           &cMaxWnd)) {%@NL@%
  1450.         return FALSE;%@NL@%
  1451.     }%@NL@%
  1452. %@NL@%
  1453.     if (cWnd <= cMaxWnd) {%@NL@%
  1454.         %@AB@%/* only one run needed; move to top left corner */%@AE@%%@NL@%
  1455.         x = (SHORT)rc. xLeft;%@NL@%
  1456.         y = (SHORT)rc. yTop - yEdge;%@NL@%
  1457.         for (i = cWnd - 1; i >= 0; i--) {%@NL@%
  1458.             aswp[i].x = x;%@NL@%
  1459.             aswp[i].y = y;%@NL@%
  1460.             aswp[i].cx = xEdge;%@NL@%
  1461.             aswp[i].cy = yEdge;%@NL@%
  1462.             aswp[i].fs = SWP_SIZE | SWP_MOVE;%@NL@%
  1463.             x += xDelta;%@NL@%
  1464.             y -= yDelta;%@NL@%
  1465.         }%@NL@%
  1466. %@NL@%
  1467.     } else {%@NL@%
  1468. %@NL@%
  1469.         %@AB@%/* multiple runs necessary; start at bottom right, iterate up to%@NL@%
  1470. %@AB@%           top left */%@AE@%%@NL@%
  1471. %@NL@%
  1472.         i = 0;%@NL@%
  1473. %@NL@%
  1474.         while (i < cWnd) {%@NL@%
  1475. %@NL@%
  1476.             %@AB@%/* even run */%@AE@%%@NL@%
  1477.             x = ((SHORT)rc. xLeft) + (cMaxWnd-1) * xDelta;%@NL@%
  1478.             y = ((SHORT)rc. yTop) - yEdge - (cMaxWnd-1) * yDelta;%@NL@%
  1479.             for (j = 0; j < cMaxWnd; j++) {%@NL@%
  1480.                 aswp[i].x = x;%@NL@%
  1481.                 aswp[i].y = y;%@NL@%
  1482.                 aswp[i].cx = xEdge;%@NL@%
  1483.                 aswp[i].cy = yEdge;%@NL@%
  1484.                 aswp[i].fs = SWP_SIZE | SWP_MOVE;%@NL@%
  1485.                 x -= xDelta;%@NL@%
  1486.                 y += yDelta;%@NL@%
  1487.                 if (++i >= cWnd)%@NL@%
  1488.                     break;%@NL@%
  1489.             }%@NL@%
  1490. %@NL@%
  1491.             if (i >= cWnd)%@NL@%
  1492.                 break;%@NL@%
  1493. %@NL@%
  1494.             %@AB@%/* odd run, offset by half delta y, one and one half delta x */%@AE@%%@NL@%
  1495.             x = ((SHORT)rc. xLeft) + (cMaxWnd-1) * xDelta + xDelta/2;%@NL@%
  1496.             y = ((SHORT)rc. yTop) - yEdge - (cMaxWnd-1) * yDelta + yDelta/2;%@NL@%
  1497.             for (j = 0; j < cMaxWnd - 1; j++) {%@NL@%
  1498.                 aswp[i].x = x;%@NL@%
  1499.                 aswp[i].y = y;%@NL@%
  1500.                 aswp[i].cx = xEdge;%@NL@%
  1501.                 aswp[i].cy = yEdge;%@NL@%
  1502.                 aswp[i].fs = SWP_SIZE | SWP_MOVE;%@NL@%
  1503.                 x -= xDelta;%@NL@%
  1504.                 y += yDelta;%@NL@%
  1505.                 if (++i >= cWnd)%@NL@%
  1506.                     break;%@NL@%
  1507.             }%@NL@%
  1508.         }%@NL@%
  1509.     }%@NL@%
  1510. %@NL@%
  1511.     return TRUE;%@NL@%
  1512. }%@NL@%
  1513. %@NL@%
  1514. %@NL@%
  1515. %@AB@%/***************************************************************************\%@NL@%
  1516. %@AB@%* SetCascadeParams%@NL@%
  1517. %@AB@%*%@NL@%
  1518. %@AB@%* This function sets parameters for cascading windows.        The window edges%@NL@%
  1519. %@AB@%* are based on a fraction CASC_EDGE_NUM/CASC_EDGE_DENOM of the rectangle.%@NL@%
  1520. %@AB@%* The x delta is four system font characters across, the y delta is two%@NL@%
  1521. %@AB@%* system lines high.%@NL@%
  1522. %@AB@%*%@NL@%
  1523. %@AB@%* Parameters:%@NL@%
  1524. %@AB@%*   prc:        rectangle to contain the windows%@NL@%
  1525. %@AB@%*   pxEdge:        width of the cascaded windows%@NL@%
  1526. %@AB@%*   pyEdge:        height of the cascaded windows%@NL@%
  1527. %@AB@%*   pxDelta:        x cascade offset%@NL@%
  1528. %@AB@%*   pyDelta:        y cascade offset%@NL@%
  1529. %@AB@%*   pcMaxWnd:        maximum number of windows in a cascade%@NL@%
  1530. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1531. %@NL@%
  1532. BOOL SetCascadeParams(PRECTL prc, SHORT *pxEdge, SHORT *pyEdge, SHORT *pxDelta,%@NL@%
  1533.         SHORT *pyDelta, SHORT *pcMaxWnd)%@NL@%
  1534. {%@NL@%
  1535.     register SHORT xEdge, yEdge;%@NL@%
  1536.     SHORT xDelta, yDelta;%@NL@%
  1537.     SHORT cMaxWnd;%@NL@%
  1538. %@NL@%
  1539.     %@AB@%/* get x and y deltas from system values */%@AE@%%@NL@%
  1540.     xDelta = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER)) +%@NL@%
  1541.              LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CXMINMAXBUTTON)) / 2 + 2;%@NL@%
  1542.     yDelta = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)) +%@NL@%
  1543.              LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR))%@NL@%
  1544.              - cyBorder;%@NL@%
  1545. %@NL@%
  1546.     %@AB@%/* get initial cut at yEdge using fraction */%@AE@%%@NL@%
  1547.     yEdge = (((SHORT)(prc->yTop - prc->yBottom)) * CASC_EDGE_NUM) /%@NL@%
  1548.             CASC_EDGE_DENOM;%@NL@%
  1549. %@NL@%
  1550.     %@AB@%/* determine maximum number of deltas used per run */%@AE@%%@NL@%
  1551.     cMaxWnd = (((SHORT)(prc->yTop - prc->yBottom)) - yEdge) / yDelta;%@NL@%
  1552. %@NL@%
  1553.     %@AB@%/* set x and y edges so full cascade will fill rectangle completely */%@AE@%%@NL@%
  1554.     xEdge = ((SHORT)(prc->xRight - prc->xLeft)) - xDelta/2 - cMaxWnd * xDelta;%@NL@%
  1555.     yEdge = ((SHORT)(prc->yTop - prc->yBottom)) - cMaxWnd * yDelta;%@NL@%
  1556. %@NL@%
  1557.     %@AB@%/* check that values are reasonable */%@AE@%%@NL@%
  1558.     if (cMaxWnd < 1 || xEdge < 1 || yEdge < 1) {%@NL@%
  1559.         return FALSE;%@NL@%
  1560.     }%@NL@%
  1561. %@NL@%
  1562.     *pxEdge = xEdge;%@NL@%
  1563.     *pyEdge = yEdge;%@NL@%
  1564.     *pxDelta = xDelta;%@NL@%
  1565.     *pyDelta = yDelta;%@NL@%
  1566.     %@AB@%/* return cMaxWnd as the maximum number of windows in a cascade */%@AE@%%@NL@%
  1567.     *pcMaxWnd = cMaxWnd + 1;%@NL@%
  1568. %@NL@%
  1569.     return TRUE;%@NL@%
  1570. }%@NL@%
  1571. %@NL@%
  1572. %@NL@%
  1573. %@AB@%/***************************************************************************\%@NL@%
  1574. %@AB@%* ArrangeWindows%@NL@%
  1575. %@AB@%*%@NL@%
  1576. %@AB@%* This function arranges application document windows.%@NL@%
  1577. %@AB@%*%@NL@%
  1578. %@AB@%* Returns:%@NL@%
  1579. %@AB@%*   TRUE if successful%@NL@%
  1580. %@AB@%*   FALSE otherwise%@NL@%
  1581. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1582. %@NL@%
  1583. BOOL ArrangeWindows(USHORT fStyle)%@NL@%
  1584. {%@NL@%
  1585.     USHORT cswpWnd, cswpIcon;%@NL@%
  1586.     RECTL rcl;%@NL@%
  1587.     register BOOL fReturn = FALSE;%@NL@%
  1588.     SWP NEAR *npswpWnd;%@NL@%
  1589.     SWP NEAR *npswpIcon;%@NL@%
  1590. %@NL@%
  1591.     npswpWnd = (SWP NEAR *) WinAllocMem(hHeap, sizeof(SWP) * cDocs);%@NL@%
  1592.     npswpIcon = (SWP NEAR *) WinAllocMem(hHeap, sizeof(SWP) * cDocs);%@NL@%
  1593. %@NL@%
  1594.     GetArrangeSwp(&cswpWnd, npswpWnd, &cswpIcon, npswpIcon);%@NL@%
  1595. %@NL@%
  1596.     GetArrangeRectangle((PRECTL)&rcl, (BOOL)cswpIcon);%@NL@%
  1597. %@NL@%
  1598.     %@AB@%/* set window positions */%@AE@%%@NL@%
  1599.     if (!ArrangeWindowPositions((PRECTL)&rcl, cswpWnd, (PSWP)npswpWnd, fStyle) ||%@NL@%
  1600.         !ArrangeIconPositions(cswpIcon, (PSWP)npswpIcon)) {%@NL@%
  1601.         goto ARRANGE_CLEANUP;%@NL@%
  1602.     }%@NL@%
  1603. %@NL@%
  1604. %@AI@%#if %@AE@%1 %@NL@%
  1605.     %@AB@%/* rearrange the windows */%@AE@%%@NL@%
  1606.     WinSetMultWindowPos(NULL, (PSWP)npswpWnd, cswpWnd);%@NL@%
  1607.     WinSetMultWindowPos(NULL, (PSWP)npswpIcon, cswpIcon);%@NL@%
  1608. %@AI@%#endif %@AE@%%@NL@%
  1609.     fReturn = TRUE;%@NL@%
  1610. %@NL@%
  1611. ARRANGE_CLEANUP:%@NL@%
  1612.     WinFreeMem(hHeap, (NPBYTE)npswpWnd, sizeof(SWP) * cDocs);%@NL@%
  1613.     WinFreeMem(hHeap, (NPBYTE)npswpIcon, sizeof(SWP) * cDocs);%@NL@%
  1614. %@NL@%
  1615.     return fReturn;%@NL@%
  1616. }%@NL@%
  1617. %@NL@%
  1618. %@AB@%/***************************************************************************\%@NL@%
  1619. %@AB@%* GetArrangeHandles%@NL@%
  1620. %@AB@%*%@NL@%
  1621. %@AB@%* This function generates the handles of all windows to be arranged and%@NL@%
  1622. %@AB@%* creates an array of SWP structures containing those handles.  Minimized%@NL@%
  1623. %@AB@%* and non-minimized windows are separated.  Non-frame, invisible and%@NL@%
  1624. %@AB@%* non-sizeable windows are ignored.%@NL@%
  1625. %@AB@%*%@NL@%
  1626. %@AB@%* Parameter:%@NL@%
  1627. %@AB@%*   npcswpWnd:        number of nonminimized windows found%@NL@%
  1628. %@AB@%*   npswpWnd:         array of SWP structures for nonminimized windows%@NL@%
  1629. %@AB@%*   npcswpIcon:       number of minimized windows found%@NL@%
  1630. %@AB@%*   npswpIcon:        array of SWP structures for minimized windows%@NL@%
  1631. %@AB@%*%@NL@%
  1632. %@AB@%* Returns:%@NL@%
  1633. %@AB@%*   TRUE if successful%@NL@%
  1634. %@AB@%*   FALSE otherwise%@NL@%
  1635. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1636. %@NL@%
  1637. BOOL GetArrangeSwp(USHORT *npcswpWnd, SWP *npswpWnd, USHORT *npcswpIcon,%@NL@%
  1638.         SWP *npswpIcon)%@NL@%
  1639. {%@NL@%
  1640.     register USHORT cWnd, cIcon;%@NL@%
  1641.     ULONG ulStyle;%@NL@%
  1642.     HWND hwnd;%@NL@%
  1643.     register NPDOC npdoc;%@NL@%
  1644. %@NL@%
  1645.     cWnd = 0;%@NL@%
  1646.     cIcon = 0;%@NL@%
  1647. %@NL@%
  1648.     %@AB@%/* enumerate windows and selectively add them to the arrange lists */%@AE@%%@NL@%
  1649.     for (hwnd = WinQueryWindow(hwndMDI, QW_TOP, FALSE);%@NL@%
  1650.          hwnd;%@NL@%
  1651.          hwnd = WinQueryWindow(hwnd, QW_NEXT, FALSE)) {%@NL@%
  1652. %@NL@%
  1653.         %@AB@%/* make sure the window is visible and owned by the app client window */%@AE@%%@NL@%
  1654.         ulStyle = WinQueryWindowULong(hwnd, QWL_STYLE);%@NL@%
  1655.         if (WinQueryWindow(hwnd, QW_OWNER, FALSE) ||%@NL@%
  1656.             !(ulStyle & WS_VISIBLE)) {%@NL@%
  1657.             continue;%@NL@%
  1658.         }%@NL@%
  1659. %@NL@%
  1660.         if (ulStyle & WS_MINIMIZED) {%@NL@%
  1661.             npswpIcon->hwnd = hwnd;%@NL@%
  1662.             npswpIcon++;%@NL@%
  1663.             cIcon++;%@NL@%
  1664.         } else {%@NL@%
  1665.             %@AB@%/* restore maximized windows */%@AE@%%@NL@%
  1666.             if (ulStyle & WS_MAXIMIZED) {%@NL@%
  1667. %@NL@%
  1668. %@AI@%#ifdef %@AE@%MINMAXFIX %@NL@%
  1669.                 %@AB@%/* Bring the min/max buttons back to life for a moment so%@NL@%
  1670. %@AB@%                   they stay in sync when the window is restored.  Then put%@NL@%
  1671. %@AB@%                   them back to the object window 07-Sep-1989 johnba%@NL@%
  1672. %@AB@%                */%@AE@%%@NL@%
  1673. %@NL@%
  1674.                 npdoc = NPDOCFROMCLIENT(WinWindowFromID(hwnd,FID_CLIENT));%@NL@%
  1675.                 WinSetParent(npdoc->hwndMinmax, hwnd, FALSE);%@NL@%
  1676. %@AI@%#endif %@AE@%%@NL@%
  1677.                 WinSetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_RESTORE );%@NL@%
  1678. %@AI@%#ifdef %@AE@%MINMAXFIX %@NL@%
  1679. %@NL@%
  1680. %@NL@%
  1681.                 if (hwndActiveDoc != hwnd) {%@NL@%
  1682.                     WinSetParent(npdoc->hwndMinmax, HWND_OBJECT, FALSE);%@NL@%
  1683.                     WinSendMsg(hwnd, WM_UPDATEFRAME, 0L, 0L);%@NL@%
  1684.                     }%@NL@%
  1685. %@AI@%#endif %@AE@%%@NL@%
  1686.                 }%@NL@%
  1687.             npswpWnd->hwnd = hwnd;%@NL@%
  1688.             npswpWnd++;%@NL@%
  1689.             cWnd++;%@NL@%
  1690.         }%@NL@%
  1691.     }%@NL@%
  1692. %@NL@%
  1693.     *npcswpWnd = cWnd;%@NL@%
  1694.     *npcswpIcon = cIcon;%@NL@%
  1695.     return TRUE;%@NL@%
  1696. }%@NL@%
  1697. %@NL@%
  1698. %@NL@%
  1699. %@AB@%/***************************************************************************\%@NL@%
  1700. %@AB@%* GetArrangeRectangle%@NL@%
  1701. %@AB@%*%@NL@%
  1702. %@AB@%* This function determines the area in which task windows are arranged.%@NL@%
  1703. %@AB@%*%@NL@%
  1704. %@AB@%* Parameter:%@NL@%
  1705. %@AB@%*   prc:        the generated area rectangle%@NL@%
  1706. %@AB@%*   fIconPark:        specifies if room should be made for icon parking lot%@NL@%
  1707. %@AB@%*%@NL@%
  1708. %@AB@%* Returns:%@NL@%
  1709. %@AB@%*   TRUE if successful%@NL@%
  1710. %@AB@%*   FALSE otherwise%@NL@%
  1711. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1712. %@NL@%
  1713. BOOL GetArrangeRectangle(PRECTL prc, BOOL fIconPark)%@NL@%
  1714. {%@NL@%
  1715.     register USHORT yIcon;%@NL@%
  1716.     register SHORT cxBorderInset;%@NL@%
  1717. %@NL@%
  1718.     %@AB@%/* get dimensions of desktop window */%@AE@%%@NL@%
  1719.     WinQueryWindowRect(hwndMDI, prc);%@NL@%
  1720. %@NL@%
  1721.     cxBorderInset = (SHORT)(WinQuerySysValue(HWND_DESKTOP, SV_CXBYTEALIGN) -%@NL@%
  1722.                        WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER));%@NL@%
  1723.     WinInflateRect(NULL, prc, -cxBorderInset, -cxBorderInset * %@NL@%
  1724.             (cyBorder / cxBorder));%@NL@%
  1725. %@NL@%
  1726.     if (fIconPark) {%@NL@%
  1727.         %@AB@%/* make room for single row of icon carpark */%@AE@%%@NL@%
  1728.         yIcon = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CYICON));%@NL@%
  1729.         prc->yBottom += (yIcon * ICON_PARK_NUM) / ICON_PARK_DENOM;%@NL@%
  1730.     }%@NL@%
  1731. %@NL@%
  1732.     return TRUE;%@NL@%
  1733. }%@NL@%
  1734. %@NL@%
  1735. %@AB@%/***************************************************************************\%@NL@%
  1736. %@AB@%* ArrangeIconPositions%@NL@%
  1737. %@AB@%*%@NL@%
  1738. %@AB@%* This function sets positions for minimized windows.%@NL@%
  1739. %@AB@%*%@NL@%
  1740. %@AB@%* Parameters:%@NL@%
  1741. %@AB@%*   cIcon:        number of icons to position%@NL@%
  1742. %@AB@%*   aswp:        array of SetWindowPos structures for those icons%@NL@%
  1743. %@AB@%*%@NL@%
  1744. %@AB@%* Returns:%@NL@%
  1745. %@AB@%*   TRUE if successful%@NL@%
  1746. %@AB@%*   FALSE otherwise%@NL@%
  1747. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  1748. %@NL@%
  1749. BOOL ArrangeIconPositions(USHORT cIcon, PSWP aswpIcon)%@NL@%
  1750. {%@NL@%
  1751.     register USHORT i;%@NL@%
  1752. %@NL@%
  1753.     for (i = 0; i < cIcon; i++) {%@NL@%
  1754.         aswpIcon[i].x = 0;%@NL@%
  1755.         aswpIcon[i].y = 0;%@NL@%
  1756.         aswpIcon[i].fs = SWP_MOVE;%@NL@%
  1757.     }%@NL@%
  1758. %@NL@%
  1759.     return TRUE;%@NL@%
  1760. }%@NL@%
  1761. %@NL@%
  1762. %@NL@%
  1763. %@2@%%@AH@%AVIO.C%@AE@%%@EH@%%@NL@%
  1764. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\BROWSE\AVBROWSE\AVIO.C%@AE@%%@NL@%
  1765. %@NL@%
  1766. %@AB@%/*%@NL@%
  1767. %@AB@%    avio.c -- AVIO action routines%@NL@%
  1768. %@AB@%%@NL@%
  1769. %@AB@%    Implements scrollbars, sets up an AVIO Presentation Space%@NL@%
  1770. %@AB@%*/%@AE@%%@NL@%
  1771. %@AI@%#define %@AE@% INCL_AVIO %@NL@%
  1772. %@AI@%#define %@AE@%        INCL_DEV %@NL@%
  1773. %@AI@%#define %@AE@% INCL_VIO %@NL@%
  1774. %@AI@%#define %@AE@% INCL_WINWINDOWMGR %@NL@%
  1775. %@AI@%#define %@AE@% INCL_WINSYS %@NL@%
  1776. %@AI@%#define %@AE@% INCL_WINMESSAGEMGR %@NL@%
  1777. %@AI@%#define %@AE@% INCL_WINTRACKRECT %@NL@%
  1778. %@AI@%#define %@AE@% INCL_WINFRAMEMGR %@NL@%
  1779. %@AI@%#define %@AE@% INCL_WINSCROLLBARS %@NL@%
  1780. %@AI@%#include %@AE@%<os2.h> %@NL@%
  1781. <string.h>        %@AB@%/* One strlen() call in the Blast() macro */%@AE@%%@NL@%
  1782. "avio.h"        %@AB@%/* Get Avio-prefixed routine prototypes   */%@AE@%%@NL@%
  1783. %@AB@%/*%@NL@%
  1784. %@AB@%    Constants%@NL@%
  1785. %@AB@%*/%@AE@%%@NL@%
  1786. char        Blank[2] = { 0x20, 0x07 };        %@AB@%/* <Space> + EGA white attribute */%@AE@%%@NL@%
  1787. %@AB@%/*%@NL@%
  1788. %@AB@%    Macros to make the code more readable%@NL@%
  1789. %@AB@%*/%@AE@%%@NL@%
  1790. %@AB@%/* Upper and Lower Bound Calculations */%@AE@%%@NL@%
  1791. %@AI@%#define %@AE@%       Abs(a)                (((a) > 0) ? (a) : (-(a))) %@NL@%
  1792. %@AI@%#define %@AE@%       Min(a,b)        (((a) < (b)) ? (a) : (b)) %@NL@%
  1793. %@AI@%#define %@AE@%       Max(a,b)        (((a) > (b)) ? (a) : (b)) %@NL@%
  1794. %@AI@%#define %@AE@%LowerBound(pos, disp, lbound) Max(pos - disp, lbound) %@NL@%
  1795. %@AI@%#define %@AE@%UpperBound(pos, disp, ubound) Min(pos + disp, ubound) %@NL@%
  1796. %@NL@%
  1797. %@AB@%/* Scroll Bar Abbreviations */%@AE@%%@NL@%
  1798. %@AI@%#define %@AE@%DisableSB(hSB)        WinSetParent(hSB, HWND_OBJECT, TRUE) %@NL@%
  1799. %@AI@%#define %@AE@%EnableSB(hSB)         WinSetParent(hSB, hWndFrame,   TRUE) %@NL@%
  1800. %@AI@%#define %@AE@%SetScroll(h, pos, max) \ %@NL@%
  1801.     WinSendMsg(h, SBM_SETSCROLLBAR, MPFROM2SHORT(pos, 0), MPFROM2SHORT(0, max))%@NL@%
  1802. %@NL@%
  1803. %@AB@%/* Scrollbar redraw macros */%@AE@%%@NL@%
  1804. %@AI@%#define %@AE@%UpdateOn(c, hsb)        if (!(++c)) WinEnableWindowUpdate(hsb, TRUE) %@NL@%
  1805. %@AI@%#define %@AE@%UpdateOff(c, hsb)        if (!(c--)) WinEnableWindowUpdate(hsb, FALSE) %@NL@%
  1806. %@AI@%#define %@AE@%       UpdateFrame(sb)        \ %@NL@%
  1807.         WinSendMsg(hWndFrame, WM_UPDATEFRAME, MPFROMLONG(sb), 0L)%@NL@%
  1808. %@NL@%
  1809. %@AB@%/* Scrolling Macros */%@AE@%%@NL@%
  1810. ClearScreen()        ScrollUp(-1)        %@AB@%/* Scroll up an "infinite" # lines */%@AE@%%@NL@%
  1811. %@AI@%#define %@AE@%ScrollDown(n)        VioScrollDn(0, 0, -1, -1, n, Blank, hVPS) %@NL@%
  1812. %@AI@%#define %@AE@%ScrollUp(n)        VioScrollUp(0, 0, -1, -1, n, Blank, hVPS) %@NL@%
  1813. %@NL@%
  1814. %@AB@%/* RectL -> SWP conversion macros */%@AE@%%@NL@%
  1815. %@AI@%#define %@AE@%       lcx(r)                ((r.xRight - r.xLeft) + 1) %@NL@%
  1816. %@AI@%#define %@AE@%       lcy(r)                ((r.yTop - r.yBottom) + 1) %@NL@%
  1817. %@NL@%
  1818. %@AB@%/* Miscellaneous macros */%@AE@%%@NL@%
  1819. %@AI@%#define %@AE@%Blast(l, x, y)        VioWrtCharStr(l, Min((SHORT) strlen(l), cxChScreen), x, y, hVPS) %@NL@%
  1820. %@AI@%#define %@AE@%CalcChars(sPg, sCh) \ %@NL@%
  1821.     ((sCh) ? (Max(((sPg) / (sCh)), 0)) : 0)%@NL@%
  1822. %@AI@%#define %@AE@%       SetCellSize(h,w) VioSetDeviceCellSize(h, w, hVPS) %@NL@%
  1823. %@AI@%#define %@AE@%       Value(value)        WinQuerySysValue(HWND_DESKTOP, value) %@NL@%
  1824. %@AB@%/*%@NL@%
  1825. %@AB@%    File-Local Variables%@NL@%
  1826. %@AB@%*/%@AE@%%@NL@%
  1827. HDC        hDC;                %@AB@%/* Device Context */%@AE@%%@NL@%
  1828. HVPS        hVPS;                %@AB@%/* Virtual PS */%@AE@%%@NL@%
  1829. int        iTopLine;        %@AB@%/* PS Line of window corner */%@AE@%%@NL@%
  1830. int        iCurCol;         %@AB@%/* Current column of window corner */%@AE@%%@NL@%
  1831. int        cxChPage;        %@AB@%/* Width and height of our window, in characters */%@AE@%%@NL@%
  1832. int        cyChPage;%@NL@%
  1833. int        iMaxHorz;        %@AB@%/* Scroll bar upper bounds */%@AE@%%@NL@%
  1834. int        iMaxVert;        %@NL@%
  1835. BOOL        fNeedHorz;        %@AB@%/* Do we need the scroll bars or not? */%@AE@%%@NL@%
  1836. BOOL        fNeedVert;%@NL@%
  1837. HWND        hWndHorzSB;        %@AB@%/* Window handles of ScrollBar windows */%@AE@%%@NL@%
  1838. HWND        hWndVertSB;%@NL@%
  1839. extern        HWND        hWndFrame;        %@AB@%/* Client, frame windows */%@AE@%%@NL@%
  1840. extern        HWND        hWndClient;%@NL@%
  1841. PFNWP        pfnOldClient;        %@AB@%/* Old Client Window Procedure pointer */%@AE@%%@NL@%
  1842. PFNWP        pfnOldFrame;        %@AB@%/* Old Frame  Window Procedure pointer */%@AE@%%@NL@%
  1843. SHORT        cyChPS;                %@AB@%/* Number of rows in AVIO PS */%@AE@%%@NL@%
  1844. SHORT        cxChPS;                %@AB@%/* Number of cols in AVIO PS */%@AE@%%@NL@%
  1845. SHORT        cyChScreen;                %@AB@%/* Number of rows in display space */%@AE@%%@NL@%
  1846. SHORT        cxChScreen;                %@AB@%/* Number of cols in display space */%@AE@%%@NL@%
  1847. PFNQL        pfnQueryLine;%@NL@%
  1848. %@AB@%/*%@NL@%
  1849. %@AB@%    Measurements used to help make the window look nice%@NL@%
  1850. %@AB@%*/%@AE@%%@NL@%
  1851. LONG        cxConstant, cyConstant;                        %@AB@%/* Miscellaneous frame lens */%@AE@%%@NL@%
  1852. int        cxMaxFrame, cyMaxFrame;                        %@AB@%/* Maximum frame widths */%@AE@%%@NL@%
  1853. LONG        lChWidth,   lChHeight;%@NL@%
  1854. SHORT        cxMaxClient, cyMaxClient;                %@AB@%/* Client area bounds  */%@AE@%%@NL@%
  1855. BOOL        fCreatedPS;                                %@AB@%/* AVIO PS created */%@AE@%%@NL@%
  1856. int        cHUpdate = -1;                                %@AB@%/* Keep track of updates */%@AE@%%@NL@%
  1857. int        cVUpdate = -1;%@NL@%
  1858. %@AB@%/*%@NL@%
  1859. %@AB@%   Local prototypes%@NL@%
  1860. %@AB@%*/%@AE@%%@NL@%
  1861. void FixScroll(BOOL, BOOL, HWND, ULONG, int *, int, int *);%@NL@%
  1862. void UpdateScrollBars(RECTL);%@NL@%
  1863. void Refresh(void);%@NL@%
  1864. void Update(USHORT, USHORT, USHORT);%@NL@%
  1865. %@AB@%/*%@NL@%
  1866. %@AB@%    The actual routines%@NL@%
  1867. %@AB@%*/%@AE@%%@NL@%
  1868. void AvioInit(PLBINFO plbi) {%@NL@%
  1869. %@AB@%/*%@NL@%
  1870. %@AB@%    Initialize Presentation Space, Device Context, Scroll Bars%@NL@%
  1871. %@AB@%*/%@AE@%%@NL@%
  1872.     VIOCURSORINFO vci;%@NL@%
  1873.     %@AB@%/*%@NL@%
  1874. %@AB@%        Initialize the line buffer info %@NL@%
  1875. %@AB@%    */%@AE@%%@NL@%
  1876.     cyChScreen        = plbi->sRows;%@NL@%
  1877.     cxChScreen        = plbi->sCols;%@NL@%
  1878.     cyChPS        = plbi->sPSrows;%@NL@%
  1879.     cxChPS        = plbi->sPScols;%@NL@%
  1880.     pfnQueryLine = plbi->pfnQL;%@NL@%
  1881.     %@AB@%/*%@NL@%
  1882. %@AB@%        One Time Initializations...%@NL@%
  1883. %@AB@%    */%@AE@%%@NL@%
  1884.     if (!fCreatedPS) {%@NL@%
  1885.         %@AB@%/*%@NL@%
  1886. %@AB@%           Create the AVIO Presentation Space, with one attribute byte%@NL@%
  1887. %@AB@%        */%@AE@%%@NL@%
  1888.         hDC = WinOpenWindowDC(hWndClient);        %@AB@%/* Open the device context */%@AE@%%@NL@%
  1889.         VioCreatePS(&hVPS, cyChPS, cxChPS + 1, 0, 1, 0);%@NL@%
  1890.         VioAssociate(hDC, hVPS);                %@AB@%/* Link the PS with the DC */%@AE@%%@NL@%
  1891.         %@AB@%/*%@NL@%
  1892. %@AB@%            Turn off the cursor (set invisible attribute)%@NL@%
  1893. %@AB@%        */%@AE@%%@NL@%
  1894.         VioGetCurType(&vci, hVPS);%@NL@%
  1895.         vci.attr = -1;%@NL@%
  1896.         VioSetCurType(&vci, hVPS);%@NL@%
  1897.         %@AB@%/*%@NL@%
  1898. %@AB@%            Measure the frame components%@NL@%
  1899. %@AB@%        */%@AE@%%@NL@%
  1900.         cxConstant = 0;%@NL@%
  1901.         cyConstant = Value(SV_CYTITLEBAR) + Value(SV_CYMENU);%@NL@%
  1902.         %@AB@%/*%@NL@%
  1903. %@AB@%            Snag scroll bar info%@NL@%
  1904. %@AB@%        */%@AE@%%@NL@%
  1905.         hWndHorzSB        = WinWindowFromID(hWndFrame,  FID_HORZSCROLL);%@NL@%
  1906.         hWndVertSB        = WinWindowFromID(hWndFrame,  FID_VERTSCROLL);%@NL@%
  1907.         fNeedHorz        = fNeedVert        = TRUE;%@NL@%
  1908.         %@AB@%/*%@NL@%
  1909. %@AB@%            Setup the Client and Frame routines%@NL@%
  1910. %@AB@%        */%@AE@%%@NL@%
  1911.         pfnOldFrame        = WinSubclassWindow(hWndFrame,  AvioFrameWndProc);%@NL@%
  1912.         pfnOldClient        = WinSubclassWindow(hWndClient, AvioClientWndProc);%@NL@%
  1913.         fCreatedPS        = TRUE;%@NL@%
  1914.     }%@NL@%
  1915.     %@AB@%/*%@NL@%
  1916. %@AB@%        Repaint the screen%@NL@%
  1917. %@AB@%    */%@AE@%%@NL@%
  1918.     iTopLine = iCurCol = 0;%@NL@%
  1919.     AvioStartup(plbi->fLargeFont);%@NL@%
  1920. }%@NL@%
  1921. %@NL@%
  1922. void AvioStartup(BOOL fLargeFont) {%@NL@%
  1923. %@AB@%/*%@NL@%
  1924. %@AB@%    Clear the screen, set the font, redraw the area%@NL@%
  1925. %@AB@%*/%@AE@%%@NL@%
  1926.     RECTL rclFrame;%@NL@%
  1927. %@NL@%
  1928.     ClearScreen();%@NL@%
  1929.     AvioLargeFont(fLargeFont);%@NL@%
  1930.     WinQueryWindowRect(hWndFrame, &rclFrame);%@NL@%
  1931.     UpdateScrollBars(rclFrame);%@NL@%
  1932.     Update(0, cyChPS, 0);%@NL@%
  1933. }%@NL@%
  1934. %@NL@%
  1935. void AvioScroll(USHORT SB_Command, USHORT Position, BOOL Horizontal) {%@NL@%
  1936. %@AB@%/*%@NL@%
  1937. %@AB@%    Process the scroll bar messages%@NL@%
  1938. %@AB@%%@NL@%
  1939. %@AB@%    These routines are symmetric; in fact, SB_LINELEFT = SB_LINEUP, etc...%@NL@%
  1940. %@AB@%    so one might note that this could be condensed.  It's left expanded for%@NL@%
  1941. %@AB@%    speed and clarity.  The scrollbar values are bounded to stay inside%@NL@%
  1942. %@AB@%    the Presentation Space.%@NL@%
  1943. %@AB@%*/%@AE@%%@NL@%
  1944.     if (Horizontal) {  %@AB@%/* Horizontal Scroll Bar */%@AE@%%@NL@%
  1945.         switch (SB_Command) {%@NL@%
  1946.             case SB_LINELEFT:%@NL@%
  1947.                 iCurCol = LowerBound(iCurCol, 1, 0); break;%@NL@%
  1948.             case SB_LINERIGHT:%@NL@%
  1949.                 iCurCol = UpperBound(iCurCol, 1, iMaxHorz); break;%@NL@%
  1950.             case SB_PAGELEFT:%@NL@%
  1951.                 iCurCol = LowerBound(iCurCol, cxChPage, 0); break;%@NL@%
  1952.             case SB_PAGERIGHT:%@NL@%
  1953.                 iCurCol = UpperBound(iCurCol, cxChPage, iMaxHorz); break;%@NL@%
  1954.             case SB_SLIDERTRACK:%@NL@%
  1955.                 iCurCol = (SHORT) Position;%@NL@%
  1956.             default: break;%@NL@%
  1957.         }%@NL@%
  1958.         if (SB_Command != SB_SLIDERTRACK)%@NL@%
  1959.             SetScroll(hWndHorzSB, iCurCol, iMaxHorz);%@NL@%
  1960. %@NL@%
  1961.     } else { %@AB@%/* Vertical Scroll Bar */%@AE@%%@NL@%
  1962.         switch (SB_Command) {%@NL@%
  1963.             case SB_LINEUP:%@NL@%
  1964.                 iTopLine = LowerBound(iTopLine, 1, 0); break;%@NL@%
  1965.             case SB_LINEDOWN:%@NL@%
  1966.                 iTopLine = UpperBound(iTopLine, 1, iMaxVert); break;%@NL@%
  1967.             case SB_PAGEUP:%@NL@%
  1968.                 iTopLine = LowerBound(iTopLine, cyChPage, 0); break;%@NL@%
  1969.             case SB_PAGEDOWN:%@NL@%
  1970.                 iTopLine = UpperBound(iTopLine, cyChPage, iMaxVert);break;%@NL@%
  1971.             case SB_SLIDERTRACK:%@NL@%
  1972.                 iTopLine = (SHORT) Position;%@NL@%
  1973.             default: break;%@NL@%
  1974.         }%@NL@%
  1975.         if (SB_Command != SB_SLIDERTRACK)%@NL@%
  1976.             SetScroll(hWndVertSB, iTopLine, iMaxVert);%@NL@%
  1977.     }%@NL@%
  1978.     Refresh();%@NL@%
  1979. }%@NL@%
  1980. %@NL@%
  1981. MRESULT AvioSize(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  1982. %@AB@%/*%@NL@%
  1983. %@AB@%    Do the default AVIO sizing, and kyfe a few values%@NL@%
  1984. %@AB@%*/%@AE@%%@NL@%
  1985.     RECTL rclFrame;%@NL@%
  1986. %@NL@%
  1987.     if (!fCreatedPS) return 0L;%@NL@%
  1988.     %@AB@%/*%@NL@%
  1989. %@AB@%        Update the scroll bars, and the screen%@NL@%
  1990. %@AB@%    */%@AE@%%@NL@%
  1991.     WinQueryWindowRect(hWndFrame, &rclFrame);%@NL@%
  1992.     UpdateScrollBars(rclFrame);%@NL@%
  1993.     %@AB@%/*%@NL@%
  1994. %@AB@%        Now, do the normal AVIO processing%@NL@%
  1995. %@AB@%    */%@AE@%%@NL@%
  1996.     return WinDefAVioWindowProc(hWnd, msg, mp1, mp2);%@NL@%
  1997. }%@NL@%
  1998. %@NL@%
  1999. void Update(USHORT usLineNum, USHORT usHowMany, USHORT usStartLine) {%@NL@%
  2000. %@AB@%/*%@NL@%
  2001. %@AB@%    Updates N lines starting from START line on screen.%@NL@%
  2002. %@AB@%    Starts at saved line LINENUM.%@NL@%
  2003. %@AB@%*/%@AE@%%@NL@%
  2004.     USHORT        i;                                %@AB@%/* Loop index variable */%@AE@%%@NL@%
  2005.     USHORT        usWhichLine = usLineNum;        %@AB@%/* Line number to be queried */%@AE@%%@NL@%
  2006.     char        *szLine;%@NL@%
  2007. %@NL@%
  2008.     for (i = usStartLine; i < (usStartLine + usHowMany); i++) {%@NL@%
  2009.         szLine = (*pfnQueryLine)(usWhichLine++);        %@AB@%/* Get the line */%@AE@%%@NL@%
  2010.         if (szLine) Blast(szLine, i, 0);                %@AB@%/* Print it out */%@AE@%%@NL@%
  2011.     }%@NL@%
  2012. }%@NL@%
  2013. %@NL@%
  2014. void Refresh(void) {%@NL@%
  2015. %@AB@%/*%@NL@%
  2016. %@AB@%    Do the origin shifting and screen updating%@NL@%
  2017. %@AB@%*/%@AE@%%@NL@%
  2018.     SHORT  Delta;%@NL@%
  2019.     int static iOldTopLine = 0;%@NL@%
  2020. %@NL@%
  2021.     VioSetOrg(0, iCurCol, hVPS); %@AB@%/* Get the free AVIO horizontal shift */%@AE@%%@NL@%
  2022.     Delta = iTopLine - iOldTopLine; %@AB@%/* Compute vertical shift */%@AE@%%@NL@%
  2023.     if (Abs(Delta) < cyChPS) {%@NL@%
  2024.         if (Delta < 0) {         %@AB@%/* Scroll Up -- make Delta positive*/%@AE@%%@NL@%
  2025.             ScrollDown(-Delta);%@NL@%
  2026.             Update(iTopLine, -Delta, 0);%@NL@%
  2027.         } else {                %@AB@%/* Scroll Down by Delta */%@AE@%%@NL@%
  2028.             ScrollUp(Delta);%@NL@%
  2029.             Update(iTopLine + cyChPS - Delta, Delta, cyChPS - Delta);%@NL@%
  2030.         }%@NL@%
  2031.     } else AvioRedraw();        %@AB@%/* Redo the entire screen */%@AE@%%@NL@%
  2032.     iOldTopLine = iTopLine;%@NL@%
  2033. }%@NL@%
  2034. %@NL@%
  2035. void AvioClose(void) {%@NL@%
  2036. %@AB@%/*%@NL@%
  2037. %@AB@%    Termination routines%@NL@%
  2038. %@AB@%*/%@AE@%%@NL@%
  2039.     %@AB@%/*%@NL@%
  2040. %@AB@%        Destroy the Presentation Space%@NL@%
  2041. %@AB@%    */%@AE@%%@NL@%
  2042.     VioAssociate(NULL, hVPS);%@NL@%
  2043.     VioDestroyPS(hVPS);%@NL@%
  2044.     fCreatedPS = FALSE;%@NL@%
  2045. }%@NL@%
  2046. %@NL@%
  2047. void AvioPaint(HWND hWnd) {%@NL@%
  2048. %@AB@%/*%@NL@%
  2049. %@AB@%    Paint the AVIO presentation space by telling it to show itself.%@NL@%
  2050. %@AB@%    A possible optimization here is to repaint only the update region.%@NL@%
  2051. %@AB@%*/%@AE@%%@NL@%
  2052.     static HPS         hPS;%@NL@%
  2053.     static RECTL RectL;%@NL@%
  2054. %@NL@%
  2055.     hPS = WinBeginPaint(hWnd, (HPS) NULL, &RectL);%@NL@%
  2056.     VioShowPS(cyChPS, cxChPS, 0, hVPS);%@NL@%
  2057.     WinEndPaint(hPS);%@NL@%
  2058. } %@NL@%
  2059. %@NL@%
  2060. MRESULT AvioMinMax(PSWP pSWP) {%@NL@%
  2061. %@AB@%/*%@NL@%
  2062. %@AB@%    Handle WM_MINMAX messages, to make sure frame doesn't get too big%@NL@%
  2063. %@AB@%*/%@AE@%%@NL@%
  2064.     if (pSWP->fs & (SWP_MAXIMIZE | SWP_RESTORE)) {%@NL@%
  2065.         if (pSWP->fs & SWP_MAXIMIZE) {%@NL@%
  2066.             %@AB@%/*%@NL@%
  2067. %@AB@%                Save cx, cy values for later origin displacement%@NL@%
  2068. %@AB@%            */%@AE@%%@NL@%
  2069.             int Oldcx = pSWP->cx;%@NL@%
  2070.             int Oldcy = pSWP->cy;%@NL@%
  2071.             %@AB@%/*%@NL@%
  2072. %@AB@%                Displace, and change to maximum size%@NL@%
  2073. %@AB@%            */%@AE@%%@NL@%
  2074.             pSWP->x += (Oldcx -%@NL@%
  2075.                 (pSWP->cx = cxMaxFrame + (int) (Value(SV_CXSIZEBORDER) << 1)));%@NL@%
  2076.             pSWP->y += (Oldcy -%@NL@%
  2077.                 (pSWP->cy = cyMaxFrame + (int) (Value(SV_CYSIZEBORDER) << 1)));%@NL@%
  2078.         }%@NL@%
  2079.         %@AB@%/*%@NL@%
  2080. %@AB@%            Now, fix the scroll bars%@NL@%
  2081. %@AB@%        */%@AE@%%@NL@%
  2082.         AvioAdjustFramePos(pSWP);%@NL@%
  2083.         return (MRESULT) TRUE;%@NL@%
  2084.     }%@NL@%
  2085.     return FALSE;%@NL@%
  2086. }%@NL@%
  2087. %@NL@%
  2088. void AvioClear(void) { ClearScreen(); }%@NL@%
  2089. %@NL@%
  2090. void AvioAdjustFramePos(PSWP pSWP) {%@NL@%
  2091. %@AB@%/*%@NL@%
  2092. %@AB@%    Trap WM_ADJUSTWINDOWPOS messages to the frame with this routine.%@NL@%
  2093. %@AB@%    Keep the window sized right, and control scrollbar visibility.%@NL@%
  2094. %@AB@%*/%@AE@%%@NL@%
  2095.     RECTL rclFrame;%@NL@%
  2096. %@NL@%
  2097.     if (!(pSWP->cx && pSWP->cy)) return;         %@AB@%/* Null area... */%@AE@%%@NL@%
  2098.     if (pSWP->fs & SWP_MINIMIZE) return;        %@AB@%/* Iconic... */%@AE@%%@NL@%
  2099.     %@AB@%/*%@NL@%
  2100. %@AB@%        Make sure the dimensions are in range%@NL@%
  2101. %@AB@%    */%@AE@%%@NL@%
  2102.     pSWP->cx = Min(pSWP->cx, (cxMaxFrame + (SHORT)(Value(SV_CXSIZEBORDER)<<1)));%@NL@%
  2103.     pSWP->cy = Min(pSWP->cy, (cyMaxFrame + (SHORT)(Value(SV_CYSIZEBORDER)<<1)));%@NL@%
  2104.     %@AB@%/*%@NL@%
  2105. %@AB@%        Update the scroll bars%@NL@%
  2106. %@AB@%    */%@AE@%%@NL@%
  2107.     rclFrame.xLeft        = (LONG) pSWP->x;%@NL@%
  2108.     rclFrame.xRight        = (LONG) (pSWP->x + pSWP->cx - 1);%@NL@%
  2109.     rclFrame.yBottom        = (LONG) pSWP->y;%@NL@%
  2110.     rclFrame.yTop        = (LONG) (pSWP->y + pSWP->cy - 1);%@NL@%
  2111.     UpdateScrollBars(rclFrame);%@NL@%
  2112. %@NL@%
  2113.     return; %@NL@%
  2114. }%@NL@%
  2115. %@NL@%
  2116. void AvioTrackFrame(HWND hWnd, MPARAM mpTrackFlags) {%@NL@%
  2117. %@AB@%/*%@NL@%
  2118. %@AB@%    Takes action on WM_TRACKFRAME message%@NL@%
  2119. %@AB@%*/%@AE@%%@NL@%
  2120.     static TRACKINFO tiTrackInfo;%@NL@%
  2121.     %@AB@%/*%@NL@%
  2122. %@AB@%        Get the tracking information in the TrackInfo structure%@NL@%
  2123. %@AB@%    */%@AE@%%@NL@%
  2124.     WinSendMsg(hWnd, WM_QUERYTRACKINFO, mpTrackFlags, &tiTrackInfo);%@NL@%
  2125.     WinTrackRect(hWnd, NULL, &tiTrackInfo);%@NL@%
  2126. }%@NL@%
  2127. %@NL@%
  2128. void AvioQueryTrackInfo(PTRACKINFO pTI) {%@NL@%
  2129. %@AB@%/*%@NL@%
  2130. %@AB@%    Routine which processes WM_QUERYTRACKINFO messages to the frame.%@NL@%
  2131. %@AB@%    Call this routine after the default one to change various parameters.%@NL@%
  2132. %@AB@%%@NL@%
  2133. %@AB@%    Note:  In reality, since we have a menu bar, we should make the%@NL@%
  2134. %@AB@%    minimum width of the window something such that it does not "fold."%@NL@%
  2135. %@AB@%*/%@AE@%%@NL@%
  2136.     BOOL fMove;%@NL@%
  2137.     %@AB@%/*%@NL@%
  2138. %@AB@%        Get the grid set up for byte alignment (unless moving)%@NL@%
  2139. %@AB@%%@NL@%
  2140. %@AB@%        cxGrid is set to half character width so that arrow keys%@NL@%
  2141. %@AB@%        will function when sizing (they try to size by half a%@NL@%
  2142. %@AB@%        character)%@NL@%
  2143. %@AB@%    */%@AE@%%@NL@%
  2144.     fMove = ((pTI->fs & TF_MOVE) == TF_MOVE);%@NL@%
  2145.     pTI->fs     |= TF_GRID;%@NL@%
  2146.     pTI->cxGrid  = (fMove) ? 1 : ((SHORT) lChWidth);%@NL@%
  2147.     pTI->cyGrid  = (fMove) ? 1 : ((SHORT) lChHeight);%@NL@%
  2148.     pTI->cxKeyboard        =        (SHORT) lChWidth;%@NL@%
  2149.     pTI->cyKeyboard        =        (SHORT) lChHeight;%@NL@%
  2150.     %@AB@%/*%@NL@%
  2151. %@AB@%        Bound the frame.%@NL@%
  2152. %@AB@%        Maximum:        Sizing Border, Scrollbars, Title, Menus, client region%@NL@%
  2153. %@AB@%    */%@AE@%%@NL@%
  2154.     pTI->ptlMaxTrackSize.x = (LONG) (pTI->cxBorder << 1) + (LONG) cxMaxFrame;%@NL@%
  2155.     pTI->ptlMaxTrackSize.y = (LONG) (pTI->cyBorder << 1) + (LONG) cyMaxFrame;%@NL@%
  2156. }%@NL@%
  2157. %@NL@%
  2158. void AvioRedraw(void) {%@NL@%
  2159. %@AB@%/*%@NL@%
  2160. %@AB@%    Clear, then redraw the entire Presentation Space%@NL@%
  2161. %@AB@%*/%@AE@%%@NL@%
  2162.     ClearScreen();%@NL@%
  2163.     Update(iTopLine, cyChPS, 0);%@NL@%
  2164. }%@NL@%
  2165. %@NL@%
  2166. MRESULT CALLBACK AvioClientWndProc%@NL@%
  2167.         (HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  2168. %@AB@%/*%@NL@%
  2169. %@AB@%     Window Procedure which traps messages to the Client area%@NL@%
  2170. %@AB@%*/%@AE@%%@NL@%
  2171.      switch (msg) {%@NL@%
  2172.           case WM_PAINT:                %@AB@%/* Paint the AVIO way! */%@AE@%%@NL@%
  2173.                 AvioPaint(hWnd);%@NL@%
  2174.                 break;%@NL@%
  2175. %@NL@%
  2176.           case WM_SIZE:                        %@AB@%/* Size the AVIO way!  */%@AE@%%@NL@%
  2177.                 return AvioSize(hWnd, msg, mp1, mp2);%@NL@%
  2178.                 break;%@NL@%
  2179. %@NL@%
  2180.           case WM_HSCROLL:%@NL@%
  2181.                 AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), TRUE);%@NL@%
  2182.                 break;%@NL@%
  2183. %@NL@%
  2184.           case WM_VSCROLL:%@NL@%
  2185.                 AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), FALSE);%@NL@%
  2186.                 break;%@NL@%
  2187. %@NL@%
  2188.           case WM_ERASEBACKGROUND:%@NL@%
  2189.                 break;%@NL@%
  2190. %@NL@%
  2191.           case WM_TRACKFRAME:%@NL@%
  2192.                 AvioTrackFrame(hWnd, mp1);%@NL@%
  2193.                 break;%@NL@%
  2194. %@NL@%
  2195.           case WM_MINMAXFRAME:                %@AB@%/* Limit Maximized window size */%@AE@%%@NL@%
  2196.                 AvioMinMax((PSWP) mp1);%@NL@%
  2197. %@NL@%
  2198.                 %@AB@%/* fall through */%@AE@%%@NL@%
  2199. %@NL@%
  2200.           default: return (*pfnOldClient)(hWnd, msg, mp1, mp2);%@NL@%
  2201.      }%@NL@%
  2202.      return 0;%@NL@%
  2203. }%@NL@%
  2204. %@NL@%
  2205. MRESULT CALLBACK AvioFrameWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  2206. %@AB@%/*%@NL@%
  2207. %@AB@%    Force the frame to stay small enough (no larger than the PS)%@NL@%
  2208. %@AB@%*/%@AE@%%@NL@%
  2209. {%@NL@%
  2210.     BOOL rc;                %@AB@%/* Return code from WM_QUERYTRACKINFO */%@AE@%%@NL@%
  2211. %@NL@%
  2212.     switch(msg) {%@NL@%
  2213.         case WM_ADJUSTWINDOWPOS:        %@AB@%/* Calculate scroll bar adjustments */%@AE@%%@NL@%
  2214.             AvioAdjustFramePos(mp1);%@NL@%
  2215.             break;%@NL@%
  2216. %@NL@%
  2217.         case WM_QUERYTRACKINFO:                %@AB@%/* Get default, then process message */%@AE@%%@NL@%
  2218.             rc = (BOOL) SHORT1FROMMR((*pfnOldFrame)(hWnd, msg, mp1, mp2));%@NL@%
  2219.             AvioQueryTrackInfo((PTRACKINFO) mp2);%@NL@%
  2220.             return (MRESULT) rc;%@NL@%
  2221. %@NL@%
  2222.         default: break;%@NL@%
  2223.     }%@NL@%
  2224.     return (*pfnOldFrame)(hWnd, msg, mp1, mp2);%@NL@%
  2225. }%@NL@%
  2226. %@NL@%
  2227. void UpdateScrollBars(RECTL rclClient) {%@NL@%
  2228. %@AB@%/*%@NL@%
  2229. %@AB@%    This routine fixes up the scroll bars when the window is resized, or%@NL@%
  2230. %@AB@%    when the font size is changed.%@NL@%
  2231. %@AB@%%@NL@%
  2232. %@AB@%    Parameters:        The dimensions of the frame window%@NL@%
  2233. %@AB@%    Result:        Updates the scrollbars, enabling/disabling as needed%@NL@%
  2234. %@AB@%*/%@AE@%%@NL@%
  2235.     BOOL    fNeededHorz = fNeedHorz;  %@AB@%/* Did we need the scrollbars then? */%@AE@%%@NL@%
  2236.     BOOL    fNeededVert = fNeedVert;%@NL@%
  2237.     %@AB@%/*%@NL@%
  2238. %@AB@%        Compute the client rectangle, without the scrollbars%@NL@%
  2239. %@AB@%    */%@AE@%%@NL@%
  2240.     WinCalcFrameRect(hWndFrame, &rclClient, TRUE);%@NL@%
  2241.     %@AB@%/*%@NL@%
  2242. %@AB@%        Compute page width -- do we need the horizontal scroll bar?%@NL@%
  2243. %@AB@%    */%@AE@%%@NL@%
  2244.     cxChPage         = (int) CalcChars(lcx(rclClient), lChWidth);%@NL@%
  2245.     fNeedHorz = ((iMaxHorz = Max(cxChScreen - cxChPage,  0)) > 0);%@NL@%
  2246.     %@AB@%/*%@NL@%
  2247. %@AB@%        Compute page height -- do we need the vertical scroll bar?%@NL@%
  2248. %@AB@%    */%@AE@%%@NL@%
  2249.     cyChPage         = (int) CalcChars(lcy(rclClient), lChHeight);%@NL@%
  2250.     fNeedVert = ((iMaxVert = Max(cyChScreen - cyChPage, 0)) > 0);%@NL@%
  2251.     %@AB@%/*%@NL@%
  2252. %@AB@%        Maintain scrollbar integrity%@NL@%
  2253. %@AB@%    */%@AE@%%@NL@%
  2254.     iCurCol        = Min(iCurCol, iMaxHorz);%@NL@%
  2255.     iTopLine        = Min(iTopLine, iMaxVert);%@NL@%
  2256.     %@AB@%/*%@NL@%
  2257. %@AB@%        Now, update the scrollbars as necessary%@NL@%
  2258. %@AB@%    */%@AE@%%@NL@%
  2259.     FixScroll(fNeededHorz, fNeedHorz, hWndHorzSB,%@NL@%
  2260.               FCF_HORZSCROLL, &iCurCol, iMaxHorz, &cHUpdate);%@NL@%
  2261. %@NL@%
  2262.     FixScroll(fNeededVert, fNeedVert, hWndVertSB,%@NL@%
  2263.               FCF_VERTSCROLL, &iTopLine, iMaxVert, &cVUpdate);%@NL@%
  2264.     %@AB@%/*%@NL@%
  2265. %@AB@%        Now, update the screen to be visually consistent%@NL@%
  2266. %@AB@%    */%@AE@%%@NL@%
  2267.     Refresh();%@NL@%
  2268. }%@NL@%
  2269. %@NL@%
  2270. void FixScroll(fNeeded, fNeed, hWnd, flScroll, piPos, iMax, pc)%@NL@%
  2271. %@AB@%/*%@NL@%
  2272. %@AB@%    This routine makes the necessary scrollbar adjustments, and%@NL@%
  2273. %@AB@%    also enables/disables them.%@NL@%
  2274. %@AB@%*/%@AE@%%@NL@%
  2275. BOOL        fNeeded;            %@AB@%/* Whether we used to need the scrollbar */%@AE@%%@NL@%
  2276. BOOL        fNeed;                    %@AB@%/* Whether we need the scrollbar now */%@AE@%%@NL@%
  2277. HWND        hWnd;                    %@AB@%/* Handle to the scrollbar window */%@AE@%%@NL@%
  2278. ULONG        flScroll;            %@AB@%/* FCF_xxxxSCROLL flag (for the scrollbar) */%@AE@%%@NL@%
  2279. int        *piPos;             %@AB@%/* Current location of scrollbar thumb */%@AE@%%@NL@%
  2280. int        iMax;                    %@AB@%/* New maximum for the scrollbar */%@AE@%%@NL@%
  2281. int        *pc;                    %@AB@%/* Counter for WinEnableWindowUpdate recursion */%@AE@%%@NL@%
  2282. {%@NL@%
  2283.     if (fNeed) {    %@AB@%/* Enable the scroll bar -- we didn't need it before */%@AE@%%@NL@%
  2284.         if (!fNeeded) {%@NL@%
  2285.             EnableSB(hWnd);%@NL@%
  2286.             UpdateOff((*pc), hWnd);%@NL@%
  2287.             UpdateFrame(flScroll);%@NL@%
  2288.             UpdateOn((*pc), hWnd);%@NL@%
  2289.         }%@NL@%
  2290.         SetScroll(hWnd, (*piPos) = Min((*piPos), iMax), iMax);%@NL@%
  2291.     } else {            %@AB@%/* Disable the scroll bar, we no longer need it */%@AE@%%@NL@%
  2292.         if (fNeeded) {%@NL@%
  2293.             DisableSB(hWnd);%@NL@%
  2294.             UpdateOff((*pc), hWnd);%@NL@%
  2295.             UpdateFrame(flScroll);%@NL@%
  2296.             UpdateOn((*pc), hWnd);%@NL@%
  2297.         }%@NL@%
  2298.     }%@NL@%
  2299. }%@NL@%
  2300. %@NL@%
  2301. void AvioLargeFont(BOOL fLargeFont) {%@NL@%
  2302.     static BOOL fFirst = TRUE;                                    // Need to init?%@NL@%
  2303.     static LONG lSmallHt, lSmallWd, lLargeHt, lLargeWd;     // Font sizes%@NL@%
  2304.     SWP swp;%@NL@%
  2305. %@NL@%
  2306.     if (fFirst) {%@NL@%
  2307.         %@AB@%/*%@NL@%
  2308. %@AB@%            The first time through, get the small and large font sizes%@NL@%
  2309. %@AB@%        */%@AE@%%@NL@%
  2310.         DevQueryCaps(hDC, CAPS_CHAR_HEIGHT,                1L, &lLargeHt);%@NL@%
  2311.         DevQueryCaps(hDC, CAPS_CHAR_WIDTH,                1L, &lLargeWd);%@NL@%
  2312.         DevQueryCaps(hDC, CAPS_SMALL_CHAR_HEIGHT,        1L, &lSmallHt);%@NL@%
  2313.         DevQueryCaps(hDC, CAPS_SMALL_CHAR_WIDTH,        1L, &lSmallWd);%@NL@%
  2314.         fFirst = FALSE;%@NL@%
  2315.     }%@NL@%
  2316.     %@AB@%/*%@NL@%
  2317. %@AB@%        Set the character size with VioSetDeviceCellSize%@NL@%
  2318. %@AB@%    */%@AE@%%@NL@%
  2319.     SetCellSize( (SHORT) (lChHeight = ((fLargeFont) ? lLargeHt : lSmallHt)),%@NL@%
  2320.                  (SHORT) (lChWidth  = ((fLargeFont) ? lLargeWd : lSmallWd)) );%@NL@%
  2321.     %@AB@%/*%@NL@%
  2322. %@AB@%        Compute maximum size of client area%@NL@%
  2323. %@AB@%    */%@AE@%%@NL@%
  2324.     cxMaxClient        = (cxChPS * (SHORT) lChWidth);%@NL@%
  2325.     cxMaxFrame        = cxMaxClient + (SHORT) cxConstant;%@NL@%
  2326.     cyMaxClient = (cyChPS * (SHORT) lChHeight);%@NL@%
  2327.     cyMaxFrame  = cyMaxClient + (SHORT) cyConstant;%@NL@%
  2328.     %@AB@%/*%@NL@%
  2329. %@AB@%        Send a WM_ADJUSTFRAMEPOS message%@NL@%
  2330. %@AB@%    */%@AE@%%@NL@%
  2331.     WinQueryWindowPos(hWndFrame, &swp);%@NL@%
  2332.     if (swp.fs & SWP_MAXIMIZE) {%@NL@%
  2333.         AvioMinMax(&swp);%@NL@%
  2334.         WinSetMultWindowPos(hWndFrame, &swp, 1);%@NL@%
  2335.     } else {%@NL@%
  2336.         swp.fs = SWP_ACTIVATE | SWP_MOVE | SWP_SHOW | SWP_SIZE;%@NL@%
  2337.         WinSetWindowPos(hWndFrame, NULL, swp.x, swp.y,%@NL@%
  2338.             Min(cxMaxFrame, swp.cx), Min(cyMaxFrame, swp.cy), swp.fs);%@NL@%
  2339.     }%@NL@%
  2340.     AvioAdjustFramePos(&swp);                %@AB@%/* Fix up the frame, scroll bars */%@AE@%%@NL@%
  2341.     AvioPaint(hWndClient);                %@AB@%/* Repaint with new characters   */%@AE@%%@NL@%
  2342. }%@NL@%
  2343. %@NL@%
  2344. %@NL@%
  2345. %@2@%%@AH@%AVIO.C%@AE@%%@EH@%%@NL@%
  2346. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\AVIO.C%@AE@%%@NL@%
  2347. %@NL@%
  2348. %@AB@%/*%@NL@%
  2349. %@AB@%        avio.c -- AVIO handling routines%@NL@%
  2350. %@AB@%        For a cleaner implementation, look at the BROWSE application.%@NL@%
  2351. %@AB@%%@NL@%
  2352. %@AB@%        Implements scrollbars, sets up an AVIO Presentation Space%@NL@%
  2353. %@AB@%        Intrinsically linked with a circular queue routine%@NL@%
  2354. %@AB@%%@NL@%
  2355. %@AB@%        Created by Microsoft Corporation, 1989%@NL@%
  2356. %@AB@%*/%@AE@%%@NL@%
  2357. %@NL@%
  2358. %@AI@%#define %@AE@% INCL_AVIO %@NL@%
  2359. %@AI@%#define %@AE@%        INCL_DEV %@NL@%
  2360. %@AI@%#define %@AE@% INCL_VIO %@NL@%
  2361. %@AI@%#define %@AE@%        INCL_WIN %@NL@%
  2362. %@AI@%#include %@AE@%<os2.h> %@NL@%
  2363. %@AI@%#include %@AE@%"global.h" %@NL@%
  2364. "circleq.h"        %@AB@%/* Get Circular Buffer routines */%@AE@%%@NL@%
  2365. "avio.h"        %@AB@%/* Prototype our routines */%@AE@%%@NL@%
  2366. <stdio.h>        %@AB@%/* Needed to open LOG file */%@AE@%%@NL@%
  2367. %@AB@%/*%@NL@%
  2368. %@AB@%    Constants%@NL@%
  2369. %@AB@%*/%@AE@%%@NL@%
  2370. AVIO_PS_ROWS        25        %@AB@%/* Dimensions of the AVIO PS */%@AE@%%@NL@%
  2371. %@AI@%#define %@AE@%AVIO_PS_COLUMNS        MAXLINELEN %@NL@%
  2372.        CATTRBYTES        1        %@AB@%/* 1 or 3 attribute bytes/cell */%@AE@%%@NL@%
  2373.        DEFPAGEWIDTH        5        %@AB@%/* Default pagesizes */%@AE@%%@NL@%
  2374. %@AI@%#define %@AE@%       DEFPAGEHEIGHT        5 %@NL@%
  2375. %@NL@%
  2376. char        Blank[2] = { 0x20, 0x07 };%@NL@%
  2377. %@NL@%
  2378. %@AB@%/*%@NL@%
  2379. %@AB@%    Macros to make the code more readable%@NL@%
  2380. %@AB@%*/%@AE@%%@NL@%
  2381. %@AB@%/* Upper and Lower Bound Calculations */%@AE@%%@NL@%
  2382. %@AI@%#define %@AE@%       Abs(a)                (((a) > 0) ? (a) : (-(a))) %@NL@%
  2383. %@AI@%#define %@AE@%LowerBound(pos, disp, lbound) Max(pos - disp, lbound) %@NL@%
  2384. %@AI@%#define %@AE@%UpperBound(pos, disp, ubound) Min(pos + disp, ubound) %@NL@%
  2385. %@NL@%
  2386. %@AB@%/* Scroll Bar Abbreviations */%@AE@%%@NL@%
  2387. %@NL@%
  2388. %@AI@%#define %@AE@%       DisableSB(hSB)        WinSetParent(hSB,  HWND_OBJECT, FALSE) %@NL@%
  2389. %@AI@%#define %@AE@%       EnableSB(hSB)        WinSetParent(hSB, hWndSBParent, FALSE) %@NL@%
  2390. %@AI@%#define %@AE@%       HBarHeight()        (fNeedHorz ? lHSBHeight : 0L) %@NL@%
  2391. %@AI@%#define %@AE@%       VBarWidth()        (fNeedVert ? lVSBWidth  : 0L) %@NL@%
  2392. %@AI@%#define %@AE@%SetScroll(h, pos, max) \ %@NL@%
  2393.     WinSendMsg(h, SBM_SETSCROLLBAR, MPFROM2SHORT(pos, 0), MPFROM2SHORT(0, max))%@NL@%
  2394. %@AI@%#define %@AE@%       UpdateFrame(sb)        \ %@NL@%
  2395.     WinSendMsg(hWndSBParent, WM_UPDATEFRAME, MPFROMLONG(sb), 0L)%@NL@%
  2396. %@AI@%#define %@AE@%       UpdateOff(w)        WinEnableWindowUpdate(w, FALSE) %@NL@%
  2397. %@AI@%#define %@AE@%       UpdateOn(w)        WinEnableWindowUpdate(w, TRUE) %@NL@%
  2398. %@NL@%
  2399. %@AB@%/* Scrolling Macros */%@AE@%%@NL@%
  2400. %@AI@%#define %@AE@%       ClearScreen()        ScrollUp(-1) %@NL@%
  2401. %@AI@%#define %@AE@%ScrollDown(n)        VioScrollDn(0, 0, -1, -1, n, Blank, hVPS) %@NL@%
  2402. %@AI@%#define %@AE@%       ScrollUp(n)        VioScrollUp(0, 0, -1, -1, n, Blank, hVPS) %@NL@%
  2403. %@AI@%#define %@AE@%       SetCursor(x, y)        VioSetCurPos((USHORT) x, (USHORT) y, hVPS) %@NL@%
  2404. %@NL@%
  2405. %@AB@%/* Miscellaneous */%@AE@%%@NL@%
  2406. %@AB@%/*%@NL@%
  2407. %@AB@%    If partial ANSI emulation is desired, use:%@NL@%
  2408. %@AB@%        VioSetCurPos((USHORT) x, (USHORT) y, hVPS); \%@NL@%
  2409. %@AB@%        VioWrtTTY(l->szText, l->cch, hVPS)%@NL@%
  2410. %@AB@%*/%@AE@%%@NL@%
  2411. %@AI@%#define %@AE@%Blast(l, x, y)        VioWrtCharStr(l->szText, l->cch, x, y, hVPS) %@NL@%
  2412. %@AB@%/*%@NL@%
  2413. %@AB@%    Calculate the number of characters in a page%@NL@%
  2414. %@AB@%    For nicer behavior, you can do rounding here%@NL@%
  2415. %@AB@%*/%@AE@%%@NL@%
  2416. %@AI@%#define %@AE@%CalcChars(pPg, pCh, default) \ %@NL@%
  2417.         ((pCh) ? (Max((int) ((pPg) / ((SHORT) pCh)), 0)) : (default))%@NL@%
  2418. %@AI@%#define %@AE@%       Value(value)        WinQuerySysValue(HWND_DESKTOP, value) %@NL@%
  2419. %@AB@%/*%@NL@%
  2420. %@AB@%    File-Local Variables%@NL@%
  2421. %@AB@%*/%@AE@%%@NL@%
  2422. HDC        hDC;                %@AB@%/* Device Context */%@AE@%%@NL@%
  2423. HVPS        hVPS;                %@AB@%/* Virtual PS */%@AE@%%@NL@%
  2424. int        iTopLine;        %@AB@%/* PS Line of window corner */%@AE@%%@NL@%
  2425. int        iCurCol;         %@AB@%/* Current column of window corner */%@AE@%%@NL@%
  2426. int        cchPgWidth;        %@AB@%/* Width and height of our window */%@AE@%%@NL@%
  2427. int        cchPgHeight;%@NL@%
  2428. int        cchMaxHorz;        %@AB@%/* Scroll bar upper bounds */%@AE@%%@NL@%
  2429. int        cchMaxVert;        %@NL@%
  2430. BOOL        fNeedHorz;        %@AB@%/* Do we need the scroll bars or not? */%@AE@%%@NL@%
  2431. BOOL        fNeedVert;%@NL@%
  2432. HWND        hWndHScroll;        %@AB@%/* Window handles of ScrollBar windows */%@AE@%%@NL@%
  2433. HWND        hWndVScroll;%@NL@%
  2434. HWND        hWndSBParent;        %@AB@%/* Could mooch off the value in main(), but won't */%@AE@%%@NL@%
  2435. %@AB@%/*%@NL@%
  2436. %@AB@%    Measurements used to help make the window look nice%@NL@%
  2437. %@AB@%*/%@AE@%%@NL@%
  2438. LONG        lChWidth,   lChHeight;                        %@AB@%/* Character size */%@AE@%%@NL@%
  2439. LONG        lHSBHeight, lVSBWidth;                        %@AB@%/* Scrollbar measurements */%@AE@%%@NL@%
  2440. LONG        lMiscWidth, lMiscHeight;                %@AB@%/* Border, titlebar, ... */%@AE@%%@NL@%
  2441. int        iMaxWidth,  iMaxHeight;                        %@AB@%/* Client area bounds  */%@AE@%%@NL@%
  2442. int        iMaxFrameWidth, iMaxFrameHeight;        %@AB@%/* Frame window bounds */%@AE@%%@NL@%
  2443. BOOL        fCreated;                                %@AB@%/* AVIO PS created */%@AE@%%@NL@%
  2444. int        rc;                                        %@AB@%/* Return code */%@AE@%%@NL@%
  2445. VIOCURSORINFO vci;%@NL@%
  2446. %@AB@%/*%@NL@%
  2447. %@AB@%   Local prototypes%@NL@%
  2448. %@AB@%*/%@AE@%%@NL@%
  2449. void GetMeasurements(void);%@NL@%
  2450. void Update(USHORT, USHORT, USHORT, BOOL);%@NL@%
  2451. void Refresh(BOOL);%@NL@%
  2452. void WantCursor(BOOL);%@NL@%
  2453. void SetScrollPos(void);%@NL@%
  2454. void SetScrollPosHorz(void);%@NL@%
  2455. void SetScrollPosVert(void);%@NL@%
  2456. %@AB@%/*%@NL@%
  2457. %@AB@%    The actual routines%@NL@%
  2458. %@AB@%*/%@AE@%%@NL@%
  2459. void GetMeasurements(void) {%@NL@%
  2460. %@AB@%/*%@NL@%
  2461. %@AB@%    Get display parameters%@NL@%
  2462. %@AB@%*/%@AE@%%@NL@%
  2463.     %@AB@%/*%@NL@%
  2464. %@AB@%        Scroll bar widths and heights%@NL@%
  2465. %@AB@%    */%@AE@%%@NL@%
  2466.     lHSBHeight        = Value(SV_CYHSCROLL);%@NL@%
  2467.     lVSBWidth        = Value(SV_CXVSCROLL);%@NL@%
  2468.     %@AB@%/*%@NL@%
  2469. %@AB@%        Non-PS widths and heights%@NL@%
  2470. %@AB@%    */%@AE@%%@NL@%
  2471.     lMiscHeight        = (Value(SV_CYSIZEBORDER) << 1)        %@AB@%/* A border on each side */%@AE@%%@NL@%
  2472.                 + Value(SV_CYTITLEBAR)                %@AB@%/* The title bar...      */%@AE@%%@NL@%
  2473.                 + Value(SV_CYMENU)                %@AB@%/* ...and the menu bar   */%@AE@%%@NL@%
  2474.                 + Value(SV_CYBYTEALIGN);        %@AB@%/* ...and alignment         */%@AE@%%@NL@%
  2475.                 %@NL@%
  2476.     lMiscWidth        = (Value(SV_CXSIZEBORDER) << 1);%@AB@%/* A border on each side */%@AE@%%@NL@%
  2477.     %@AB@%/*%@NL@%
  2478. %@AB@%        Height and width of characters%@NL@%
  2479. %@AB@%    */%@AE@%%@NL@%
  2480.     rc = DevQueryCaps(hDC, CAPS_CHAR_HEIGHT, 1L, &lChHeight);%@NL@%
  2481.     rc = DevQueryCaps(hDC, CAPS_CHAR_WIDTH,  1L, &lChWidth);%@NL@%
  2482.     %@AB@%/*%@NL@%
  2483. %@AB@%        Compute size of client and frame windows%@NL@%
  2484. %@AB@%    */%@AE@%%@NL@%
  2485.     iMaxWidth                = (AVIO_PS_COLUMNS        * (int) lChWidth);%@NL@%
  2486.     iMaxHeight                = (AVIO_PS_ROWS                * (int) lChHeight);%@NL@%
  2487.     iMaxFrameWidth        = (iMaxWidth                + (int) lMiscWidth);%@NL@%
  2488.     iMaxFrameHeight        = (iMaxHeight                + (int) lMiscHeight);%@NL@%
  2489.     %@AB@%/*%@NL@%
  2490. %@AB@%        Compute cursor attributes%@NL@%
  2491. %@AB@%    */%@AE@%%@NL@%
  2492.     vci.yStart        = (USHORT) 0;%@NL@%
  2493.     vci.cEnd        = (USHORT) lChHeight - 1;%@NL@%
  2494.     vci.cx        = 0;%@NL@%
  2495. }%@NL@%
  2496. %@NL@%
  2497. void AvioInit(HWND hWndFrame, HWND hWndClient) {%@NL@%
  2498. %@AB@%/*%@NL@%
  2499. %@AB@%    Initialize Presentation Space, Device Context, Scroll Bars%@NL@%
  2500. %@AB@%*/%@AE@%%@NL@%
  2501.     %@AB@%/*%@NL@%
  2502. %@AB@%        Create the AVIO Presentation Space%@NL@%
  2503. %@AB@%    */%@AE@%%@NL@%
  2504.     hDC = WinOpenWindowDC(hWndClient);%@NL@%
  2505.     VioCreatePS(&hVPS, AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, CATTRBYTES, 0);%@NL@%
  2506.     VioAssociate(hDC, hVPS);%@NL@%
  2507.     fCreated = TRUE;%@NL@%
  2508.     %@AB@%/*%@NL@%
  2509. %@AB@%        Turn on the cursor and home it%@NL@%
  2510. %@AB@%    */%@AE@%%@NL@%
  2511.     WantCursor(TRUE);%@NL@%
  2512.     SetCursor(0, 0);%@NL@%
  2513.     %@AB@%/*%@NL@%
  2514. %@AB@%        Snag scroll bar info%@NL@%
  2515. %@AB@%    */%@AE@%%@NL@%
  2516.     hWndHScroll  = WinWindowFromID(hWndFrame,  FID_HORZSCROLL);%@NL@%
  2517.     hWndVScroll  = WinWindowFromID(hWndFrame,  FID_VERTSCROLL);%@NL@%
  2518.     hWndSBParent = WinQueryWindow(hWndHScroll, QW_PARENT, FALSE);%@NL@%
  2519.     fNeedHorz         = fNeedVert  = TRUE;%@NL@%
  2520.     %@AB@%/*%@NL@%
  2521. %@AB@%        Get character height in pixels, etc...%@NL@%
  2522. %@AB@%    */%@AE@%%@NL@%
  2523.     GetMeasurements();%@NL@%
  2524. }%@NL@%
  2525. %@NL@%
  2526. void AvioStartup(HWND hWndClient) {%@NL@%
  2527.     SWP swp;%@NL@%
  2528.     %@AB@%/*%@NL@%
  2529. %@AB@%        Initialize the queue%@NL@%
  2530. %@AB@%    */%@AE@%%@NL@%
  2531.     QueInit();%@NL@%
  2532.     %@AB@%/*%@NL@%
  2533. %@AB@%        Initialize the screen%@NL@%
  2534. %@AB@%    */%@AE@%%@NL@%
  2535.     ClearScreen();%@NL@%
  2536.     WinQueryWindowPos(hWndClient, &swp);%@NL@%
  2537.     AvioSize(hWndClient, WM_NULL, NULL, MPFROM2SHORT(swp.cx, swp.cy));%@NL@%
  2538. }%@NL@%
  2539. %@NL@%
  2540. void AvioScroll(USHORT SB_Command, USHORT usPosition, BOOL fHorizontal) {%@NL@%
  2541. %@AB@%/*%@NL@%
  2542. %@AB@%    Process the scroll bar messages%@NL@%
  2543. %@AB@%%@NL@%
  2544. %@AB@%    These routines are symmetric; in fact, SB_LINELEFT = SB_LINEUP, etc...%@NL@%
  2545. %@AB@%    so one might note that this could be condensed.  It's left expanded for%@NL@%
  2546. %@AB@%    speed and clarity.  I bound the values each way so that we stay inside%@NL@%
  2547. %@AB@%    the AVIO presentation space.%@NL@%
  2548. %@AB@%*/%@AE@%%@NL@%
  2549.     if (fHorizontal) {  %@AB@%/* Horizontal Scroll Bar */%@AE@%%@NL@%
  2550.         switch (SB_Command) {%@NL@%
  2551.             case SB_LINELEFT:%@NL@%
  2552.                 iCurCol = LowerBound(iCurCol, 1, 0); break;%@NL@%
  2553.             case SB_LINERIGHT:%@NL@%
  2554.                 iCurCol = UpperBound(iCurCol, 1, cchMaxHorz); break;%@NL@%
  2555.             case SB_PAGELEFT:%@NL@%
  2556.                 iCurCol = LowerBound(iCurCol, cchPgWidth, 0); break;%@NL@%
  2557.             case SB_PAGERIGHT:%@NL@%
  2558.                 iCurCol = UpperBound(iCurCol, cchPgWidth, cchMaxHorz); break;%@NL@%
  2559.             case SB_SLIDERTRACK:%@NL@%
  2560.                 iCurCol = (SHORT) usPosition;%@NL@%
  2561.             default: break;%@NL@%
  2562.         }%@NL@%
  2563.         if (SB_Command != SB_SLIDERTRACK)%@NL@%
  2564.             SetScroll(hWndHScroll, iCurCol, cchMaxHorz);%@NL@%
  2565. %@NL@%
  2566.     } else { %@AB@%/* Vertical Scroll Bar */%@AE@%%@NL@%
  2567.         switch (SB_Command) {%@NL@%
  2568.             case SB_LINEUP:%@NL@%
  2569.                 iTopLine = LowerBound(iTopLine, 1, 0); break;%@NL@%
  2570.             case SB_LINEDOWN:%@NL@%
  2571.                 iTopLine = UpperBound(iTopLine, 1, cchMaxVert); break;%@NL@%
  2572.             case SB_PAGEUP:%@NL@%
  2573.                 iTopLine = LowerBound(iTopLine, cchPgHeight, 0); break;%@NL@%
  2574.             case SB_PAGEDOWN:%@NL@%
  2575.                 iTopLine = UpperBound(iTopLine, cchPgHeight, cchMaxVert); break;%@NL@%
  2576.             case SB_SLIDERTRACK:%@NL@%
  2577.                 iTopLine = (SHORT) usPosition;%@NL@%
  2578.             default: break;%@NL@%
  2579.         }%@NL@%
  2580.         if (SB_Command != SB_SLIDERTRACK)%@NL@%
  2581.             SetScroll(hWndVScroll, iTopLine, cchMaxVert);%@NL@%
  2582.     }%@NL@%
  2583.     Refresh(FALSE);%@NL@%
  2584. }%@NL@%
  2585. %@NL@%
  2586. MRESULT AvioSize(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  2587. %@AB@%/*%@NL@%
  2588. %@AB@%    Do the default AVIO sizing, and kyfe a few values%@NL@%
  2589. %@AB@%*/%@AE@%%@NL@%
  2590.     if (!fCreated) return 0L;%@NL@%
  2591.     %@AB@%/*%@NL@%
  2592. %@AB@%        Compute height and width of page in characters%@NL@%
  2593. %@AB@%%@NL@%
  2594. %@AB@%        The scrollbars have already been subtracted out,%@NL@%
  2595. %@AB@%        since we are called by the client area.%@NL@%
  2596. %@AB@%    */%@AE@%%@NL@%
  2597.     cchPgHeight = CalcChars(SHORT2FROMMP(mp2), lChHeight, DEFPAGEHEIGHT); %@NL@%
  2598.     cchPgWidth  = CalcChars(SHORT1FROMMP(mp2), lChWidth,  DEFPAGEWIDTH);%@NL@%
  2599.     %@AB@%/*%@NL@%
  2600. %@AB@%        Adjust scrollbar maximums%@NL@%
  2601. %@AB@%    */%@AE@%%@NL@%
  2602.     cchMaxVert = Max(AVIO_PS_ROWS    - cchPgHeight, 0);%@NL@%
  2603.     cchMaxHorz = Max(AVIO_PS_COLUMNS -  cchPgWidth, 0);%@NL@%
  2604.     %@AB@%/*%@NL@%
  2605. %@AB@%        Maintain scrollbar integrity%@NL@%
  2606. %@AB@%    */%@AE@%%@NL@%
  2607.     fNeedHorz = (cchMaxHorz > 0);%@NL@%
  2608.     fNeedVert = (cchMaxVert > 0);%@NL@%
  2609.     SetScroll(hWndHScroll, iCurCol  = Min(iCurCol, cchMaxHorz), cchMaxHorz);%@NL@%
  2610.     SetScroll(hWndVScroll, iTopLine = Min(iTopLine,cchMaxVert), cchMaxVert);%@NL@%
  2611.     %@AB@%/*%@NL@%
  2612. %@AB@%        Do the Scroll Bar shifting%@NL@%
  2613. %@AB@%    */%@AE@%%@NL@%
  2614.     Refresh(FALSE);%@NL@%
  2615.     %@AB@%/*%@NL@%
  2616. %@AB@%        Now, do the normal AVIO processing%@NL@%
  2617. %@AB@%    */%@AE@%%@NL@%
  2618.     return WinDefAVioWindowProc(hWnd, msg, mp1, mp2);%@NL@%
  2619. }%@NL@%
  2620. %@NL@%
  2621. void Update%@NL@%
  2622.     (USHORT usLineNum, USHORT usHowMany, USHORT usStartLine, BOOL fForced) {%@NL@%
  2623. %@AB@%/*%@NL@%
  2624. %@AB@%    Updates usHowMany lines starting from usStartLine on screen.%@NL@%
  2625. %@AB@%    Starts at saved line usLineNum.  If fForced is set, all lines%@NL@%
  2626. %@AB@%    in range are displayed; otherwise it's lazy.%@NL@%
  2627. %@AB@%*/%@AE@%%@NL@%
  2628.     USHORT        i;                                %@AB@%/* Loop index */%@AE@%%@NL@%
  2629.     USHORT        usWhichLine = usLineNum;        %@AB@%/* Line to be queried */%@AE@%%@NL@%
  2630.     Line        l;                                %@AB@%/* Line to be output */%@AE@%%@NL@%
  2631. %@NL@%
  2632.     for (i = usStartLine; i < (usStartLine + usHowMany); i++) {%@NL@%
  2633.         l = QueQuery(usWhichLine++);                %@AB@%/* Get the line */%@AE@%%@NL@%
  2634.         if (!l->fDrawn || fForced) {%@NL@%
  2635.             if (l->cch) Blast(l, i, 0);                %@AB@%/* Print it out */%@AE@%%@NL@%
  2636.             if (!l->fComplete) SetCursor(i, l->cch);%@NL@%
  2637.             l->fDrawn = TRUE;%@NL@%
  2638.         }%@NL@%
  2639.     }%@NL@%
  2640. }%@NL@%
  2641. %@NL@%
  2642. void Refresh(BOOL fRedraw) {%@NL@%
  2643. %@AB@%/*%@NL@%
  2644. %@AB@%    fRedraw forces full redraw if set %@NL@%
  2645. %@AB@%*/%@AE@%%@NL@%
  2646.     SHORT  sDelta;%@NL@%
  2647.     int static iOldTopLine = -AVIO_PS_ROWS;%@NL@%
  2648. %@NL@%
  2649.     VioSetOrg(0, iCurCol, hVPS); %@AB@%/* Get the free AVIO horizontal shift */%@AE@%%@NL@%
  2650.     sDelta = iTopLine - iOldTopLine; %@AB@%/* Compute vertical shift */%@AE@%%@NL@%
  2651.     if ((Abs(sDelta) < AVIO_PS_ROWS) && !fRedraw) {%@NL@%
  2652.         if (sDelta < 0) {         %@AB@%/* Scroll Up -- make sDelta positive*/%@AE@%%@NL@%
  2653.             ScrollDown(-sDelta);%@NL@%
  2654.             Update(iTopLine, -sDelta, 0, TRUE);%@NL@%
  2655.         } else {                %@AB@%/* Scroll Down by sDelta */%@AE@%%@NL@%
  2656.             ScrollUp(sDelta);%@NL@%
  2657.             Update(iTopLine + cchPgHeight - sDelta, sDelta,%@NL@%
  2658.                                 cchPgHeight - sDelta, TRUE);%@NL@%
  2659.         }%@NL@%
  2660.     } else AvioRedraw();        %@AB@%/* Redo the entire screen */%@AE@%%@NL@%
  2661.     iOldTopLine = iTopLine;%@NL@%
  2662. }%@NL@%
  2663. %@NL@%
  2664. void AvioClose (void) {%@NL@%
  2665. %@AB@%/*%@NL@%
  2666. %@AB@%    Termination routines%@NL@%
  2667. %@AB@%*/%@AE@%%@NL@%
  2668.     %@AB@%/*%@NL@%
  2669. %@AB@%        Destroy the Presentation Space%@NL@%
  2670. %@AB@%    */%@AE@%%@NL@%
  2671.     VioAssociate(NULL, hVPS);%@NL@%
  2672.     VioDestroyPS(hVPS);%@NL@%
  2673.     fCreated = FALSE;%@NL@%
  2674. }%@NL@%
  2675. %@NL@%
  2676. void AvioPaint(HWND hWnd) {%@NL@%
  2677.     static HPS   hPS;%@NL@%
  2678.     static RECTL rcl;%@NL@%
  2679. %@NL@%
  2680.     hPS = WinBeginPaint(hWnd, NULL, &rcl);%@NL@%
  2681.     VioShowPS(AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, hVPS);%@NL@%
  2682.     WinEndPaint(hPS);%@NL@%
  2683. } %@NL@%
  2684. %@NL@%
  2685. MRESULT AvioMinMax(PSWP pSWP) {%@NL@%
  2686. %@AB@%/*%@NL@%
  2687. %@AB@%    Control Maximizing%@NL@%
  2688. %@AB@%*/%@AE@%%@NL@%
  2689.     if (pSWP->fs & (SWP_MAXIMIZE | SWP_RESTORE)) {%@NL@%
  2690.         if (pSWP->fs & SWP_MAXIMIZE) {%@NL@%
  2691.             %@AB@%/*%@NL@%
  2692. %@AB@%                Save cx, cy values for later origin displacement%@NL@%
  2693. %@AB@%            */%@AE@%%@NL@%
  2694.             int iOldcx = pSWP->cx;%@NL@%
  2695.             int iOldcy = pSWP->cy;%@NL@%
  2696.             %@AB@%/*%@NL@%
  2697. %@AB@%                Displace, and change to maximum size%@NL@%
  2698. %@AB@%            */%@AE@%%@NL@%
  2699.             pSWP->x += (iOldcx - (pSWP->cx = iMaxFrameWidth));%@NL@%
  2700.             pSWP->y += (iOldcy - (pSWP->cy = iMaxFrameHeight));%@NL@%
  2701.         }%@NL@%
  2702.         %@AB@%/*%@NL@%
  2703. %@AB@%            Now, fix the scroll bars%@NL@%
  2704. %@AB@%        */%@AE@%%@NL@%
  2705.         AvioAdjustFrame(pSWP);%@NL@%
  2706.         return (MRESULT) TRUE;%@NL@%
  2707.     }%@NL@%
  2708.     return FALSE;%@NL@%
  2709. }%@NL@%
  2710. %@NL@%
  2711. void AvioClear(void) { ClearScreen(); }%@NL@%
  2712. %@NL@%
  2713. void AvioAdjustFrame(PSWP pSWP) {%@NL@%
  2714. %@AB@%/*%@NL@%
  2715. %@AB@%    Trap WM_ADJUSTWINDOWPOS messages to the frame with this routine.%@NL@%
  2716. %@AB@%    Keep the window sized right, and control scrollbar visibility.%@NL@%
  2717. %@AB@%*/%@AE@%%@NL@%
  2718.     BOOL fNeededHorz = fNeedHorz;%@NL@%
  2719.     BOOL fNeededVert = fNeedVert;%@NL@%
  2720. %@AB@%/*%@NL@%
  2721. %@AB@%    Do scrollbar enable/disable calculations (but don't update the screen)%@NL@%
  2722. %@AB@%*/%@AE@%%@NL@%
  2723.     if (pSWP->fs & SWP_MINIMIZE) fNeedHorz = fNeedVert = FALSE;%@NL@%
  2724.     if ((pSWP->cx * pSWP->cy) == 0) return;%@NL@%
  2725.     %@AB@%/*%@NL@%
  2726. %@AB@%        Do we need them?%@NL@%
  2727. %@AB@%    */%@AE@%%@NL@%
  2728.     fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight));%@NL@%
  2729.     fNeedHorz = (pSWP->cx < (SHORT) (iMaxFrameWidth  + VBarWidth()));%@NL@%
  2730.     fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight + HBarHeight()));%@NL@%
  2731. %@AB@%/*%@NL@%
  2732. %@AB@%    Do width calculations to make sure we're staying small enough.%@NL@%
  2733. %@AB@%    The Tracking Rectangle shouldn't allow us to get too big.%@NL@%
  2734. %@AB@%*/%@AE@%%@NL@%
  2735.     %@AB@%/*%@NL@%
  2736. %@AB@%        Check if we're stretching too far%@NL@%
  2737. %@AB@%    */%@AE@%%@NL@%
  2738.     pSWP->cx = Min(pSWP->cx, iMaxFrameWidth  + (int) VBarWidth());%@NL@%
  2739.     pSWP->cy = Min(pSWP->cy, iMaxFrameHeight + (int) HBarHeight());%@NL@%
  2740.     %@AB@%/*%@NL@%
  2741. %@AB@%        ...if so, fix, then add them!%@NL@%
  2742. %@AB@%    */%@AE@%%@NL@%
  2743.     AvioSize(NULL, WM_NULL, NULL, MPFROM2SHORT(%@NL@%
  2744.         pSWP->cx - (int) (lMiscWidth + VBarWidth()),%@NL@%
  2745.         pSWP->cy - (int) (lMiscHeight + HBarHeight()) ));%@NL@%
  2746. %@NL@%
  2747.     if (fNeedHorz) {%@NL@%
  2748.         if (!fNeededHorz) {%@NL@%
  2749.             EnableSB(hWndHScroll);%@NL@%
  2750.             UpdateOff(hWndHScroll);%@NL@%
  2751.             UpdateFrame(FCF_HORZSCROLL);%@NL@%
  2752.             UpdateOn(hWndHScroll);%@NL@%
  2753.         }%@NL@%
  2754.     } else {%@NL@%
  2755.         if (fNeededHorz) {%@NL@%
  2756.             DisableSB(hWndHScroll);%@NL@%
  2757.             UpdateOff(hWndHScroll);%@NL@%
  2758.             UpdateFrame(FCF_HORZSCROLL);%@NL@%
  2759.             UpdateOn(hWndHScroll);%@NL@%
  2760.         }%@NL@%
  2761.     }%@NL@%
  2762.     if (fNeedVert) {%@NL@%
  2763.         if (!fNeededVert) {%@NL@%
  2764.              EnableSB(hWndVScroll);%@NL@%
  2765.              UpdateOff(hWndVScroll);%@NL@%
  2766.              UpdateFrame(FCF_VERTSCROLL);%@NL@%
  2767.              UpdateOn(hWndVScroll);%@NL@%
  2768.         }%@NL@%
  2769.     } else {%@NL@%
  2770.         if (fNeededVert) {%@NL@%
  2771.              DisableSB(hWndVScroll);%@NL@%
  2772.              UpdateOff(hWndVScroll);%@NL@%
  2773.              UpdateFrame(FCF_VERTSCROLL);%@NL@%
  2774.              UpdateOn(hWndVScroll);%@NL@%
  2775.         }%@NL@%
  2776.     }%@NL@%
  2777. }%@NL@%
  2778. %@NL@%
  2779. void AvioTrackFrame(HWND hWnd, MPARAM mpTrackFlags) {%@NL@%
  2780. %@AB@%/*%@NL@%
  2781. %@AB@%    Takes action on WM_TRACKFRAME message%@NL@%
  2782. %@AB@%*/%@AE@%%@NL@%
  2783.     static TRACKINFO tiTrackInfo;%@NL@%
  2784.     %@AB@%/*%@NL@%
  2785. %@AB@%        Get the tracking information in the TrackInfo structure%@NL@%
  2786. %@AB@%    */%@AE@%%@NL@%
  2787.     WinSendMsg(hWnd, WM_QUERYTRACKINFO, mpTrackFlags, &tiTrackInfo);%@NL@%
  2788.     WinTrackRect(hWnd, NULL, &tiTrackInfo);%@NL@%
  2789. }%@NL@%
  2790. %@NL@%
  2791. void AvioQueryTrackInfo(PTRACKINFO pTI) {%@NL@%
  2792. %@AB@%/*%@NL@%
  2793. %@AB@%    Forces the frame to be byte aligned and bounded%@NL@%
  2794. %@AB@%*/%@AE@%%@NL@%
  2795.     BOOL fMove;%@NL@%
  2796.     %@AB@%/*%@NL@%
  2797. %@AB@%        Get the grid set up for byte alignment%@NL@%
  2798. %@AB@%%@NL@%
  2799. %@AB@%        Set cxGrid to half a character width, because sizing%@NL@%
  2800. %@AB@%        from the keyboard tries to move by half characters.%@NL@%
  2801. %@AB@%        Also, make sure we can move the window freely.%@NL@%
  2802. %@AB@%    */%@AE@%%@NL@%
  2803.     fMove = ((pTI->fs & TF_MOVE) == TF_MOVE);%@NL@%
  2804.     pTI->fs     |= TF_GRID;%@NL@%
  2805.     pTI->cxGrid  = (fMove) ? 1 : ((SHORT) lChWidth);%@NL@%
  2806.     pTI->cyGrid  = (fMove) ? 1 : ((SHORT) lChHeight);%@NL@%
  2807.     pTI->cxKeyboard = (SHORT) lChWidth;%@NL@%
  2808.     pTI->cyKeyboard = (SHORT) lChHeight;%@NL@%
  2809.     %@AB@%/*%@NL@%
  2810. %@AB@%        Bound the frame now%@NL@%
  2811. %@AB@%    */%@AE@%%@NL@%
  2812.     pTI->ptlMinTrackSize.x = (pTI->cxBorder << 1) + lMiscWidth;%@NL@%
  2813.     pTI->ptlMinTrackSize.y = (pTI->cyBorder << 1) + lMiscHeight;%@NL@%
  2814.     pTI->ptlMaxTrackSize.x = iMaxFrameWidth  + lVSBWidth +  (pTI->cxBorder <<1);%@NL@%
  2815.     pTI->ptlMaxTrackSize.y = iMaxFrameHeight + lHSBHeight + (pTI->cyBorder <<1);%@NL@%
  2816. }%@NL@%
  2817. %@NL@%
  2818. BOOL AvioUpdateLines(BOOL fPage, BOOL *fPaging) {%@NL@%
  2819. %@AB@%/*%@NL@%
  2820. %@AB@%    Update the display%@NL@%
  2821. %@AB@%*/%@AE@%%@NL@%
  2822.     int        cLines;%@NL@%
  2823. %@NL@%
  2824.     cLines = QueUpdateHead(AVIO_PS_ROWS, fPage, *fPaging);%@NL@%
  2825.     if (cLines == AVIO_PS_ROWS) *fPaging = TRUE;%@NL@%
  2826.     if (cLines > 0) {%@NL@%
  2827.         ScrollUp(cLines);%@NL@%
  2828.         Update(iTopLine + AVIO_PS_ROWS - cLines, cLines,%@NL@%
  2829.                         AVIO_PS_ROWS - cLines, TRUE);%@NL@%
  2830.     }%@NL@%
  2831.     Update(iTopLine, cchPgHeight, 0, FALSE);%@NL@%
  2832.     return TRUE;%@NL@%
  2833. }%@NL@%
  2834. %@NL@%
  2835. void AvioRedraw(void) {%@NL@%
  2836. %@AB@%/*%@NL@%
  2837. %@AB@%    Clear, then redraw the entire Presentation Space%@NL@%
  2838. %@AB@%*/%@AE@%%@NL@%
  2839.     ClearScreen();%@NL@%
  2840.     Update(iTopLine, cchPgHeight, 0, TRUE);%@NL@%
  2841. }%@NL@%
  2842. %@NL@%
  2843. void WantCursor(BOOL fYes) {%@NL@%
  2844. %@AB@%/*%@NL@%
  2845. %@AB@%    Do the underscore cursor%@NL@%
  2846. %@AB@%*/%@AE@%%@NL@%
  2847.     vci.attr        = (USHORT) (fYes ? 0 : -1);%@NL@%
  2848.     vci.yStart        = 0;%@NL@%
  2849.     vci.cEnd        = (USHORT) lChHeight - 1;%@NL@%
  2850.     vci.cx        = 0;%@NL@%
  2851.     VioSetCurType(&vci, hVPS);%@NL@%
  2852. }%@NL@%
  2853. %@NL@%
  2854. void AvioPageUp(void) {%@NL@%
  2855. %@AB@%/*%@NL@%
  2856. %@AB@%    Execute the Page Up instruction%@NL@%
  2857. %@AB@%*/%@AE@%%@NL@%
  2858.     int cLines;%@NL@%
  2859. %@NL@%
  2860.     cLines = QuePageUp(AVIO_PS_ROWS);%@NL@%
  2861.     ScrollDown(cLines);%@NL@%
  2862.     Update(iTopLine, cLines, 0, TRUE);%@NL@%
  2863. }%@NL@%
  2864. %@NL@%
  2865. %@NL@%
  2866. %@NL@%
  2867. %@2@%%@AH@%BIGBEN.C%@AE@%%@EH@%%@NL@%
  2868. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\BIGBEN\BIGBEN.C%@AE@%%@NL@%
  2869. %@NL@%
  2870. %@AB@%/*%@NL@%
  2871. %@AB@% * This example uses a few of the many VIO calls.%@NL@%
  2872. %@AB@% * %@NL@%
  2873. %@AB@% * This example puts the time on the screen in large numbers.%@NL@%
  2874. %@AB@% *%@NL@%
  2875. %@AB@% * Created by Microsoft Corp. 1986%@NL@%
  2876. %@AB@% */%@AE@%%@NL@%
  2877. %@NL@%
  2878. %@AI@%#include %@AE@%<os2def.h> %@NL@%
  2879. %@AI@%#define %@AE@%INCL_DOSPROCESS %@NL@%
  2880. %@AI@%#define %@AE@%INCL_DOSDATETIME %@NL@%
  2881. %@AI@%#include %@AE@%<bsedos.h> %@NL@%
  2882. %@AI@%#define %@AE@%INCL_SUB %@NL@%
  2883. %@AI@%#include %@AE@%<bsesub.h> %@NL@%
  2884. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  2885. %@NL@%
  2886. %@AI@%#define %@AE@%       CHAR_WIDTH        8 %@NL@%
  2887. %@AI@%#define %@AE@%       CHAR_HEIGHT        7 %@NL@%
  2888. %@NL@%
  2889.        CLOCK_ROW        10        %@AB@%/* row to start the clock */%@AE@%%@NL@%
  2890.        TOTAL_COLMS        80        %@AB@%/* screen size in colms */%@AE@%%@NL@%
  2891.        TOTAL_ROWS        24        %@AB@%/* screen size in rows */%@AE@%%@NL@%
  2892. %@NL@%
  2893.         %@NL@%
  2894. char        BigChars[10][CHAR_HEIGHT][CHAR_WIDTH] = {%@NL@%
  2895. %@NL@%
  2896. {%@NL@%
  2897.         "   00  ",%@NL@%
  2898.         "  0  0 ",%@NL@%
  2899.         " 0    0",%@NL@%
  2900.         " 0    0",%@NL@%
  2901.         " 0    0",%@NL@%
  2902.         "  0  0 ",%@NL@%
  2903.         "   00  "%@NL@%
  2904. },%@NL@%
  2905. {%@NL@%
  2906.         "   1   ",%@NL@%
  2907.         "   1   ",%@NL@%
  2908.         "   1   ",%@NL@%
  2909.         "   1   ",%@NL@%
  2910.         "   1   ",%@NL@%
  2911.         "   1   ",%@NL@%
  2912.         "   1   "%@NL@%
  2913. }, %@NL@%
  2914. {%@NL@%
  2915.         "  2222 ",%@NL@%
  2916.         " 2    2",%@NL@%
  2917.         "      2",%@NL@%
  2918.         "     2 ",%@NL@%
  2919.         "   2   ",%@NL@%
  2920.         "  2    ",%@NL@%
  2921.         " 222222" %@NL@%
  2922. },%@NL@%
  2923. {%@NL@%
  2924.         " 33333 ",%@NL@%
  2925.         "      3",%@NL@%
  2926.         "      3",%@NL@%
  2927.         "   333 ",%@NL@%
  2928.         "      3",%@NL@%
  2929.         "      3",%@NL@%
  2930.         " 33333 " %@NL@%
  2931. },%@NL@%
  2932. {%@NL@%
  2933.         "    44 ",%@NL@%
  2934.         "   4 4 ",%@NL@%
  2935.         "  4  4 ",%@NL@%
  2936.         " 4   4 ",%@NL@%
  2937.         " 444444",%@NL@%
  2938.         "     4 ",%@NL@%
  2939.         "     4 " %@NL@%
  2940. },%@NL@%
  2941. {%@NL@%
  2942.         " 555555",%@NL@%
  2943.         " 5     ",%@NL@%
  2944.         " 55555 ",%@NL@%
  2945.         "      5",%@NL@%
  2946.         "      5",%@NL@%
  2947.         " 5    5",%@NL@%
  2948.         "  5555 " %@NL@%
  2949. },%@NL@%
  2950. {%@NL@%
  2951.         "    6  ",%@NL@%
  2952.         "   6   ",%@NL@%
  2953.         "  6    ",%@NL@%
  2954.         "  6666 ",%@NL@%
  2955.         " 6    6",%@NL@%
  2956.         " 6    6",%@NL@%
  2957.         "  6666 " %@NL@%
  2958. },%@NL@%
  2959. {%@NL@%
  2960.         " 777777",%@NL@%
  2961.         "      7",%@NL@%
  2962.         "     7 ",%@NL@%
  2963.         "    7  ",%@NL@%
  2964.         "   7   ",%@NL@%
  2965.         "  7    ",%@NL@%
  2966.         " 7     "%@NL@%
  2967. },%@NL@%
  2968. {%@NL@%
  2969.         "  8888 ",%@NL@%
  2970.         " 8    8",%@NL@%
  2971.         " 8    8",%@NL@%
  2972.         "  8888 ",%@NL@%
  2973.         " 8    8",%@NL@%
  2974.         " 8    8",%@NL@%
  2975.         "  8888 "%@NL@%
  2976. },%@NL@%
  2977. {%@NL@%
  2978.         "  9999 ",%@NL@%
  2979.         " 9    9",%@NL@%
  2980.         " 9    9",%@NL@%
  2981.         "  9999 ",%@NL@%
  2982.         "    9  ",%@NL@%
  2983.         "   9   ",%@NL@%
  2984.         "  9    "%@NL@%
  2985. }%@NL@%
  2986. };%@NL@%
  2987. %@NL@%
  2988. %@NL@%
  2989. main(argc, argv)%@NL@%
  2990.         int        argc;%@NL@%
  2991.         char        *argv[];%@NL@%
  2992. {%@NL@%
  2993.         unsigned        rc;        %@AB@%/* return code */%@AE@%%@NL@%
  2994.         DATETIME Now;         %@AB@%/* time struct for DosGetDateTime */%@AE@%%@NL@%
  2995. %@NL@%
  2996.         %@AB@%/* clear the screen */%@AE@%%@NL@%
  2997. %@NL@%
  2998.         VioWrtNCell( " \07", TOTAL_ROWS * TOTAL_COLMS, 0, 0, 0 );%@NL@%
  2999. %@NL@%
  3000.         %@AB@%/* paint separators between hours and minutes, and minutes and seconds*/%@AE@%%@NL@%
  3001. %@NL@%
  3002.         VioWrtNCell( "|\07", 1, (CLOCK_ROW + 2), 27, 0 );%@NL@%
  3003.         VioWrtNCell( "|\07", 1, (CLOCK_ROW + 5), 27, 0 );%@NL@%
  3004.         VioWrtNCell( "|\07", 1, (CLOCK_ROW + 2), 52, 0 );%@NL@%
  3005.         VioWrtNCell( "|\07", 1, (CLOCK_ROW + 5), 52, 0 );%@NL@%
  3006.          %@NL@%
  3007.         for (;;) {%@NL@%
  3008. %@NL@%
  3009.             %@AB@%/* get the system time */%@AE@%%@NL@%
  3010. %@NL@%
  3011.             if (rc = DosGetDateTime( &Now))  {%@NL@%
  3012. %@NL@%
  3013.                 printf("DosGetDateTime failed, error: %d\n", rc);%@NL@%
  3014.                 DosExit(EXIT_PROCESS, 0);%@NL@%
  3015.             }%@NL@%
  3016. %@NL@%
  3017.             %@AB@%/* write the digits out to the screen */%@AE@%%@NL@%
  3018. %@NL@%
  3019.             LoadNumber(Now.hours / 10, 5, CLOCK_ROW);%@NL@%
  3020.             LoadNumber(Now.hours % 10, 15, CLOCK_ROW);%@NL@%
  3021.             LoadNumber(Now.minutes / 10, 30, CLOCK_ROW);%@NL@%
  3022.             LoadNumber(Now.minutes % 10, 40, CLOCK_ROW);%@NL@%
  3023.             LoadNumber(Now.seconds / 10, 55, CLOCK_ROW);%@NL@%
  3024.             LoadNumber(Now.seconds % 10, 65, CLOCK_ROW);%@NL@%
  3025. %@NL@%
  3026.             DosSleep(900L);%@NL@%
  3027.         }%@NL@%
  3028. }%@NL@%
  3029. %@NL@%
  3030. %@NL@%
  3031. %@AB@%/* display the digit at the given coordinates */%@AE@%%@NL@%
  3032. %@NL@%
  3033. LoadNumber( dig, x, y )%@NL@%
  3034.         unsigned        dig;%@NL@%
  3035.         unsigned        x;%@NL@%
  3036.         unsigned        y;%@NL@%
  3037. {%@NL@%
  3038.         int        i;%@NL@%
  3039. %@NL@%
  3040.         %@AB@%/* write a list of char strings to make up a display number */%@AE@%%@NL@%
  3041. %@NL@%
  3042.         for (i=0; (i < CHAR_HEIGHT); i++) %@NL@%
  3043. %@NL@%
  3044.             %@AB@%/* write a character string starting from the coordinates */%@AE@%%@NL@%
  3045. %@NL@%
  3046.             VioWrtCharStr( BigChars[dig][i], CHAR_WIDTH, y++, x, 0);%@NL@%
  3047. } %@NL@%
  3048. %@NL@%
  3049. %@NL@%
  3050. %@2@%%@AH@%BIO.C%@AE@%%@EH@%%@NL@%
  3051. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\BIO\BIO.C%@AE@%%@NL@%
  3052. %@NL@%
  3053. %@AB@%/*  Biorhythm - Utility to compute personal biorhythm charts.%@NL@%
  3054. %@AB@%*%@NL@%
  3055. %@AB@%*   Created by Microsoft Corp., 1989%@NL@%
  3056. %@AB@%*%@NL@%
  3057. %@AB@%*   Purpose:%@NL@%
  3058. %@AB@%*       Program entry point, initialization and GetMessage loop.%@NL@%
  3059. %@AB@%*%@NL@%
  3060. %@AB@%*   Arguments:%@NL@%
  3061. %@AB@%*       None%@NL@%
  3062. %@AB@%*%@NL@%
  3063. %@AB@%*   Globals (modified):%@NL@%
  3064. %@AB@%*       hAB           - Handle to the Anchor Block%@NL@%
  3065. %@AB@%*       hMsgQ         - Handle to the application's message queue%@NL@%
  3066. %@AB@%*       hwndAppFrame  - Window handle of parent window's frame%@NL@%
  3067. %@AB@%*       hwndKidFrame  - Window handle of parent window's frame%@NL@%
  3068. %@AB@%*       hwndApp       - Window handle of parent window's client area%@NL@%
  3069. %@AB@%*       hwndKid       - Window handle of child window's client area%@NL@%
  3070. %@AB@%*       szAppName[10] - RC file program name (Biorhythm).%@NL@%
  3071. %@AB@%*       szKidName[10] - RC file child window name (Legend).%@NL@%
  3072. %@AB@%*%@NL@%
  3073. %@AB@%*   Globals (referenced):%@NL@%
  3074. %@AB@%*       tmFontInfo    - Text Metric structure defined during WM_CREATE %@NL@%
  3075. %@AB@%*%@NL@%
  3076. %@AB@%*   Description:%@NL@%
  3077. %@AB@%*       The theory of biorhythms states that life consists of three cycles,%@NL@%
  3078. %@AB@%*       physical, emotional and intellectual of 23, 28 and 33 days,%@NL@%
  3079. %@AB@%*       respectively.  The cycles each begin on the date of birth.%@NL@%
  3080. %@AB@%*%@NL@%
  3081. %@AB@%*   Limits:%@NL@%
  3082. %@AB@%*       The intended use of this program is for the 20th and 21st centuries.%@NL@%
  3083. %@AB@%*       The calculations of biorhythms will not be accurate outside of this%@NL@%
  3084. %@AB@%*       range due to formulae used to compute days between dates.%@NL@%
  3085. %@AB@%*%@NL@%
  3086. %@AB@%*/%@AE@%%@NL@%
  3087. %@NL@%
  3088. %@AI@%#define %@AE@%INCL_WIN %@NL@%
  3089. %@AI@%#include %@AE@%<os2.h> %@NL@%
  3090. %@NL@%
  3091. %@AI@%#include %@AE@%<stddef.h> %@NL@%
  3092. %@NL@%
  3093. %@AI@%#include %@AE@%"bio.h" %@NL@%
  3094. %@NL@%
  3095. %@AB@%/* Write-once global variables */%@AE@%%@NL@%
  3096. HAB     hAB;%@NL@%
  3097. HMQ     hMsgQ;%@NL@%
  3098. HWND    hwndApp, hwndKid;%@NL@%
  3099. HWND    hwndAppFrame, hwndKidFrame;%@NL@%
  3100. char    szAppName[10];%@NL@%
  3101. char    szKidName[10];%@NL@%
  3102. ULONG        AppCtlData = FCF_STANDARD | FCF_VERTSCROLL | FCF_NOBYTEALIGN & ~FCF_SHELLPOSITION;%@NL@%
  3103. ULONG        KidCtlData = FCF_TITLEBAR;%@NL@%
  3104. PFNWP        OldFrameWndProc;%@NL@%
  3105. %@NL@%
  3106. %@AB@%/* Read-only global variables */%@AE@%%@NL@%
  3107. extern  FONTMETRICS     tmFontInfo;%@NL@%
  3108. extern        SHORT                cxLegendField;%@NL@%
  3109. extern        SHORT                cxDateField;%@NL@%
  3110. %@NL@%
  3111. SHORT cdecl main(  )%@NL@%
  3112. {%@NL@%
  3113.     QMSG        qMsg;%@NL@%
  3114.     SHORT       dx, dy, x, y;%@NL@%
  3115.     SHORT        cxSizeBorder;%@NL@%
  3116.     SHORT        cySizeBorder;%@NL@%
  3117.     SHORT        cxBorder;%@NL@%
  3118.     SHORT        cyBorder;%@NL@%
  3119. %@NL@%
  3120.     %@AB@%/* Standard initialization.  Get anchor block and message queue. */%@AE@%%@NL@%
  3121.     hAB   = WinInitialize(0);%@NL@%
  3122.     hMsgQ = WinCreateMsgQueue( hAB, 0 );%@NL@%
  3123. %@NL@%
  3124.     %@AB@%/* Get string constants for parent and child window registration%@NL@%
  3125. %@AB@%       and creation from resource string table. */%@AE@%%@NL@%
  3126.     WinLoadString( hAB, (HMODULE) NULL, IDS_APPNAME, sizeof(szAppName), szAppName );%@NL@%
  3127.     WinLoadString( hAB, (HMODULE) NULL, IDS_KIDNAME, sizeof(szKidName), szKidName );%@NL@%
  3128. %@NL@%
  3129.     %@AB@%/* Register parent window.  Terminate if error. */%@AE@%%@NL@%
  3130.     if ( !WinRegisterClass( hAB, szAppName, BioWndProc,%@NL@%
  3131.             CS_CLIPCHILDREN | CS_SIZEREDRAW, 0 ) )%@NL@%
  3132.         return( FALSE );%@NL@%
  3133. %@NL@%
  3134.     %@AB@%/* Register child window.  Terminate if error. */%@AE@%%@NL@%
  3135.     if ( !WinRegisterClass( hAB, szKidName, KidWndProc, 0, 0 ) )%@NL@%
  3136.         return( FALSE );%@NL@%
  3137. %@NL@%
  3138.     %@AB@%/* Create a parent window of class szAppName */%@AE@%%@NL@%
  3139.     hwndAppFrame = WinCreateStdWindow(%@NL@%
  3140.         HWND_DESKTOP,%@NL@%
  3141.         0L,%@NL@%
  3142.         &AppCtlData,%@NL@%
  3143.         szAppName,%@NL@%
  3144.         NULL,%@NL@%
  3145.         0L,%@NL@%
  3146.         (HMODULE) NULL,%@NL@%
  3147.         ID_BIO,%@NL@%
  3148.         (HWND FAR *)&hwndApp%@NL@%
  3149.         );%@NL@%
  3150. %@NL@%
  3151.     %@AB@%/* Create a child window of class KidClass */%@AE@%%@NL@%
  3152.     hwndKidFrame = WinCreateStdWindow(%@NL@%
  3153.         hwndApp,%@NL@%
  3154.         FS_BORDER,%@NL@%
  3155.         &KidCtlData,%@NL@%
  3156.         szKidName,%@NL@%
  3157.         szKidName,%@NL@%
  3158.         0L,%@NL@%
  3159.         (HMODULE) NULL,%@NL@%
  3160.         0,%@NL@%
  3161.         (HWND FAR *)&hwndKid%@NL@%
  3162.         );%@NL@%
  3163. %@NL@%
  3164.     %@AB@%/* Subclass frame so that minimum window size can be controled */%@AE@%%@NL@%
  3165.     OldFrameWndProc = WinSubclassWindow( hwndAppFrame, FrameWndProc );%@NL@%
  3166. %@NL@%
  3167.     %@AB@%/* Get the size of the screen and border.  Used to place and size window */%@AE@%%@NL@%
  3168.     cxSizeBorder =  (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );%@NL@%
  3169.     cySizeBorder =  (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );%@NL@%
  3170.     cxBorder         =  (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXBORDER );%@NL@%
  3171.     cyBorder         =  (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER );%@NL@%
  3172.     x                 =  (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );%@NL@%
  3173.     y                 =  (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );%@NL@%
  3174. %@NL@%
  3175.     %@AB@%/* Calculate width and height of child window.  Must be able to%@NL@%
  3176. %@AB@%       display three lines and wide enough for text and corresponding colored%@NL@%
  3177. %@AB@%       line.  Must take into account titlebar and border vertical sizes. */%@AE@%%@NL@%
  3178.     dx = cxLegendField * 2;%@NL@%
  3179.     dy = (SHORT)(tmFontInfo.lMaxBaselineExt*3 +%@NL@%
  3180.          WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +%@NL@%
  3181.          WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ) * 2);%@NL@%
  3182. %@NL@%
  3183.     %@AB@%/* Place and size parent and child windows, then make them visible.%@NL@%
  3184. %@AB@%       WinCreateStdWindow does not include position and size arguments.%@NL@%
  3185. %@AB@%       Parent window is thin, but full screen high.  Child window is placed%@NL@%
  3186. %@AB@%       10 pixels over and up from the parent window's lower left corner. */%@AE@%%@NL@%
  3187.     WinSetWindowPos( hwndAppFrame, NULL,%@NL@%
  3188.                      x-(3*cxDateField)+cxSizeBorder,%@NL@%
  3189.                      -cySizeBorder,%@NL@%
  3190.                      (3*cxDateField),%@NL@%
  3191.                      y+2*cySizeBorder,%@NL@%
  3192.                      SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW );%@NL@%
  3193.     WinSetWindowPos( hwndKidFrame, NULL, 10, 10, dx, dy,%@NL@%
  3194.                      SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW );%@NL@%
  3195. %@NL@%
  3196.     %@AB@%/* Get messages from application queue and dispatch them for processing */%@AE@%%@NL@%
  3197.     while( WinGetMsg( hAB, &qMsg, (HWND)NULL, 0, 0 ) )%@NL@%
  3198.     {%@NL@%
  3199.         WinDispatchMsg( hAB, &qMsg );%@NL@%
  3200.     }%@NL@%
  3201. %@NL@%
  3202.     %@AB@%/* Clean up.  All child windows will be destoyed automatically */%@AE@%%@NL@%
  3203.     WinDestroyWindow( hwndAppFrame );%@NL@%
  3204.     WinDestroyMsgQueue( hMsgQ );%@NL@%
  3205.     WinTerminate( hAB );%@NL@%
  3206. }%@NL@%
  3207. %@NL@%
  3208. %@NL@%
  3209. %@2@%%@AH@%BIOCMD.C%@AE@%%@EH@%%@NL@%
  3210. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\BIO\BIOCMD.C%@AE@%%@NL@%
  3211. %@NL@%
  3212. %@AB@%/*  BioDlg() - Dialog Box routine.%@NL@%
  3213. %@AB@%*%@NL@%
  3214. %@AB@%*   Created by Microsoft Corporation, 1989%@NL@%
  3215. %@AB@%*%@NL@%
  3216. %@AB@%*   Purpose:%@NL@%
  3217. %@AB@%*       Allow setting of birthdate and viewing date for biorhythm display.%@NL@%
  3218. %@AB@%*%@NL@%
  3219. %@AB@%*   Arguments:%@NL@%
  3220. %@AB@%*       hDlg          - Handle of Dialog Box owning message%@NL@%
  3221. %@AB@%*       message       - Message itself%@NL@%
  3222. %@AB@%*       mp1           - Extra message-dependent info%@NL@%
  3223. %@AB@%*       mp2           - Extra message-dependent info%@NL@%
  3224. %@AB@%*%@NL@%
  3225. %@AB@%*   Globals (modified):%@NL@%
  3226. %@AB@%*       Born          - Birthdate in julian days.  Read from OS2.INI.%@NL@%
  3227. %@AB@%*       SelectDay     - Current day being tracked, day is highlighted.%@NL@%
  3228. %@AB@%*                        This is stored as # days from birthdate.%@NL@%
  3229. %@AB@%*                        This is initialized to the current date in WM_CREATE.%@NL@%
  3230. %@AB@%*       Day           - Day number from date born which is top line being%@NL@%
  3231. %@AB@%*                       displayed.  Initially three days before SelectDay.%@NL@%
  3232. %@AB@%*       bBorn         - Boolean indicating whether valid birtdate entered or%@NL@%
  3233. %@AB@%*                       defined in OS2.INI.  Nothing graphed until valid.%@NL@%
  3234. %@AB@%*%@NL@%
  3235. %@AB@%*   Globals (referenced):%@NL@%
  3236. %@AB@%*       hAB           - Handle to the Anchor Block%@NL@%
  3237. %@AB@%*       szAppName[]   - RC file program name (Biorhythm).%@NL@%
  3238. %@AB@%*%@NL@%
  3239. %@AB@%*   Description:%@NL@%
  3240. %@AB@%*       Biorythm cycles start on the date of birth and the state of%@NL@%
  3241. %@AB@%*       of these cycles may be viewed on the selected date.  A check%@NL@%
  3242. %@AB@%*       box is provided to update (record) the birthdate in the WIN.INI%@NL@%
  3243. %@AB@%*       file so that it will be automatically available in subsequent%@NL@%
  3244. %@AB@%*       sessions.%@NL@%
  3245. %@AB@%*%@NL@%
  3246. %@AB@%*   Limits:%@NL@%
  3247. %@AB@%*       Minor error checking is provided when OK is selected to make%@NL@%
  3248. %@AB@%*       sure that the dates specified fall in the 20th and 21st%@NL@%
  3249. %@AB@%*       centuries.  No error checking is attempted to verify correct%@NL@%
  3250. %@AB@%*       month or day of month entries. %@NL@%
  3251. %@AB@%*%@NL@%
  3252. %@AB@%*/%@AE@%%@NL@%
  3253. %@NL@%
  3254. %@AI@%#define %@AE@%INCL_WIN %@NL@%
  3255. %@AI@%#include %@AE@%<os2.h> %@NL@%
  3256. %@NL@%
  3257. %@AI@%#include %@AE@%"bio.h" %@NL@%
  3258. %@AI@%#include %@AE@%<math.h> %@NL@%
  3259. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  3260. %@NL@%
  3261. %@AB@%/* Read-only global variables */%@AE@%%@NL@%
  3262. extern HAB      hAB;%@NL@%
  3263. extern char     szAppName[];%@NL@%
  3264. %@NL@%
  3265. %@AB@%/* Global variables (modified) */%@AE@%%@NL@%
  3266. extern long     SelectDay, Day;%@NL@%
  3267. extern double   Born;%@NL@%
  3268. extern BOOL     bBorn;%@NL@%
  3269. %@NL@%
  3270. %@AB@%/* Function prototypes */%@AE@%%@NL@%
  3271. void InitBioDlg(HWND);%@NL@%
  3272. void BioDlgCmd(HWND, MPARAM);%@NL@%
  3273. %@NL@%
  3274. MRESULT CALLBACK BioDlg( hDlg, message, mp1, mp2 )%@NL@%
  3275. HWND    hDlg;%@NL@%
  3276. USHORT  message;%@NL@%
  3277. MPARAM  mp1;%@NL@%
  3278. MPARAM  mp2;%@NL@%
  3279. {%@NL@%
  3280.     switch( message ) {%@NL@%
  3281.         case WM_INITDLG:%@NL@%
  3282.             InitBioDlg(hDlg);%@NL@%
  3283.             break;%@NL@%
  3284. %@NL@%
  3285.         case WM_COMMAND:%@NL@%
  3286.             BioDlgCmd(hDlg, mp1);%@NL@%
  3287.             break;%@NL@%
  3288. %@NL@%
  3289.         default:%@NL@%
  3290.             return( WinDefDlgProc( hDlg, message, mp1, mp2 ) );%@NL@%
  3291. %@NL@%
  3292.     }%@NL@%
  3293.     return 0L;%@NL@%
  3294. }%@NL@%
  3295. %@NL@%
  3296. %@NL@%
  3297. %@AB@%/*  About() - General purpose About dialog box.%@NL@%
  3298. %@AB@%*%@NL@%
  3299. %@AB@%*   Purpose:%@NL@%
  3300. %@AB@%*       Provide program propoganda.%@NL@%
  3301. %@AB@%*%@NL@%
  3302. %@AB@%*   Arguments:%@NL@%
  3303. %@AB@%*       hDlg          - Handle of Dialog Box owning message%@NL@%
  3304. %@AB@%*       message       - Message itself%@NL@%
  3305. %@AB@%*       mp1           - Extra message-dependent info%@NL@%
  3306. %@AB@%*       mp2           - Extra message-dependent info%@NL@%
  3307. %@AB@%*/%@AE@%%@NL@%
  3308. %@NL@%
  3309. MRESULT CALLBACK About( hWndDlg, message, mp1, mp2 )%@NL@%
  3310. HWND   hWndDlg;%@NL@%
  3311. USHORT message;%@NL@%
  3312. MPARAM  mp1;%@NL@%
  3313. MPARAM  mp2;%@NL@%
  3314. {%@NL@%
  3315.     switch( message )%@NL@%
  3316.     {%@NL@%
  3317.       case WM_COMMAND:%@NL@%
  3318.         switch( LOUSHORT( mp1 ) )%@NL@%
  3319.         {%@NL@%
  3320.           case DID_OK:%@NL@%
  3321.             WinDismissDlg( hWndDlg, TRUE );%@NL@%
  3322.             break;%@NL@%
  3323. %@NL@%
  3324.           default:%@NL@%
  3325.             break;%@NL@%
  3326.         }%@NL@%
  3327.         break;%@NL@%
  3328. %@NL@%
  3329.       default:%@NL@%
  3330.         return( WinDefDlgProc( hWndDlg, message, mp1, mp2 ) );%@NL@%
  3331.     }%@NL@%
  3332.     return( FALSE );%@NL@%
  3333. }%@NL@%
  3334. %@NL@%
  3335. %@NL@%
  3336. void InitBioDlg(HWND hDlg) {%@NL@%
  3337. %@AB@%/*%@NL@%
  3338. %@AB@%     If valid OS2.INI info, fill in birthdate edit fields%@NL@%
  3339. %@AB@%*/%@AE@%%@NL@%
  3340.     USHORT        year, month;%@NL@%
  3341.     double      day;%@NL@%
  3342. %@NL@%
  3343.     if (bBorn) {%@NL@%
  3344.       calendar( Born, (int *)&year, (int *)&month, &day );%@NL@%
  3345.       WinSetDlgItemShort( hDlg, ID_BDYEAR, year, FALSE );%@NL@%
  3346.       WinSetDlgItemShort( hDlg, ID_BDMONTH, month, FALSE );%@NL@%
  3347.       WinSetDlgItemShort( hDlg, ID_BDDAY, (int)day, FALSE );%@NL@%
  3348.     }%@NL@%
  3349.     %@AB@%/* Display current date or date highlighted */%@AE@%%@NL@%
  3350.     calendar( Born+SelectDay, (int *)&year, (int *)&month, &day );%@NL@%
  3351.     WinSetDlgItemShort( hDlg, ID_YEAR, year, FALSE );%@NL@%
  3352.     WinSetDlgItemShort( hDlg, ID_MONTH, month, FALSE );%@NL@%
  3353.     WinSetDlgItemShort( hDlg, ID_DAY, (int)day, FALSE );%@NL@%
  3354. }%@NL@%
  3355. %@NL@%
  3356. %@NL@%
  3357. void BioDlgCmd(HWND hDlg, MPARAM mp1) {%@NL@%
  3358. %@AB@%/*%@NL@%
  3359. %@AB@%    Bio Dialog Box routine WM_COMMAND processor%@NL@%
  3360. %@AB@%*/%@AE@%%@NL@%
  3361.     USHORT        year, month, iDay;%@NL@%
  3362.     double      day;%@NL@%
  3363.     char        szBuf[10];%@NL@%
  3364. %@NL@%
  3365.     switch( LOUSHORT( mp1 ) ) {%@NL@%
  3366.         case DID_OK:%@NL@%
  3367.             %@AB@%/* Get the birthday edit field values */%@AE@%%@NL@%
  3368.             WinQueryDlgItemShort( hDlg, ID_BDYEAR, &year, FALSE );%@NL@%
  3369.             WinQueryDlgItemShort( hDlg, ID_BDMONTH, &month, FALSE );%@NL@%
  3370.             WinQueryDlgItemShort( hDlg, ID_BDDAY, &iDay, FALSE );%@NL@%
  3371.             day = (double)iDay;%@NL@%
  3372.             %@AB@%/* Check that date is within acceptable range */%@AE@%%@NL@%
  3373.             if (year<1900 || year>2100) {%@NL@%
  3374.                WinMessageBox( HWND_DESKTOP, hDlg,%@NL@%
  3375.                               "Dates valid from 1900-2100",%@NL@%
  3376.                               "Birthday!", 0,%@NL@%
  3377.                               MB_OK | MB_ICONEXCLAMATION );%@NL@%
  3378.                break;%@NL@%
  3379.             }%@NL@%
  3380.             %@AB@%/* Get julian date of birth date */%@AE@%%@NL@%
  3381.             Born = julian( year, month, day );%@NL@%
  3382. %@NL@%
  3383.             %@AB@%/* Write birth date to OS2.INI if check box checked */%@AE@%%@NL@%
  3384.             if (WinSendDlgItemMsg(hDlg, ID_OS2INI, BM_QUERYCHECK, 0L, 0L)) {%@NL@%
  3385.                    sprintf(szBuf, "%d", year);%@NL@%
  3386.               WinWriteProfileString( hAB, szAppName, "Year", szBuf );%@NL@%
  3387.                    sprintf(szBuf, "%d", month);%@NL@%
  3388.               WinWriteProfileString( hAB, szAppName, "Month", szBuf );%@NL@%
  3389.                    sprintf(szBuf, "%d", (int)day);%@NL@%
  3390.               WinWriteProfileString( hAB, szAppName, "Day", szBuf );%@NL@%
  3391.             }%@NL@%
  3392. %@NL@%
  3393.             %@AB@%/* Get selected day of interest edit field values */%@AE@%%@NL@%
  3394.             WinQueryDlgItemShort( hDlg, ID_YEAR, &year, FALSE );%@NL@%
  3395.             WinQueryDlgItemShort( hDlg, ID_MONTH, &month, FALSE );%@NL@%
  3396.             WinQueryDlgItemShort( hDlg, ID_DAY, &iDay, FALSE );%@NL@%
  3397.             day = (double)iDay;%@NL@%
  3398.             %@AB@%/* Check that date is within acceptable range */%@AE@%%@NL@%
  3399.             if (year<1900 || year>2100) {%@NL@%
  3400.                WinMessageBox( HWND_DESKTOP, hDlg,%@NL@%
  3401.                               "Dates valid from 1900-2100",%@NL@%
  3402.                               "Display Date!", 0,%@NL@%
  3403.                               MB_OK | MB_ICONEXCLAMATION );%@NL@%
  3404.                break;%@NL@%
  3405.             }%@NL@%
  3406. %@NL@%
  3407.             %@AB@%/* Compute number of days since birth */%@AE@%%@NL@%
  3408.                  SelectDay  = (long)(julian( year, month, day ) - Born);%@NL@%
  3409.             %@AB@%/* Top date of display is 3 days before selected day */%@AE@%%@NL@%
  3410.             Day = SelectDay - 3;%@NL@%
  3411.             %@AB@%/* Got a valid birthdate, enable all routines */%@AE@%%@NL@%
  3412.             bBorn = TRUE;%@NL@%
  3413.             WinDismissDlg( hDlg, TRUE );%@NL@%
  3414.             break;%@NL@%
  3415. %@NL@%
  3416.         case DID_CANCEL:%@NL@%
  3417.             %@AB@%/* Exit and ignore entries */%@AE@%%@NL@%
  3418.             WinDismissDlg( hDlg, FALSE );%@NL@%
  3419.             break;%@NL@%
  3420. %@NL@%
  3421.         default:%@NL@%
  3422.             break;%@NL@%
  3423.     }%@NL@%
  3424. }%@NL@%
  3425. %@NL@%
  3426. %@NL@%
  3427. %@2@%%@AH@%BIOPAINT.C%@AE@%%@EH@%%@NL@%
  3428. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\BIO\BIOPAINT.C%@AE@%%@NL@%
  3429. %@NL@%
  3430. %@AB@%/*%@NL@%
  3431. %@AB@%    biopaint.c        -   WM_PAINT processing and calendar conversion routines%@NL@%
  3432. %@AB@%%@NL@%
  3433. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  3434. %@AB@%*/%@AE@%%@NL@%
  3435. %@AI@%#define %@AE@%INCL_WIN %@NL@%
  3436. %@AI@%#define %@AE@%INCL_GPI %@NL@%
  3437. %@AI@%#include %@AE@%<os2.h> %@NL@%
  3438. %@NL@%
  3439. %@AI@%#include %@AE@%"bio.h" %@NL@%
  3440. %@AI@%#include %@AE@%<math.h> %@NL@%
  3441. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  3442. %@NL@%
  3443. %@AB@%/* Read-only global variables */%@AE@%%@NL@%
  3444. extern double   Born;%@NL@%
  3445. extern long     Day, SelectDay;%@NL@%
  3446. extern BOOL     bBorn;%@NL@%
  3447. extern FONTMETRICS tmFontInfo;%@NL@%
  3448. extern int      LinesPerPage;%@NL@%
  3449. extern RECTL    rclClient;%@NL@%
  3450. extern SHORT        cxDateField;%@NL@%
  3451. %@NL@%
  3452. %@AB@%/* Read-only static variables */%@AE@%%@NL@%
  3453. static double   Cycle[] = { 23.0, 28.0, 33.0 };%@NL@%
  3454. static char     cDayOfWeek[] = "MTWTFSS";%@NL@%
  3455. extern LONG     Color[];%@NL@%
  3456. %@NL@%
  3457. %@NL@%
  3458. %@NL@%
  3459. %@AB@%/*  APPPaint() - Parent window WM_PAINT processing routine.%@NL@%
  3460. %@AB@%*%@NL@%
  3461. %@AB@%*   Purpose:%@NL@%
  3462. %@AB@%*       Routine to graph biorhythm cycles and tabulate dates.%@NL@%
  3463. %@AB@%*%@NL@%
  3464. %@AB@%*   Arguments:%@NL@%
  3465. %@AB@%*       hWnd          - Handle of Window owning message%@NL@%
  3466. %@AB@%*       message       - Message itself%@NL@%
  3467. %@AB@%*       mp1           - Extra message-dependent info%@NL@%
  3468. %@AB@%*       mp2           - Extra message-dependent info%@NL@%
  3469. %@AB@%*%@NL@%
  3470. %@AB@%*   Globals (static):%@NL@%
  3471. %@AB@%*       Cycle[]       - Array holding period for phy/emot/int: 23,28,33%@NL@%
  3472. %@AB@%*       cDayOfWeek[]  - Array of chars holding first letter of days of week.%@NL@%
  3473. %@AB@%*       Color[]       - Set of colored pens used to identify cycles.%@NL@%
  3474. %@AB@%*%@NL@%
  3475. %@AB@%*   Globals (referenced):%@NL@%
  3476. %@AB@%*       Born          - Birthdate in julian days.  Read from WIN.INI.%@NL@%
  3477. %@AB@%*        SelectDay     - Current day being tracked, day is highlighted.%@NL@%
  3478. %@AB@%*                        This is stored as the number of days from birthdate.%@NL@%
  3479. %@AB@%*                        Initialized to present day in WM_CREATE processing.%@NL@%
  3480. %@AB@%*       Day           - Day number from date born which is top line being%@NL@%
  3481. %@AB@%*                       displayed.  Initially three days before SelectDay.%@NL@%
  3482. %@AB@%*       bBorn         - Boolean indicating whether valid birtdate entered or%@NL@%
  3483. %@AB@%*        rclClient     - Size of client area defined by WM_SIZE message%@NL@%
  3484. %@AB@%*       LinesPerPage  - Number of system font lines on client area, defined%@NL@%
  3485. %@AB@%*                       by WM_SIZE message handling%@NL@%
  3486. %@AB@%*       tmFontInfo    - Text Metric structure defined during WM_CREATE %@NL@%
  3487. %@AB@%*%@NL@%
  3488. %@AB@%*   Description:%@NL@%
  3489. %@AB@%*       Tabulates dates and graphs cycles.  On color displays, weekends%@NL@%
  3490. %@AB@%*       are written in red.  The update rectangle is used to minimize%@NL@%
  3491. %@AB@%*       repaint time of affected client area.%@NL@%
  3492. %@AB@%*/%@AE@%%@NL@%
  3493. VOID APIENTRY APPPaint( hWnd )%@NL@%
  3494. HWND   hWnd;%@NL@%
  3495. {%@NL@%
  3496.     HPS         hPS;%@NL@%
  3497.     POINTL      ptl;%@NL@%
  3498.     int         y, i;%@NL@%
  3499.     int         start, last;%@NL@%
  3500.     char        szDay[16];%@NL@%
  3501.     int         Amplitude, offset;%@NL@%
  3502.     int         year, month;%@NL@%
  3503.     double      day;%@NL@%
  3504.     RECTL       rc, rcClip;%@NL@%
  3505.     int         DayOfWeek;%@NL@%
  3506.     HRGN        hrgnClip;%@NL@%
  3507.     POINTL        ptlTextBox[5];%@NL@%
  3508. %@NL@%
  3509.     hPS = WinBeginPaint( hWnd, NULL, &rcClip );%@NL@%
  3510. %@NL@%
  3511.     %@AB@%/* Erase client area */%@AE@%%@NL@%
  3512.     WinQueryWindowRect( hWnd, &rc );%@NL@%
  3513.     WinFillRect( hPS, &rc, CLR_WHITE );%@NL@%
  3514. %@NL@%
  3515.     %@AB@%/* Label parts of table and graph. */%@AE@%%@NL@%
  3516.     ptl.y = rclClient.yTop - tmFontInfo.lMaxBaselineExt + %@AB@%/* Top line */%@AE@%%@NL@%
  3517.             tmFontInfo.lMaxDescender;%@NL@%
  3518.     ptl.x = 0;%@NL@%
  3519.     GpiCharStringAt( hPS, &ptl, 7L, (PCH)"   DATE" );%@NL@%
  3520.     ptl.x = cxDateField + tmFontInfo.lAveCharWidth;%@NL@%
  3521.     GpiCharStringAt( hPS, &ptl, 3L, (PCH)"LOW" );%@NL@%
  3522.     GpiQueryTextBox( hPS, 4L, "HIGH", TXTBOX_COUNT, ptlTextBox );%@NL@%
  3523.     ptl.x = rclClient.xRight - ptlTextBox[TXTBOX_CONCAT].x - tmFontInfo.lAveCharWidth;%@NL@%
  3524.     GpiCharStringAt( hPS, &ptl, 4L, (PCH)"HIGH" );%@NL@%
  3525. %@NL@%
  3526.     %@AB@%/* Underline labels from left to right across client area */%@AE@%%@NL@%
  3527.     ptl.y = rclClient.yTop - tmFontInfo.lMaxBaselineExt;%@NL@%
  3528.     ptl.x = 0;%@NL@%
  3529.     GpiMove( hPS, &ptl );%@NL@%
  3530.     ptl.x = rclClient.xRight;%@NL@%
  3531.     GpiLine( hPS, &ptl );%@NL@%
  3532. %@NL@%
  3533.     %@AB@%/* Draw a vertical line separator between dates and cycles */%@AE@%%@NL@%
  3534.     ptl.y = rclClient.yTop;%@NL@%
  3535.     ptl.x = cxDateField;%@NL@%
  3536.     GpiMove( hPS, &ptl );%@NL@%
  3537.     ptl.y = rclClient.yBottom;%@NL@%
  3538.     GpiLine( hPS, &ptl );%@NL@%
  3539. %@NL@%
  3540.     %@AB@%/* Draw a dotted vertical center line to reference cycles */%@AE@%%@NL@%
  3541.     GpiSetLineType( hPS, LINETYPE_DOT );%@NL@%
  3542.     ptl.x = (cxDateField + rclClient.xRight) / 2;%@NL@%
  3543.     GpiMove( hPS, &ptl );%@NL@%
  3544.     ptl.y = rclClient.yTop;%@NL@%
  3545.     GpiLine( hPS, &ptl );%@NL@%
  3546.     %@AB@%/* (Should not have to restore line type after EndPaint) */%@AE@%%@NL@%
  3547.     GpiSetLineType( hPS, LINETYPE_DEFAULT );%@NL@%
  3548. %@NL@%
  3549.     %@AB@%/* Update only the range of lines which fall into update rectangle */%@AE@%%@NL@%
  3550.     start = (int)((rclClient.yTop - rcClip.yTop) / tmFontInfo.lMaxBaselineExt);%@NL@%
  3551.     if (start<1)%@NL@%
  3552.        start = 1;%@NL@%
  3553.     last = (int)((rclClient.yTop - rcClip.yBottom) / tmFontInfo.lMaxBaselineExt);%@NL@%
  3554.     if (last>(LinesPerPage-1))%@NL@%
  3555.        last = LinesPerPage-1;%@NL@%
  3556.     %@NL@%
  3557.     %@AB@%/* Set clip rectangle to completely draw entire rectangle representing%@NL@%
  3558. %@AB@%       each date affected.  Start drawing one day before and after%@NL@%
  3559. %@AB@%       (outside clip rectangle) so that cycle lines will connect correctly%@NL@%
  3560. %@AB@%       with unaffected lines. */%@AE@%%@NL@%
  3561.     rcClip.yTop = rclClient.yTop - start*tmFontInfo.lMaxBaselineExt;%@NL@%
  3562.     start--;%@NL@%
  3563.     last++;%@NL@%
  3564.     rcClip.yBottom = rclClient.yTop - last*tmFontInfo.lMaxBaselineExt + 1;%@NL@%
  3565.     hrgnClip = GpiCreateRegion( hPS, 1L, &rcClip );%@NL@%
  3566.     GpiSetClipRegion( hPS, hrgnClip, &hrgnClip );%@NL@%
  3567. %@NL@%
  3568.     %@AB@%/* List days and date */%@AE@%%@NL@%
  3569.     for (y=start; y<=last; y++) {%@NL@%
  3570.         %@AB@%/* Get the calendar date from julian day */%@AE@%%@NL@%
  3571.         calendar( Born+Day+y-1, &year, &month, &day );%@NL@%
  3572.         %@AB@%/* Get offset into days of the week initials array */%@AE@%%@NL@%
  3573.         DayOfWeek = (int)((LONG)(Born+Day+y) % 7);%@NL@%
  3574.         %@AB@%/* Assemble each of the parts in a buffer */%@AE@%%@NL@%
  3575.         sprintf(szDay, " %02d-%02d-%02d",%@NL@%
  3576.                 month, (int)day, year - (trunc4((double)year / 100)*100) );%@NL@%
  3577.         %@AB@%/* If color available, draw weekends in red */%@AE@%%@NL@%
  3578.         if (DayOfWeek > 4)%@NL@%
  3579.            GpiSetColor( hPS, CLR_RED );%@NL@%
  3580.         ptl.x = 0;%@NL@%
  3581.         ptl.y = rclClient.yTop - ((y+1)*tmFontInfo.lMaxBaselineExt -%@NL@%
  3582.                 tmFontInfo.lMaxDescender);%@NL@%
  3583.         GpiCharStringAt( hPS, &ptl, 1L, (PCH)&cDayOfWeek[DayOfWeek] );%@NL@%
  3584.         GpiQueryWidthTable( hPS, (LONG)'W', 1L, &ptl.x );%@NL@%
  3585.         GpiCharStringAt( hPS, &ptl, 9L, (PCH)szDay );%@NL@%
  3586.         GpiSetColor( hPS, CLR_BLACK );%@NL@%
  3587.     }%@NL@%
  3588. %@NL@%
  3589.     %@AB@%/* Amplitude of sin wave is half client area minus space for dates */%@AE@%%@NL@%
  3590.     Amplitude = (int)((rclClient.xRight - cxDateField - tmFontInfo.lAveCharWidth) >> 1);%@NL@%
  3591.     %@AB@%/* Move to right, make room for column of dates */%@AE@%%@NL@%
  3592.     offset = (int)(Amplitude + cxDateField + tmFontInfo.lAveCharWidth - (tmFontInfo.lAveCharWidth>>1));%@NL@%
  3593.     for (i=0; i<3 && bBorn; i++ ) {%@NL@%
  3594.         GpiSetColor( hPS, Color[i] );%@NL@%
  3595.         for (y=start; y<=last; y++) {%@NL@%
  3596.             ptl.x = (int)(sin( (y+Day-1)/Cycle[i]*2*3.14159 ) * Amplitude + offset);%@NL@%
  3597.             ptl.y = rclClient.yTop - (y*tmFontInfo.lMaxBaselineExt +%@NL@%
  3598.                         tmFontInfo.lMaxBaselineExt/2);%@NL@%
  3599.             if ((y+Day-1 > 0) && (y>start))%@NL@%
  3600.                GpiLine( hPS, &ptl );%@NL@%
  3601.             else%@NL@%
  3602.                GpiMove( hPS, &ptl );%@NL@%
  3603.         }%@NL@%
  3604.     }%@NL@%
  3605. %@NL@%
  3606.     %@AB@%/* Draw highlight on selected day if visible. */%@AE@%%@NL@%
  3607.     if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage - 1)) {%@NL@%
  3608.         rc.xRight = rclClient.xRight;%@NL@%
  3609.         rc.xLeft = rclClient.xLeft;%@NL@%
  3610.         rc.yTop = rclClient.yTop - (int)(SelectDay - Day + 1) * tmFontInfo.lMaxBaselineExt;%@NL@%
  3611.         rc.yBottom = rc.yTop - tmFontInfo.lMaxBaselineExt + 1;%@NL@%
  3612.         WinInvertRect( hPS, &rc );%@NL@%
  3613.     }%@NL@%
  3614. %@NL@%
  3615.     WinEndPaint( hPS );%@NL@%
  3616. %@NL@%
  3617.     return;%@NL@%
  3618. }%@NL@%
  3619. %@NL@%
  3620. %@NL@%
  3621. %@AB@%/*  julian() - Compute julian date from Gregorian calendar date.%@NL@%
  3622. %@AB@%*%@NL@%
  3623. %@AB@%*   Purpose:%@NL@%
  3624. %@AB@%*       Provide a standard time base.%@NL@%
  3625. %@AB@%*%@NL@%
  3626. %@AB@%*   Arguments:%@NL@%
  3627. %@AB@%*       year          - Calendar year%@NL@%
  3628. %@AB@%*       month         - Calendar month%@NL@%
  3629. %@AB@%*       day           - Calendar day and fraction%@NL@%
  3630. %@AB@%*%@NL@%
  3631. %@AB@%*   Return Value:%@NL@%
  3632. %@AB@%*       double        - Julian date converted%@NL@%
  3633. %@AB@%*%@NL@%
  3634. %@AB@%*   Description:%@NL@%
  3635. %@AB@%*       Convert Gregorian dates to Julian Days.  Refer to Alamanac for%@NL@%
  3636. %@AB@%*       Computers (1978), p. B2, Naval Observatory Pub.%@NL@%
  3637. %@AB@%*%@NL@%
  3638. %@AB@%*   Limits:%@NL@%
  3639. %@AB@%*       Valid between ~1900 and 2099.%@NL@%
  3640. %@AB@%*%@NL@%
  3641. %@AB@%*/%@AE@%%@NL@%
  3642. %@NL@%
  3643. double PASCAL julian (year, month, day)%@NL@%
  3644. int    year, month;%@NL@%
  3645. double day;%@NL@%
  3646. {%@NL@%
  3647.   double dj;%@NL@%
  3648.   double fracDay, intDay;%@NL@%
  3649. %@NL@%
  3650.   fracDay = modf(day, &intDay);%@NL@%
  3651.   dj = (long)367*year - 7*(year + (month+9) / 12) / 4 + 275*month / 9 +%@NL@%
  3652.        intDay + 1721013.5 + fracDay;%@NL@%
  3653.   return dj;%@NL@%
  3654. }%@NL@%
  3655. %@NL@%
  3656. %@NL@%
  3657. %@AB@%/*  calendar() - Compute Gregorian calendar date from julian date.%@NL@%
  3658. %@AB@%*%@NL@%
  3659. %@AB@%*   Purpose:%@NL@%
  3660. %@AB@%*       Provide a standard time base.%@NL@%
  3661. %@AB@%*%@NL@%
  3662. %@AB@%*   Arguments:%@NL@%
  3663. %@AB@%*       juldate       - Julian date to convert%@NL@%
  3664. %@AB@%*       year          - Calendar year result%@NL@%
  3665. %@AB@%*       month         - Calendar month result%@NL@%
  3666. %@AB@%*       day           - Calendar day and fraction result%@NL@%
  3667. %@AB@%*%@NL@%
  3668. %@AB@%*   Return Value:%@NL@%
  3669. %@AB@%*       void%@NL@%
  3670. %@AB@%*%@NL@%
  3671. %@AB@%*   Globals (modified):%@NL@%
  3672. %@AB@%*       none%@NL@%
  3673. %@AB@%*%@NL@%
  3674. %@AB@%*   Globals (referenced):%@NL@%
  3675. %@AB@%*       none%@NL@%
  3676. %@AB@%*%@NL@%
  3677. %@AB@%*   Description:%@NL@%
  3678. %@AB@%*       Convert Julian Days to Gregorian date.  Refer to Astronomical%@NL@%
  3679. %@AB@%*       Formulae for Calculators (1979), p. 23, by Jean Meeus.%@NL@%
  3680. %@AB@%*%@NL@%
  3681. %@AB@%*   Limits:%@NL@%
  3682. %@AB@%*       Valid for positive Julian Day values.%@NL@%
  3683. %@AB@%*%@NL@%
  3684. %@AB@%*/%@AE@%%@NL@%
  3685. %@NL@%
  3686. void PASCAL calendar (juldate, year, month, day)%@NL@%
  3687. double juldate;%@NL@%
  3688. int *year;%@NL@%
  3689. int *month;%@NL@%
  3690. double *day;%@NL@%
  3691. {%@NL@%
  3692.   long b, c, d, e, z, alf;%@NL@%
  3693. %@NL@%
  3694.   juldate = juldate + 0.5;%@NL@%
  3695.   z = trunc4(juldate);%@NL@%
  3696.   alf = trunc4((z - 1867216.25)/36524.25);%@NL@%
  3697.   b = z + 1 + alf - alf / 4 + 1524;%@NL@%
  3698.   c = trunc4((b - 122.1)/365.25);%@NL@%
  3699.   d = 365*c + c / 4;%@NL@%
  3700.   e = trunc4((b - d)/30.6001);%@NL@%
  3701.   *day = b - d - trunc4(30.6001*e) + juldate - z;%@NL@%
  3702.   if (e > 13)%@NL@%
  3703.       *month = (int)e - 13;%@NL@%
  3704.   else%@NL@%
  3705.       *month = (int)e - 1;%@NL@%
  3706.   if (*month > 2)%@NL@%
  3707.       *year = (int)c - 4716;%@NL@%
  3708.   else%@NL@%
  3709.       *year = (int)c - 4715;%@NL@%
  3710. }%@NL@%
  3711. %@NL@%
  3712. long PASCAL trunc4( dflValue )%@NL@%
  3713. double dflValue;%@NL@%
  3714. {%@NL@%
  3715.    double intValue;%@NL@%
  3716.    modf(dflValue, &intValue);%@NL@%
  3717.    return (long)intValue;%@NL@%
  3718. }%@NL@%
  3719. %@NL@%
  3720. %@NL@%
  3721. %@2@%%@AH@%BMAP.C%@AE@%%@EH@%%@NL@%
  3722. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\MSNGR\BMAP.C%@AE@%%@NL@%
  3723. %@NL@%
  3724. %@AB@%/****************************** MODULE Header ******************************\%@NL@%
  3725. %@AB@%* Module Name:  bmap.c - Messenger application - bitmap module%@NL@%
  3726. %@AB@%*%@NL@%
  3727. %@AB@%* Created: 8/1/89  sanfords%@NL@%
  3728. %@AB@%*%@NL@%
  3729. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  3730. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  3731. %@NL@%
  3732. %@AI@%#include %@AE@%"msngr.h" %@NL@%
  3733. %@AI@%#include %@AE@%"string.h" %@NL@%
  3734. %@AI@%#ifdef %@AE@%SLOOP %@NL@%
  3735. %@AI@%#define %@AE@%BITMAPINFOHEADER2 BITMAPINFOHEADER %@NL@%
  3736. %@AI@%#define %@AE@%PBITMAPINFOHEADER2 PBITMAPINFOHEADER %@NL@%
  3737. %@AI@%#define %@AE@%BITMAPINFO2 BITMAPINFO %@NL@%
  3738. %@AI@%#define %@AE@%PBITMAPINFO2 PBITMAPINFO %@NL@%
  3739. %@AI@%#endif %@AE@%%@NL@%
  3740. %@NL@%
  3741. typedef struct _CDATA {%@NL@%
  3742.     RECTL rcl;%@NL@%
  3743.     HBITMAP hbm;%@NL@%
  3744.     BOOL fSelect;%@NL@%
  3745.     BOOL fSelecting;%@NL@%
  3746.     NPUSERLIST npUL;%@NL@%
  3747. } CDATA;%@NL@%
  3748. typedef CDATA *NPCDATA;%@NL@%
  3749. %@NL@%
  3750. %@NL@%
  3751. typedef struct _PKT {%@NL@%
  3752.     HBITMAP hbm;%@NL@%
  3753.     SHORT cx;%@NL@%
  3754.     SHORT cy;%@NL@%
  3755.     char szName[MAX_NAMESTR + 1];%@NL@%
  3756. } PKT;%@NL@%
  3757. typedef PKT *NPPKT;%@NL@%
  3758. %@NL@%
  3759. extern HWND hwndMsngr;%@NL@%
  3760. extern SHORT cyText;%@NL@%
  3761. extern HAB hab;%@NL@%
  3762. extern HSZ hszAppName;%@NL@%
  3763. extern HSZ hszEmailName;%@NL@%
  3764. extern char szEmailName[];%@NL@%
  3765. extern HWND hwndLB;%@NL@%
  3766. extern ITEMLIST msgTopicItemList[];%@NL@%
  3767. %@NL@%
  3768. %@NL@%
  3769. %@NL@%
  3770. %@AB@%/*%@NL@%
  3771. %@AB@% * local procs%@NL@%
  3772. %@AB@% */%@AE@%%@NL@%
  3773. MRESULT bmpInit(HWND hwnd, NPPKT ppktInit);%@NL@%
  3774. MRESULT sndBmapInit(HWND hwnd, NPUSERLIST pUserItem);%@NL@%
  3775. BOOL sndBmap(NPCDATA pcd);%@NL@%
  3776. HBITMAP SnapRegion(HPS hps, PRECTL prcl);%@NL@%
  3777. void DrawRgn(HPS hps, PRECTL prcl);%@NL@%
  3778. void SortRect(PRECTL prcl, PRECTL prclSorted);%@NL@%
  3779. HDC CreateDC(PSZ lpszDriver, HDC hdcCompat);%@NL@%
  3780. %@NL@%
  3781. %@AI@%#define %@AE@%max(a,b)    (((a) > (b)) ? (a) : (b)) %@NL@%
  3782. %@NL@%
  3783. %@AB@%/*%@NL@%
  3784. %@AB@% * file globals%@NL@%
  3785. %@AB@% */%@AE@%%@NL@%
  3786. ATOM fmtBmapPkt;%@NL@%
  3787. HPOINTER hptrSelBmap = 0;%@NL@%
  3788. HPOINTER hptrBmap = 0;%@NL@%
  3789. %@NL@%
  3790. void InitBmapModule()%@NL@%
  3791. {%@NL@%
  3792.     fmtBmapPkt = WinAddAtom(WinQuerySystemAtomTable(), SZBMAPDATA);%@NL@%
  3793.     hptrSelBmap = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_SELBMAP);%@NL@%
  3794.     hptrBmap = WinLoadPointer(HWND_DESKTOP, NULL, IDD_GETBITMAP);%@NL@%
  3795. } %@NL@%
  3796. %@NL@%
  3797. void CloseBmapModule()%@NL@%
  3798. {%@NL@%
  3799.     WinDeleteAtom(WinQuerySystemAtomTable(), fmtBmapPkt);%@NL@%
  3800.     WinDestroyPointer(hptrSelBmap);%@NL@%
  3801.     WinDestroyPointer(hptrBmap);%@NL@%
  3802. }%@NL@%
  3803. %@NL@%
  3804. HDMGDATA bmpXfer(pXferInfo)%@NL@%
  3805. PXFERINFO pXferInfo;%@NL@%
  3806. {%@NL@%
  3807.     PBYTE pbuf;%@NL@%
  3808.     PKT pkt;%@NL@%
  3809.     PBITMAPINFO pbmi;%@NL@%
  3810.     HDC hdc;%@NL@%
  3811.     HPS hpsMem;%@NL@%
  3812.     SIZEL size;%@NL@%
  3813. %@NL@%
  3814.     if (pXferInfo->usFmt != fmtBmapPkt)%@NL@%
  3815.         return(DDE_NOTPROCESSED);%@NL@%
  3816. %@NL@%
  3817.     if (pXferInfo->usType == XTYP_POKE) {%@NL@%
  3818.         %@AB@%/*%@NL@%
  3819. %@AB@%         * we have bitmap bits...stick them into pkt.hbm.%@NL@%
  3820. %@AB@%         */%@AE@%%@NL@%
  3821.         pbuf = DdeAccessData(pXferInfo->hDmgData);%@NL@%
  3822.         %@NL@%
  3823.         DdeCopyBlock(pbuf, (PBYTE)&pkt.szName[0], MAX_NAMESTR + 1L);%@NL@%
  3824.         pbmi = (PBITMAPINFO)(pbuf + MAX_NAMESTR + 1);%@NL@%
  3825. %@NL@%
  3826.         pkt.cx = pbmi->cx;%@NL@%
  3827.         pkt.cy = pbmi->cy;%@NL@%
  3828.         size.cx = (LONG)pkt.cx;%@NL@%
  3829.         size.cy = (LONG)pkt.cy;%@NL@%
  3830.         hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);%@NL@%
  3831.         hpsMem = GpiCreatePS(hab, hdc, &size,%@NL@%
  3832.                 PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );%@NL@%
  3833.         pkt.hbm = GpiCreateBitmap(hpsMem, (PBITMAPINFOHEADER2)pbmi, CBM_INIT,%@NL@%
  3834.                 (PBYTE)&pbmi->argbColor[1 << pbmi->cBitCount],%@NL@%
  3835.                 (PBITMAPINFO2)pbmi);%@NL@%
  3836.         GpiAssociate(hpsMem, NULL);%@NL@%
  3837.         GpiDestroyPS(hpsMem);%@NL@%
  3838.         DevCloseDC(hdc);%@NL@%
  3839.         DdeFreeData(pXferInfo->hDmgData);%@NL@%
  3840.         %@NL@%
  3841.         WinLoadDlg(HWND_DESKTOP, hwndMsngr, BmpDlgProc, 0L, IDD_GETBITMAP,%@NL@%
  3842.                 (PVOID)&pkt);%@NL@%
  3843.         return(1);%@NL@%
  3844.     }%@NL@%
  3845.     return(0);%@NL@%
  3846. }%@NL@%
  3847. %@NL@%
  3848. %@NL@%
  3849. %@AB@%/*%@NL@%
  3850. %@AB@% * This is the proc used for receiving a bitmap%@NL@%
  3851. %@AB@% */%@AE@%%@NL@%
  3852. MRESULT EXPENTRY BmpDlgProc(hwnd, msg, mp1, mp2)%@NL@%
  3853. HWND hwnd;%@NL@%
  3854. USHORT msg;%@NL@%
  3855. MPARAM mp1;%@NL@%
  3856. MPARAM mp2;%@NL@%
  3857. {%@NL@%
  3858.     HBITMAP hbm;%@NL@%
  3859.     HPS hps;%@NL@%
  3860.     WRECT wrc;%@NL@%
  3861.     %@NL@%
  3862.     switch(msg) {%@NL@%
  3863.     case WM_INITDLG:%@NL@%
  3864.         return(bmpInit(hwnd, (NPPKT)(SHORT)mp2));%@NL@%
  3865.         break;%@NL@%
  3866. %@NL@%
  3867.     case WM_DESTROY:%@NL@%
  3868.         if (hbm = ((NPPKT)WinQueryWindowUShort(hwnd, QWS_USER))->hbm)%@NL@%
  3869.             GpiDeleteBitmap(hbm);%@NL@%
  3870.         WinFreeMem(hheap, (NPBYTE)WinQueryWindowUShort(hwnd, QWS_USER),%@NL@%
  3871.                 sizeof(PKT));%@NL@%
  3872.         break;%@NL@%
  3873. %@NL@%
  3874.     case WM_WINDOWPOSCHANGED:%@NL@%
  3875.         %@AB@%/*%@NL@%
  3876. %@AB@%         * hide the OK button when minimized since it messes up the icon.%@NL@%
  3877. %@AB@%         */%@AE@%%@NL@%
  3878.         if ((LONG)mp2 & AWP_MINIMIZED)%@NL@%
  3879.             WinShowWindow(WinWindowFromID(hwnd, MBID_OK), FALSE);%@NL@%
  3880.         else if ((LONG)mp2 & AWP_RESTORED)%@NL@%
  3881.             WinShowWindow(WinWindowFromID(hwnd, MBID_OK), TRUE);%@NL@%
  3882.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  3883.         break;%@NL@%
  3884. %@NL@%
  3885.     case WM_COMMAND:%@NL@%
  3886.         WinDestroyWindow(hwnd);%@NL@%
  3887.         break;%@NL@%
  3888.         %@NL@%
  3889.     case WM_PAINT:%@NL@%
  3890.         WinDefDlgProc(hwnd, msg, mp1, mp2);%@NL@%
  3891.         %@AB@%/*%@NL@%
  3892. %@AB@%         * draw the bitmap just above the OK button.%@NL@%
  3893. %@AB@%         */%@AE@%%@NL@%
  3894.         hps = WinGetPS(hwnd);%@NL@%
  3895.         WinQueryWindowRect(WinWindowFromID(hwnd, MBID_OK), (PRECTL)&wrc);%@NL@%
  3896.         WinMapWindowPoints(WinWindowFromID(hwnd, MBID_OK), hwnd, (PPOINTL)&wrc, 2);%@NL@%
  3897.         wrc.yBottom = wrc.yTop + cyText / 2;%@NL@%
  3898.         hbm = ((NPPKT)WinQueryWindowUShort(hwnd, QWS_USER))->hbm;%@NL@%
  3899.         WinDrawBitmap(hps, hbm, (PRECTL)NULL, (PPOINTL)&wrc, 0L, 0L, DBM_NORMAL);%@NL@%
  3900.         WinReleasePS(hps);%@NL@%
  3901.         break;%@NL@%
  3902. %@NL@%
  3903.     default:%@NL@%
  3904.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  3905.     }%@NL@%
  3906.     return(0);%@NL@%
  3907. }%@NL@%
  3908. %@NL@%
  3909. %@NL@%
  3910. MRESULT bmpInit(hwnd, ppktInit)%@NL@%
  3911. HWND hwnd;%@NL@%
  3912. NPPKT ppktInit;%@NL@%
  3913. {%@NL@%
  3914.     char szTitle[MAX_TITLESTR];%@NL@%
  3915.     WRECT wrc;%@NL@%
  3916.     NPPKT ppkt;%@NL@%
  3917.     SHORT cxMin;%@NL@%
  3918. %@NL@%
  3919.     if (!(ppkt = (NPPKT)WinAllocMem(hheap, sizeof(PKT))))%@NL@%
  3920.         return(1);    %@NL@%
  3921.     *ppkt = *ppktInit;%@NL@%
  3922.     WinSetWindowUShort(hwnd, QWL_USER, (USHORT)ppkt);%@NL@%
  3923.     %@AB@%/*%@NL@%
  3924. %@AB@%     * This is required because currently, automatic ICON resource loading%@NL@%
  3925. %@AB@%     * is not supported for dialogs.%@NL@%
  3926. %@AB@%     */%@AE@%%@NL@%
  3927.     WinSendMsg(hwnd, WM_SETICON, (MPARAM)hptrBmap, 0L);%@NL@%
  3928.     %@AB@%/*%@NL@%
  3929. %@AB@%     * Set up title.%@NL@%
  3930. %@AB@%     */%@AE@%%@NL@%
  3931.     WinQueryWindowText(hwnd, MAX_TITLESTR, (PSZ)szTitle);%@NL@%
  3932.     lstrcat(szTitle, szTitle, ppkt->szName);%@NL@%
  3933.     WinSetWindowText(hwnd, (PSZ)szTitle);%@NL@%
  3934.     %@AB@%/*%@NL@%
  3935. %@AB@%     * resize the dialog so the bitmap just fits.%@NL@%
  3936. %@AB@%     */%@AE@%%@NL@%
  3937.     WinQueryWindowRect(hwnd, (PRECTL)&wrc);%@NL@%
  3938.     cxMin = wrc.xRight;%@NL@%
  3939.     WinQueryWindowRect(WinWindowFromID(hwnd, MBID_OK), (PRECTL)&wrc);%@NL@%
  3940.     WinMapWindowPoints(WinWindowFromID(hwnd, MBID_OK), hwnd, (PPOINTL)&wrc, 2);%@NL@%
  3941.     WinSetWindowPos(hwnd, NULL, 0, 0, max(wrc.xLeft * 2 + ppkt->cx, cxMin),%@NL@%
  3942.             wrc.yTop + ppkt->cy + cyText +%@NL@%
  3943.             (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR), SWP_SIZE);%@NL@%
  3944.     return(0);%@NL@%
  3945. }%@NL@%
  3946. %@NL@%
  3947. %@NL@%
  3948. %@NL@%
  3949. MRESULT EXPENTRY SendBitmapDlgProc(hwnd, msg, mp1, mp2)%@NL@%
  3950. HWND hwnd;%@NL@%
  3951. USHORT msg;%@NL@%
  3952. MPARAM mp1;%@NL@%
  3953. MPARAM mp2;%@NL@%
  3954. {%@NL@%
  3955.     NPCDATA pcd;%@NL@%
  3956.     POINTL pt;%@NL@%
  3957.     HPS hps;%@NL@%
  3958. %@NL@%
  3959.     pcd = (NPCDATA)WinQueryWindowUShort(hwnd, QWS_USER);%@NL@%
  3960.     %@NL@%
  3961.     switch (msg) {%@NL@%
  3962.     case WM_INITDLG:%@NL@%
  3963.         return(sndBmapInit(hwnd, (NPUSERLIST)(SHORT)mp2));%@NL@%
  3964.         break;%@NL@%
  3965. %@NL@%
  3966.     case WM_DESTROY:%@NL@%
  3967.         WinFreeMem(hheap, (NPBYTE)pcd, sizeof(CDATA));%@NL@%
  3968.         break;%@NL@%
  3969.         %@NL@%
  3970.     case WM_COMMAND:%@NL@%
  3971.         switch (LOUSHORT(mp1)) {%@NL@%
  3972.         case IDC_SENDBITMAP:%@NL@%
  3973.             if (sndBmap(pcd))%@NL@%
  3974.                 WinDismissDlg(hwnd, 0);%@NL@%
  3975.             break;%@NL@%
  3976.             %@NL@%
  3977.         case MBID_CANCEL:                    %@NL@%
  3978.             WinDismissDlg(hwnd, 0);%@NL@%
  3979.             break;%@NL@%
  3980.             %@NL@%
  3981.         case IDC_SELECT:%@NL@%
  3982.             pcd->fSelect = TRUE;%@NL@%
  3983.             WinSetCapture(HWND_DESKTOP, hwnd);%@NL@%
  3984.             break;%@NL@%
  3985.         }%@NL@%
  3986.         break;%@NL@%
  3987. %@NL@%
  3988.     case WM_BUTTON1DOWN:%@NL@%
  3989.         if (pcd->fSelect) {%@NL@%
  3990.             if (pcd->hbm) {%@NL@%
  3991.                 GpiDeleteBitmap(pcd->hbm);%@NL@%
  3992.                 pcd->hbm = NULL;%@NL@%
  3993.             }%@NL@%
  3994.             WinSetRect(hab, &pcd->rcl, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1),%@NL@%
  3995.                     SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));%@NL@%
  3996.             WinMapWindowPoints(hwnd, (HWND)HWND_DESKTOP, (PPOINTL)&pcd->rcl, 2);%@NL@%
  3997.             hps = WinGetScreenPS(HWND_DESKTOP);%@NL@%
  3998.             DrawRgn(hps, &pcd->rcl);%@NL@%
  3999.             WinReleasePS(hps);%@NL@%
  4000.             pcd->fSelecting = TRUE;%@NL@%
  4001.         }%@NL@%
  4002.         break;%@NL@%
  4003. %@NL@%
  4004.     case WM_MOUSEMOVE:%@NL@%
  4005.         if (pcd->fSelect) {%@NL@%
  4006.             WinSetPointer(HWND_DESKTOP, hptrSelBmap);%@NL@%
  4007.         } else {%@NL@%
  4008.             WinSetPointer(HWND_DESKTOP,%@NL@%
  4009.                     WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));%@NL@%
  4010.         }%@NL@%
  4011.         if (pcd->fSelecting) {%@NL@%
  4012.             hps = WinGetScreenPS(HWND_DESKTOP);%@NL@%
  4013.             DrawRgn(hps, &pcd->rcl);    %@AB@%/* erase old rect */%@AE@%%@NL@%
  4014.             pt.x = SHORT1FROMMP(mp1);%@NL@%
  4015.             pt.y = SHORT2FROMMP(mp1);%@NL@%
  4016.             WinMapWindowPoints(hwnd, HWND_DESKTOP, &pt, 1);%@NL@%
  4017.             pcd->rcl.xRight = pt.x;%@NL@%
  4018.             pcd->rcl.yTop = pt.y;%@NL@%
  4019.             DrawRgn(hps, &pcd->rcl);    %@AB@%/* draw new one */%@AE@%%@NL@%
  4020.             WinReleasePS(hps);%@NL@%
  4021.         }%@NL@%
  4022.         break;%@NL@%
  4023. %@NL@%
  4024.     case WM_BUTTON1UP:%@NL@%
  4025.         if (pcd->fSelecting) {%@NL@%
  4026.             WinSetCapture(HWND_DESKTOP, (HWND)NULL);%@NL@%
  4027.             hps = WinGetScreenPS(HWND_DESKTOP);%@NL@%
  4028.             DrawRgn(hps, &pcd->rcl);%@NL@%
  4029.             pcd->hbm = SnapRegion(hps, &pcd->rcl);%@NL@%
  4030.             WinReleasePS(hps);%@NL@%
  4031.             pcd->fSelecting = FALSE;%@NL@%
  4032.             pcd->fSelect = FALSE;%@NL@%
  4033.             WinEnableWindow(WinWindowFromID(hwnd, IDC_SENDBITMAP),%@NL@%
  4034.                     !WinIsRectEmpty(hab, &pcd->rcl));%@NL@%
  4035.         }%@NL@%
  4036.         break;%@NL@%
  4037. %@NL@%
  4038.         %@NL@%
  4039.     default:%@NL@%
  4040.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  4041.         break;%@NL@%
  4042.     }%@NL@%
  4043.     return(0);%@NL@%
  4044. }%@NL@%
  4045. %@NL@%
  4046. %@NL@%
  4047. %@AB@%/*%@NL@%
  4048. %@AB@% * returns fFailed%@NL@%
  4049. %@AB@% */%@AE@%%@NL@%
  4050. MPARAM sndBmapInit(hwnd, pUserItem)%@NL@%
  4051. HWND hwnd;%@NL@%
  4052. NPUSERLIST pUserItem;%@NL@%
  4053. {%@NL@%
  4054.     NPCDATA pcd;%@NL@%
  4055.     char szTitle[MAX_TITLESTR];%@NL@%
  4056.     char szName[MAX_NAMESTR];%@NL@%
  4057.     %@NL@%
  4058.     if (!(pcd = (NPCDATA)WinAllocMem(hheap, sizeof(CDATA))))%@NL@%
  4059.         return(1);%@NL@%
  4060.     WinSetRectEmpty(hab, &pcd->rcl);%@NL@%
  4061.     pcd->hbm = NULL;%@NL@%
  4062.     pcd->fSelect = FALSE;%@NL@%
  4063.     pcd->fSelecting = FALSE;%@NL@%
  4064.     pcd->npUL = pUserItem;%@NL@%
  4065.     if (pcd->npUL->hConvMsg == NULL) {%@NL@%
  4066.         NotifyUser(SZCANTCONNECT);%@NL@%
  4067.         return(1);%@NL@%
  4068.     }%@NL@%
  4069.     WinQueryWindowText(hwnd, MAX_TITLESTR, szTitle);%@NL@%
  4070.     DdeGetHszString(pcd->npUL->hsz, szName, (LONG)MAX_NAMESTR);%@NL@%
  4071.     lstrcat(szTitle, szTitle, szName);%@NL@%
  4072.     WinSetWindowText(hwnd, (PSZ)szTitle);%@NL@%
  4073.     WinSetWindowUShort(hwnd, QWS_USER, (USHORT)pcd);%@NL@%
  4074.     return(0);%@NL@%
  4075. }%@NL@%
  4076. %@NL@%
  4077. %@NL@%
  4078. BOOL sndBmap(pcd)%@NL@%
  4079. NPCDATA pcd;%@NL@%
  4080. {%@NL@%
  4081.     BITMAPINFOHEADER bih;%@NL@%
  4082.     SHORT cbBuffer, cbBitmapInfo;%@NL@%
  4083.     PBYTE pbBuffer;%@NL@%
  4084.     PBITMAPINFO pbmi;%@NL@%
  4085.     PSZ pszName;%@NL@%
  4086.     SEL sel;%@NL@%
  4087.     HPS hps;%@NL@%
  4088.     HDC hdc;%@NL@%
  4089.     SIZEL size;%@NL@%
  4090.     %@NL@%
  4091.     %@AB@%/*%@NL@%
  4092. %@AB@%     * Compute the size of the image-data buffer and the bitmap information%@NL@%
  4093. %@AB@%     * structure.%@NL@%
  4094. %@AB@%     */%@AE@%%@NL@%
  4095.     GpiQueryBitmapParameters(pcd->hbm, &bih);%@NL@%
  4096.     cbBuffer = (((bih.cBitCount * bih.cx) + 31) / 32) * 4;%@NL@%
  4097.     if (cbBuffer > 0xFFFF / bih.cy / bih.cPlanes) {%@NL@%
  4098.         NotifyUser(SZTOOBIG);%@NL@%
  4099.         return(FALSE);%@NL@%
  4100.     }%@NL@%
  4101.     cbBuffer *= bih.cy * bih.cPlanes;%@NL@%
  4102.     cbBitmapInfo = sizeof(BITMAPINFO) +%@NL@%
  4103.         (sizeof(RGB) * (1 << bih.cBitCount));%@NL@%
  4104.     %@NL@%
  4105.     %@AB@%/*%@NL@%
  4106. %@AB@%     * Allocate memory for the image data-buffer and the bitmap information%@NL@%
  4107. %@AB@%     * structure.%@NL@%
  4108. %@AB@%     */%@AE@%%@NL@%
  4109.     DosAllocSeg(cbBuffer + cbBitmapInfo + MAX_NAMESTR + 1, &sel, 0);%@NL@%
  4110.     pszName = (PSZ)MAKEP(sel, 0);%@NL@%
  4111.     lstrcpy(pszName, szEmailName);%@NL@%
  4112.     pbmi = (PBITMAPINFO)(pszName + MAX_NAMESTR + 1);%@NL@%
  4113.     pbBuffer = (PBYTE)&pbmi->argbColor[1 << bih.cBitCount];%@NL@%
  4114.     *(PBITMAPINFOHEADER)pbmi = bih;%@NL@%
  4115. %@NL@%
  4116.     size.cx = (LONG)bih.cx;%@NL@%
  4117.     size.cy = (LONG)bih.cy;%@NL@%
  4118.     hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);%@NL@%
  4119.     hps = GpiCreatePS(hab, hdc, &size,%@NL@%
  4120.             PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );%@NL@%
  4121.     GpiSetBitmap(hps, pcd->hbm);%@NL@%
  4122.     GpiQueryBitmapBits(hps, 0L, (LONG)bih.cy, (PBYTE)pbBuffer,%@NL@%
  4123.             (PBITMAPINFO2)pbmi);%@NL@%
  4124.     GpiAssociate(hps, NULL);%@NL@%
  4125.     GpiDestroyPS(hps);%@NL@%
  4126.     DevCloseDC(hdc);%@NL@%
  4127. %@NL@%
  4128.     if (!DdeClientXfer(pszName,%@NL@%
  4129.             (LONG)(cbBuffer + cbBitmapInfo + MAX_NAMESTR + 1),%@NL@%
  4130.             pcd->npUL->hConvMsg,%@NL@%
  4131.             msgTopicItemList[IIL_BMPXFER].hszItem,%@NL@%
  4132.             fmtBmapPkt, XTYP_POKE, ulTimeout, 0L)) {%@NL@%
  4133.         MyPostError(DdeGetLastError());%@NL@%
  4134.     }%@NL@%
  4135. %@NL@%
  4136.     DosFreeSeg(sel);%@NL@%
  4137.     GpiDeleteBitmap(pcd->hbm);%@NL@%
  4138.     pcd->hbm = NULL;%@NL@%
  4139.     WinSetRectEmpty(hab, &pcd->rcl);%@NL@%
  4140.     return(TRUE);%@NL@%
  4141. }%@NL@%
  4142. %@NL@%
  4143. %@NL@%
  4144. HBITMAP SnapRegion(hps, prcl)%@NL@%
  4145. HPS hps;%@NL@%
  4146. PRECTL prcl;%@NL@%
  4147. {%@NL@%
  4148.     HDC hdc;%@NL@%
  4149.     HBITMAP hbm, hbmOld;%@NL@%
  4150.     BITMAPINFOHEADER bih;%@NL@%
  4151.     POINTL rgpt[3];%@NL@%
  4152.     HPS hpsMem;%@NL@%
  4153.     SIZEL size;%@NL@%
  4154. %@NL@%
  4155.     SortRect(prcl, prcl);%@NL@%
  4156.     WinInflateRect(hab, prcl, -1, -1);%@NL@%
  4157. %@NL@%
  4158.     size.cx = (USHORT)(prcl->xRight - prcl->xLeft);%@NL@%
  4159.     size.cy = (USHORT)(prcl->yTop - prcl->yBottom);%@NL@%
  4160. %@NL@%
  4161.     %@AB@%/* Create a memory DC */%@AE@%%@NL@%
  4162.     hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);%@NL@%
  4163. %@NL@%
  4164.     %@AB@%/* create a memory PS */%@AE@%%@NL@%
  4165.     hpsMem = GpiCreatePS(hab, hdc, &size,%@NL@%
  4166.             PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );%@NL@%
  4167. %@NL@%
  4168.     %@AB@%/* Create a bitmap */%@AE@%%@NL@%
  4169.     bih.cbFix = sizeof(BITMAPINFOHEADER);%@NL@%
  4170.     bih.cx = (SHORT)size.cx;%@NL@%
  4171.     bih.cy = (SHORT)size.cy;%@NL@%
  4172.     bih.cPlanes = 1;%@NL@%
  4173.     bih.cBitCount = 8;%@NL@%
  4174.     hbm = GpiCreateBitmap(hpsMem, (PBITMAPINFOHEADER2)&bih, 0L, 0, 0);%@NL@%
  4175.     if (hbm == GPI_ERROR) %@NL@%
  4176.         return(0);%@NL@%
  4177.     %@NL@%
  4178.     %@AB@%/* put the bitmap into the memory PS */%@AE@%%@NL@%
  4179.     hbmOld = GpiSetBitmap(hpsMem, hbm);%@NL@%
  4180. %@NL@%
  4181.     %@AB@%/* copy the window to the memory PS */%@AE@%%@NL@%
  4182.     rgpt[0].x = 0;%@NL@%
  4183.     rgpt[0].y = 0;%@NL@%
  4184.     rgpt[1].x = size.cx;%@NL@%
  4185.     rgpt[1].y = size.cy;%@NL@%
  4186.     rgpt[2].x = prcl->xLeft;%@NL@%
  4187.     rgpt[2].y = prcl->yBottom;%@NL@%
  4188.     GpiBitBlt(hpsMem, hps, 3L, (PPOINTL)&rgpt[0], ROP_SRCCOPY, 0L);%@NL@%
  4189. %@NL@%
  4190.     %@AB@%/* free the bitmap */%@AE@%%@NL@%
  4191.     GpiSetBitmap(hpsMem, hbmOld);%@NL@%
  4192. %@NL@%
  4193.     %@AB@%/* destroy the memory DC */%@AE@%%@NL@%
  4194.     GpiAssociate(hpsMem, NULL);%@NL@%
  4195.     GpiDestroyPS(hpsMem);%@NL@%
  4196.     DevCloseDC(hdc);%@NL@%
  4197.     return(hbm);%@NL@%
  4198. } %@AB@%/* end snapregion */%@AE@%%@NL@%
  4199. %@NL@%
  4200. %@NL@%
  4201. HDC CreateDC(lpszDriver, hdcCompat)%@NL@%
  4202. PSZ  lpszDriver;%@NL@%
  4203. HDC hdcCompat;%@NL@%
  4204. {%@NL@%
  4205.     struct {%@NL@%
  4206.         ULONG FAR *lpLogAddr;%@NL@%
  4207.         PSZ  lpszDriver;%@NL@%
  4208.     } opendc;%@NL@%
  4209. %@NL@%
  4210.     opendc.lpLogAddr = NULL;%@NL@%
  4211.     opendc.lpszDriver = lpszDriver;%@NL@%
  4212. %@NL@%
  4213.     return((HDC)DevOpenDC(hab, OD_MEMORY, (PSZ)"*", 2L,%@NL@%
  4214.             (PDEVOPENDATA)&opendc, hdcCompat));%@NL@%
  4215. }%@NL@%
  4216. %@NL@%
  4217. %@NL@%
  4218. void DrawRgn(hps, prcl)%@NL@%
  4219. HPS hps;%@NL@%
  4220. PRECTL prcl;%@NL@%
  4221. {%@NL@%
  4222.     RECTL rclSorted;%@NL@%
  4223.     %@NL@%
  4224.     SortRect(prcl, &rclSorted);%@NL@%
  4225.     WinDrawBorder(hps, &rclSorted, 1, 1, SYSCLR_WINDOW, SYSCLR_WINDOW,%@NL@%
  4226.             DB_DESTINVERT | DB_STANDARD);%@NL@%
  4227. }%@NL@%
  4228. %@NL@%
  4229. void SortRect(prcl, prclSorted)%@NL@%
  4230. PRECTL prcl;%@NL@%
  4231. PRECTL prclSorted;%@NL@%
  4232. {%@NL@%
  4233.     LONG l;%@NL@%
  4234. %@NL@%
  4235.     WinCopyRect(hab, prclSorted, prcl);%@NL@%
  4236.     if (prclSorted->yTop < prclSorted->yBottom) {%@NL@%
  4237.         l = prclSorted->yBottom;%@NL@%
  4238.         prclSorted->yBottom = prclSorted->yTop;%@NL@%
  4239.         prclSorted->yTop = l;%@NL@%
  4240.     }%@NL@%
  4241.     %@NL@%
  4242.     if (prclSorted->xRight < prclSorted-> xLeft) {%@NL@%
  4243.         l = prclSorted->xRight;%@NL@%
  4244.         prclSorted->xRight = prclSorted->xLeft;%@NL@%
  4245.         prclSorted->xLeft = l;%@NL@%
  4246.     }%@NL@%
  4247. }%@NL@%
  4248. %@NL@%
  4249. %@NL@%
  4250. %@NL@%
  4251. %@NL@%
  4252. %@NL@%
  4253. %@NL@%
  4254. %@2@%%@AH@%BROWSE.C%@AE@%%@EH@%%@NL@%
  4255. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\BROWSE\AVBROWSE\BROWSE.C%@AE@%%@NL@%
  4256. %@NL@%
  4257. %@AB@%/*%@NL@%
  4258. %@AB@%    browse.c -- AVIO File Browsing Utility%@NL@%
  4259. %@AB@%%@NL@%
  4260. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  4261. %@AB@%*/%@AE@%%@NL@%
  4262. %@AI@%#define %@AE@%       INCL_WINTRACKRECT %@NL@%
  4263. %@AI@%#define %@AE@%       INCL_WINWINDOWMGR %@NL@%
  4264. %@AI@%#define %@AE@%       INCL_WINPOINTERS %@NL@%
  4265. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  4266. %@AI@%#include %@AE@%<os2.h> %@NL@%
  4267. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  4268. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  4269. %@AI@%#include %@AE@%<string.h> %@NL@%
  4270. %@AI@%#include %@AE@%"avio.h" %@NL@%
  4271. %@AI@%#include %@AE@%"browse.h" %@NL@%
  4272. %@AI@%#include %@AE@%<opendlg.h> %@NL@%
  4273. %@AB@%/*%@NL@%
  4274. %@AB@%    Constants%@NL@%
  4275. %@AB@%*/%@AE@%%@NL@%
  4276. %@AI@%#define %@AE@%MAXLINELEN        120 %@NL@%
  4277. %@AI@%#define %@AE@%AVIO_PS_ROWS        25 %@NL@%
  4278. %@AI@%#define %@AE@%       AVIO_PS_COLS        80 %@NL@%
  4279. %@AB@%/*%@NL@%
  4280. %@AB@%    Global Variables%@NL@%
  4281. %@AB@%*/%@AE@%%@NL@%
  4282. FILE        *pfInput;%@NL@%
  4283. PFNWP        pfnOldClient;%@NL@%
  4284. char        *aszLines[NUM_DATA_LINES];%@NL@%
  4285. SHORT        sTopLine = 0;%@NL@%
  4286. DLF        dlfInput;%@NL@%
  4287. HFILE        hfInput;%@NL@%
  4288. USHORT        usAction;%@NL@%
  4289. LBINFO        lbiData;%@NL@%
  4290. HPOINTER hptrWait;%@NL@%
  4291. HPOINTER hptrArrow;%@NL@%
  4292. HWND        hWndClient;%@NL@%
  4293. HWND        hWndFrame;%@NL@%
  4294. BOOL        fLargeFont = FALSE;%@NL@%
  4295. SHORT        sMaxLine;%@NL@%
  4296. %@AB@%/*%@NL@%
  4297. %@AB@%    Open the input file%@NL@%
  4298. %@AB@%*/%@AE@%%@NL@%
  4299. int cdecl main(int argc, char *argv[]) {%@NL@%
  4300.      static CHAR szClientClass[] = "Browse";%@NL@%
  4301.      static CHAR szCaption[]         = "";%@NL@%
  4302.      HAB        hAB;%@NL@%
  4303.      HMQ        hmq;%@NL@%
  4304.      QMSG        qmsg;%@NL@%
  4305.      ULONG        flFrameFlags = FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL;%@NL@%
  4306.      ULONG         flFrameStyle = WS_VISIBLE | FS_SCREENALIGN;%@NL@%
  4307.      char        *szInFile;%@NL@%
  4308. %@NL@%
  4309.      hAB = WinInitialize(0);%@NL@%
  4310.      hmq = WinCreateMsgQueue(hAB, 0);%@NL@%
  4311. %@NL@%
  4312.      WinRegisterClass(hAB, szClientClass, BrowseWndProc, CS_SYNCPAINT, 0);%@NL@%
  4313. %@NL@%
  4314.      hWndFrame = WinCreateStdWindow(HWND_DESKTOP, flFrameStyle,%@NL@%
  4315.                                     &flFrameFlags, szClientClass, szCaption,%@NL@%
  4316.                                      0L, (HMODULE) NULL, ID_RESOURCE, &hWndClient);%@NL@%
  4317.      %@AB@%/*%@NL@%
  4318. %@AB@%        Get the hourglass and arrow pointers%@NL@%
  4319. %@AB@%     */%@AE@%%@NL@%
  4320.      hptrWait  = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT,  FALSE);%@NL@%
  4321.      hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);%@NL@%
  4322. %@NL@%
  4323.      if (argc == 1) pfInput = stdin;%@NL@%
  4324.      else {%@NL@%
  4325.         if (!(pfInput = fopen(argv[1], "r"))) {%@NL@%
  4326.             fprintf(stderr, "***Error:  Could not open %s", szInFile);%@NL@%
  4327.             return(-1);%@NL@%
  4328.         }%@NL@%
  4329.      }%@NL@%
  4330.      ReadFile();%@NL@%
  4331.      %@AB@%/*%@NL@%
  4332. %@AB@%        Setup AVIO PS and force a paint%@NL@%
  4333. %@AB@%        Note:  This subclasses the client and frame windows%@NL@%
  4334. %@AB@%     */%@AE@%%@NL@%
  4335.      lbiData.sPSrows        = AVIO_PS_ROWS;%@NL@%
  4336.      lbiData.sPScols        = AVIO_PS_COLS;%@NL@%
  4337.      lbiData.sRows        = sTopLine;%@NL@%
  4338.      lbiData.sCols        = sMaxLine;%@NL@%
  4339.      lbiData.pfnQL        = (PFNQL) RetrieveLine;%@NL@%
  4340.      lbiData.fLargeFont        = FALSE;%@NL@%
  4341.      AvioInit(&lbiData);%@NL@%
  4342.      %@AB@%/*%@NL@%
  4343. %@AB@%        Process messages%@NL@%
  4344. %@AB@%     */%@AE@%%@NL@%
  4345.      while (WinGetMsg(hAB, &qmsg, NULL, 0, 0)) WinDispatchMsg(hAB, &qmsg);%@NL@%
  4346. %@NL@%
  4347.      %@AB@%/* Blast the AVIO PS */%@AE@%%@NL@%
  4348.      AvioClose();%@NL@%
  4349. %@NL@%
  4350.      WinDestroyWindow(hWndFrame);%@NL@%
  4351.      WinDestroyMsgQueue(hmq);%@NL@%
  4352.      WinTerminate(hAB);%@NL@%
  4353.      return 0;%@NL@%
  4354. }%@NL@%
  4355. %@NL@%
  4356. void ReadFile(void) {%@NL@%
  4357. %@AB@%/*%@NL@%
  4358. %@AB@%    Reads in a file using <stdio.h> fgets() calls.%@NL@%
  4359. %@AB@%    It might be wise to put better word wrap facilities here%@NL@%
  4360. %@AB@%*/%@AE@%%@NL@%
  4361.     char        szLine[MAXLINELEN];%@NL@%
  4362. %@NL@%
  4363.     %@AB@%/* Put up the hourglass */%@AE@%%@NL@%
  4364.     WinSetPointer(HWND_DESKTOP, hptrWait);%@NL@%
  4365. %@NL@%
  4366.     %@AB@%/* Reinitialize buffer, MaxLineLength */%@AE@%%@NL@%
  4367.     for (; sTopLine > 0; ) free(aszLines[--sTopLine]);%@NL@%
  4368.     sMaxLine = 0;%@NL@%
  4369. %@NL@%
  4370.     %@AB@%/* Read in the file */%@AE@%%@NL@%
  4371.     while (fgets(szLine, MAXLINELEN, pfInput)) {%@NL@%
  4372. %@NL@%
  4373.         %@AB@%/* Convert LF (\n) into NULL (\0) */%@AE@%%@NL@%
  4374.         if (szLine[strlen(szLine) - 1] == '\n') {%@NL@%
  4375.             szLine[strlen(szLine) - 1] = 0;%@NL@%
  4376.         } else szLine[MAXLINELEN - 1] = 0;%@NL@%
  4377. %@NL@%
  4378.         if (StoreLine(szLine)) {%@NL@%
  4379.             fprintf(stderr,"***Error:  Line buffer full\n");%@NL@%
  4380.             return;%@NL@%
  4381.         }%@NL@%
  4382.     }%@NL@%
  4383.     fclose(pfInput);%@NL@%
  4384. %@NL@%
  4385.     %@AB@%/* Reset the mouse pointer */%@AE@%%@NL@%
  4386.     WinSetPointer(HWND_DESKTOP, hptrArrow);%@NL@%
  4387. %@NL@%
  4388.     return;%@NL@%
  4389. }%@NL@%
  4390. %@NL@%
  4391. SHORT StoreLine(char *szLine) {%@NL@%
  4392. %@AB@%/*%@NL@%
  4393. %@AB@%    Put a line into the line buffer; line numbers are free%@NL@%
  4394. %@AB@%    For > 64K data, add code here and in RetrieveLine%@NL@%
  4395. %@AB@%*/%@AE@%%@NL@%
  4396.     int                i, cLinePos;%@NL@%
  4397.     BOOL        fDone;%@NL@%
  4398.     %@AB@%/*%@NL@%
  4399. %@AB@%        Check if top line exceeded, or malloc() fails%@NL@%
  4400. %@AB@%    */%@AE@%%@NL@%
  4401.     if (sTopLine == NUM_DATA_LINES)  return -1;%@NL@%
  4402.     %@AB@%/*%@NL@%
  4403. %@AB@%        Compute line length with tabs expanded%@NL@%
  4404. %@AB@%    */%@AE@%%@NL@%
  4405.     cLinePos = 0;%@NL@%
  4406.     for (i = 0; i < MAXLINELEN; i++) {%@NL@%
  4407.         switch(szLine[i]) {%@NL@%
  4408.             case '\0':%@NL@%
  4409.                 cLinePos++; i = MAXLINELEN;%@NL@%
  4410.                 break;%@NL@%
  4411.             case '\t':%@NL@%
  4412.                 do {%@NL@%
  4413.                     cLinePos++;%@NL@%
  4414.                 } while (cLinePos % 8);%@NL@%
  4415.                 break;%@NL@%
  4416. %@NL@%
  4417.             default:%@NL@%
  4418.                 cLinePos++;%@NL@%
  4419.         }%@NL@%
  4420. %@NL@%
  4421.     }%@NL@%
  4422.     if (cLinePos > sMaxLine) sMaxLine = cLinePos;%@NL@%
  4423.     if (!(aszLines[sTopLine] = malloc(cLinePos))) return -1;%@NL@%
  4424.     %@AB@%/*%@NL@%
  4425. %@AB@%        Copy szLine into the line buffer.  Expand tabs here.%@NL@%
  4426. %@AB@%    */%@AE@%%@NL@%
  4427.     i = cLinePos = 0; fDone = FALSE;%@NL@%
  4428.     while ((i <= MAXLINELEN) && (!fDone)) {%@NL@%
  4429.         switch(szLine[i]) {%@NL@%
  4430.             case '\t':%@NL@%
  4431.                 do {%@NL@%
  4432.                     aszLines[sTopLine][cLinePos++] = ' ';%@NL@%
  4433.                 } while (cLinePos % 8);%@NL@%
  4434.                 break;%@NL@%
  4435. %@NL@%
  4436.             default:%@NL@%
  4437.                 aszLines[sTopLine][cLinePos++] = szLine[i];%@NL@%
  4438.                 fDone = !szLine[i];%@NL@%
  4439.                 break;%@NL@%
  4440.         }%@NL@%
  4441.         i++;%@NL@%
  4442.     }%@NL@%
  4443.     sTopLine++;%@NL@%
  4444.     return 0;%@NL@%
  4445. }%@NL@%
  4446. %@NL@%
  4447. char * _loadds RetrieveLine(USHORT usLineNum) {%@NL@%
  4448. %@AB@%/*%@NL@%
  4449. %@AB@%    Return line numbered usLineNum%@NL@%
  4450. %@AB@%*/%@AE@%%@NL@%
  4451.     if ((SHORT) usLineNum >= sTopLine) {                %@AB@%/* Out of range */%@AE@%%@NL@%
  4452.         return NULL;%@NL@%
  4453.     }%@NL@%
  4454.     return aszLines[usLineNum];%@NL@%
  4455. }%@NL@%
  4456. %@NL@%
  4457. MRESULT CALLBACK BrowseWndProc(hWnd, msg, mp1, mp2)%@NL@%
  4458. HWND hWnd;%@NL@%
  4459. USHORT msg;%@NL@%
  4460. MPARAM mp1;%@NL@%
  4461. MPARAM mp2;%@NL@%
  4462. {%@NL@%
  4463. %@AB@%/*%@NL@%
  4464. %@AB@%    Handle the About... and Open... messages%@NL@%
  4465. %@AB@%*/%@AE@%%@NL@%
  4466.     switch(msg) {%@NL@%
  4467.         case WM_COMMAND:%@NL@%
  4468.             switch (COMMANDMSG(&msg)->cmd) {%@NL@%
  4469.                 case IDM_ABOUT:%@NL@%
  4470.                     WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,%@NL@%
  4471.                               (HMODULE) NULL, IDD_ABOUT, NULL);%@NL@%
  4472.                     return 0;%@NL@%
  4473. %@NL@%
  4474.                 case IDM_OPEN:%@NL@%
  4475.                     %@AB@%/*%@NL@%
  4476. %@AB@%                        Open the file, using the file dialog%@NL@%
  4477. %@AB@%                        then reopen it with stdio calls%@NL@%
  4478. %@AB@%                    */%@AE@%%@NL@%
  4479.                     SetupDLF(&dlfInput, DLG_OPENDLG, &hfInput,%@NL@%
  4480.                         "\\*.*", NULL, "Browse Open File",%@NL@%
  4481.                         "Select a file to be browsed.");%@NL@%
  4482.                     DlgFile(hWnd, &dlfInput);%@NL@%
  4483.                     pfInput = fopen(dlfInput.szOpenFile, "r");%@NL@%
  4484.                     ReadFile();%@NL@%
  4485.                     %@AB@%/*%@NL@%
  4486. %@AB@%                        Close the opened handle%@NL@%
  4487. %@AB@%                    */%@AE@%%@NL@%
  4488.                     DosClose(hfInput);%@NL@%
  4489. %@NL@%
  4490.                     %@AB@%/* Fix up the screen display */%@AE@%%@NL@%
  4491.                     lbiData.sRows = sTopLine;%@NL@%
  4492.                     lbiData.sCols = sMaxLine;%@NL@%
  4493.                     lbiData.fLargeFont = fLargeFont;%@NL@%
  4494.                     AvioInit(&lbiData);%@NL@%
  4495. %@NL@%
  4496.                     return 0;%@NL@%
  4497. %@NL@%
  4498.                 case IDM_FONT:%@NL@%
  4499.                     AvioLargeFont(fLargeFont = !fLargeFont);%@NL@%
  4500.                        return 0;%@NL@%
  4501. %@NL@%
  4502.                 default: return 0;%@NL@%
  4503.             }%@NL@%
  4504.             break;%@NL@%
  4505.         default: return WinDefWindowProc(hWnd, msg, mp1, mp2);%@NL@%
  4506.     }%@NL@%
  4507.     return 0L;%@NL@%
  4508. }%@NL@%
  4509. %@NL@%
  4510. MRESULT CALLBACK AboutDlgProc(hDlg, msg, mp1, mp2)%@NL@%
  4511. %@AB@%/*%@NL@%
  4512. %@AB@%    About... dialog procedure%@NL@%
  4513. %@AB@%*/%@AE@%%@NL@%
  4514. HWND        hDlg;%@NL@%
  4515. USHORT        msg;%@NL@%
  4516. MPARAM        mp1;%@NL@%
  4517. MPARAM        mp2;%@NL@%
  4518. {%@NL@%
  4519.     switch(msg) {%@NL@%
  4520.         case WM_COMMAND:%@NL@%
  4521.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  4522.                 case DID_OK: WinDismissDlg(hDlg, TRUE); break;%@NL@%
  4523.                 default: break;%@NL@%
  4524.             }%@NL@%
  4525.         default: return WinDefDlgProc(hDlg, msg, mp1, mp2);%@NL@%
  4526.     }%@NL@%
  4527.     return FALSE;%@NL@%
  4528. }%@NL@%
  4529. %@NL@%
  4530. %@NL@%
  4531. %@2@%%@AH@%BROWSE.C%@AE@%%@EH@%%@NL@%
  4532. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\BROWSE\VBROWSE\BROWSE.C%@AE@%%@NL@%
  4533. %@NL@%
  4534. %@AB@%/*%@NL@%
  4535. %@AB@%    VIO File Browsing Application%@NL@%
  4536. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  4537. %@AB@%*/%@AE@%%@NL@%
  4538. %@AI@%#define %@AE@%        INCL_KBD %@NL@%
  4539. %@AI@%#define %@AE@%        INCL_VIO %@NL@%
  4540. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  4541. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  4542. %@AI@%#include %@AE@%<os2.h> %@NL@%
  4543. %@AI@%#include %@AE@%<string.h> %@NL@%
  4544. %@AI@%#include %@AE@%"browse.h" %@NL@%
  4545. %@AB@%/*%@NL@%
  4546. %@AB@%    Global Variables%@NL@%
  4547. %@AB@%*/%@AE@%%@NL@%
  4548. FILE        *pfInput;%@NL@%
  4549. char        *aszLines[NUM_DATA_LINES];%@NL@%
  4550. SHORT        sTopLine= -1;%@NL@%
  4551. SHORT        sRows;%@NL@%
  4552. SHORT        HorScrollPos=0;%@NL@%
  4553. BYTE        abBlank[2] = { 0x20, 0x07 }; %@NL@%
  4554. %@NL@%
  4555. %@AB@%/*%@NL@%
  4556. %@AB@%    Macros for Vio calls%@NL@%
  4557. %@AB@%    The last parameter is zero because we're using a VIO PS%@NL@%
  4558. %@AB@%*/%@AE@%%@NL@%
  4559. %@AI@%#define %@AE@%ClearScreen()        VioScrollDn(0, 0, -1, -1, -1, abBlank, 0) %@NL@%
  4560. %@AI@%#define %@AE@%       Move(r,c)        VioSetCurPos(r, c, 0) %@NL@%
  4561. %@AI@%#define %@AE@%ScrollDown(n)        VioScrollDn(0, 0, -1, -1,  n, abBlank, 0) %@NL@%
  4562. %@AI@%#define %@AE@%ScrollUp(n)        VioScrollUp(0, 0, -1, -1,  n, abBlank, 0) %@NL@%
  4563. %@AI@%#define %@AE@%Write(s)        VioWrtTTY(s, strlen(s), 0) %@NL@%
  4564. %@AB@%/*%@NL@%
  4565. %@AB@%    Macros for bounds checking%@NL@%
  4566. %@AB@%*/%@AE@%%@NL@%
  4567. %@AI@%#define %@AE@%Abs(x)                (((x) > 0) ? (x) : (-(x))) %@NL@%
  4568. %@AI@%#define %@AE@%Max(x, y)        (((x) > (y)) ? (x) : (y)) %@NL@%
  4569. %@AI@%#define %@AE@%Min(x, y)        (((x) < (y)) ? (x) : (y)) %@NL@%
  4570. %@AI@%#define %@AE@%LowerBound(pos, disp, lbound)        Max(pos - disp, lbound) %@NL@%
  4571. %@AI@%#define %@AE@%UpperBound(pos, disp, ubound)        Min(pos + disp, ubound) %@NL@%
  4572. %@NL@%
  4573. %@AB@%/*%@NL@%
  4574. %@AB@%    Functions%@NL@%
  4575. %@AB@%*/%@AE@%%@NL@%
  4576. int cdecl main(int argc, char *argv[]) {%@NL@%
  4577. %@AB@%/*%@NL@%
  4578. %@AB@%    Open the input file and initialize globals%@NL@%
  4579. %@AB@%*/%@AE@%%@NL@%
  4580.     char        *szFilename;%@NL@%
  4581.     VIOMODEINFO        viomiMode;%@NL@%
  4582. %@NL@%
  4583.     %@AB@%/*%@NL@%
  4584. %@AB@%        Open the Input File%@NL@%
  4585. %@AB@%    */%@AE@%%@NL@%
  4586.     if (argc == 1)%@NL@%
  4587.         pfInput = stdin;%@NL@%
  4588.     else {%@NL@%
  4589.         szFilename = argv[1];%@NL@%
  4590.         if (!(pfInput = fopen(szFilename,"r"))) {%@NL@%
  4591.             fprintf(stderr, "***Error:  Could not open %s", szFilename);%@NL@%
  4592.             return(-1);%@NL@%
  4593.         }%@NL@%
  4594.     }%@NL@%
  4595.     %@AB@%/*%@NL@%
  4596. %@AB@%        Read it into the line buffer%@NL@%
  4597. %@AB@%    */%@AE@%%@NL@%
  4598.     if (ReadFile()) return(-1);%@NL@%
  4599.     %@AB@%/*%@NL@%
  4600. %@AB@%        Get the video parameters%@NL@%
  4601. %@AB@%    */%@AE@%%@NL@%
  4602.     viomiMode.cb = sizeof(viomiMode);%@NL@%
  4603.     VioGetMode(&viomiMode, 0);%@NL@%
  4604.     sRows = (SHORT) viomiMode.row;%@NL@%
  4605. %@NL@%
  4606.     DisplayScreen(0, TRUE);%@NL@%
  4607.     ManipulateFile();%@NL@%
  4608. %@NL@%
  4609.     return 0;%@NL@%
  4610. }%@NL@%
  4611. %@NL@%
  4612. SHORT ReadFile(VOID) {%@NL@%
  4613. %@AB@%/*%@NL@%
  4614. %@AB@%    Read lines from the file into the line buffer%@NL@%
  4615. %@AB@%    If there's an error, abort the program (return -1)%@NL@%
  4616. %@AB@%*/%@AE@%%@NL@%
  4617.     char szLine[MAXLINELENGTH];%@NL@%
  4618. %@NL@%
  4619.     while (fgets(szLine, MAXLINELENGTH, pfInput)) {%@NL@%
  4620. %@NL@%
  4621.         %@AB@%/* Convert LF (\n) character to NULL (\0) */%@AE@%%@NL@%
  4622.         if (szLine[strlen(szLine)-1] == '\n')%@NL@%
  4623.             szLine[strlen(szLine)-1] = 0;%@NL@%
  4624.         else {%@NL@%
  4625.             fprintf(stderr,"***Error:  Incomplete line read\n");%@NL@%
  4626.             return(-1);%@NL@%
  4627.         }%@NL@%
  4628. %@NL@%
  4629.         %@AB@%/* Put the line into the line buffer */%@AE@%%@NL@%
  4630.         if (StoreLine(szLine)) {%@NL@%
  4631.             fprintf(stderr,"***Error:  Line buffer full\n");%@NL@%
  4632.             return(-1);%@NL@%
  4633.         }%@NL@%
  4634.     }%@NL@%
  4635. %@NL@%
  4636.     %@AB@%/* Close the Input file */%@AE@%%@NL@%
  4637.     fclose(pfInput);%@NL@%
  4638.     return 0;%@NL@%
  4639. }%@NL@%
  4640. %@NL@%
  4641. VOID ManipulateFile(VOID) {%@NL@%
  4642. %@AB@%/*%@NL@%
  4643. %@AB@%    Main loop for display processing%@NL@%
  4644. %@AB@%*/%@AE@%%@NL@%
  4645.     CHAR    ch;%@NL@%
  4646.     SHORT   sLine = 0;%@NL@%
  4647. %@NL@%
  4648.     %@AB@%/* The main command loop */%@AE@%%@NL@%
  4649.     while ((ch = GetKbdInput()) != ESC) {%@NL@%
  4650.         %@AB@%/*%@NL@%
  4651. %@AB@%            Take user input and compute new top line of screen%@NL@%
  4652. %@AB@%            by taking appropriate jump in jumptable.%@NL@%
  4653. %@AB@%%@NL@%
  4654. %@AB@%            Note:  no horizontal scrolling.%@NL@%
  4655. %@AB@%        */%@AE@%%@NL@%
  4656.         switch (ch) {%@NL@%
  4657.         case LINE_UP:         sLine = LowerBound(sLine, 1, 0);                break;%@NL@%
  4658.         case LINE_DOWN:  sLine = UpperBound(sLine, 1, BOTTOM);                break;%@NL@%
  4659.         case PAGE_UP:         sLine = LowerBound(sLine, sRows, 0);                break;%@NL@%
  4660.         case PAGE_DOWN:  sLine = UpperBound(sLine, sRows, BOTTOM);        break;%@NL@%
  4661.         case HOME_KEY:         sLine = 0;                                        break;%@NL@%
  4662.         case END_KEY:         sLine = BOTTOM;                                break;%@NL@%
  4663.         default:                                                        break;%@NL@%
  4664.         }%@NL@%
  4665.         DisplayScreen((USHORT) sLine, !ch);%@NL@%
  4666.     }%@NL@%
  4667. %@NL@%
  4668.     %@AB@%/* Set Cursor to the bottom of the screen */%@AE@%%@NL@%
  4669.     Move((USHORT) sRows - 1, 0);%@NL@%
  4670. }%@NL@%
  4671. %@NL@%
  4672. SHORT StoreLine(char *szLine) {%@NL@%
  4673. %@AB@%/*%@NL@%
  4674. %@AB@%    Put a line into the line buffer; line numbers are free%@NL@%
  4675. %@AB@%    For > 64K data, add code here and in RetrieveLine%@NL@%
  4676. %@AB@%*/%@AE@%%@NL@%
  4677.     %@AB@%/*%@NL@%
  4678. %@AB@%        Check if top line exceeded, or if malloc() fails%@NL@%
  4679. %@AB@%    */%@AE@%%@NL@%
  4680.     if ((sTopLine == NUM_DATA_LINES) ||%@NL@%
  4681.         ((aszLines[++sTopLine] = malloc(strlen(szLine) + 1)) == NULL))%@NL@%
  4682. %@NL@%
  4683.         return -1;%@NL@%
  4684.     %@AB@%/*%@NL@%
  4685. %@AB@%        Copy szLine into the line buffer%@NL@%
  4686. %@AB@%    */%@AE@%%@NL@%
  4687.     strcpy(aszLines[sTopLine], szLine);%@NL@%
  4688.     return 0;%@NL@%
  4689. }%@NL@%
  4690. %@NL@%
  4691. SHORT RetrieveLine(char **pszLine , USHORT usLineNum) {%@NL@%
  4692. %@AB@%/*%@NL@%
  4693. %@AB@%    Return line numbered usLineNum%@NL@%
  4694. %@AB@%*/%@AE@%%@NL@%
  4695.     if ((SHORT) usLineNum > sTopLine) return -1;  %@AB@%/* Out of range */%@AE@%%@NL@%
  4696.     *pszLine = aszLines[usLineNum];%@NL@%
  4697.     return 0;%@NL@%
  4698. }%@NL@%
  4699. %@NL@%
  4700. VOID DisplayScreen(USHORT usDisplayTop, BOOL fForceDraw) {%@NL@%
  4701. %@AB@%/*%@NL@%
  4702. %@AB@%    Display lines on the screen, starting at usDisplayTop%@NL@%
  4703. %@AB@%    by scrolling, then painting new information%@NL@%
  4704. %@AB@%*/%@AE@%%@NL@%
  4705.     SHORT            sDelta;%@NL@%
  4706.     static USHORT   usOldDispTop;%@NL@%
  4707. %@NL@%
  4708.     sDelta = usDisplayTop - usOldDispTop;%@NL@%
  4709.     %@AB@%/*%@NL@%
  4710. %@AB@%        If only a few lines need repainting...%@NL@%
  4711. %@AB@%    */%@AE@%%@NL@%
  4712.     if ((Abs(sDelta) < sRows) && !fForceDraw ) {%@NL@%
  4713.         %@AB@%/*%@NL@%
  4714. %@AB@%            Moving to a "higher line", so:%@NL@%
  4715. %@AB@%                Scroll down by the amount (make the difference positive)%@NL@%
  4716. %@AB@%                Paint in the lines at the top%@NL@%
  4717. %@AB@%        */%@AE@%%@NL@%
  4718.         if (sDelta < 0) {%@NL@%
  4719.             ScrollDown(-sDelta);%@NL@%
  4720.             Refresh(usDisplayTop, -sDelta, 0);%@NL@%
  4721.         } else {%@NL@%
  4722.             %@AB@%/*%@NL@%
  4723. %@AB@%                Moving to a "lower line", so:%@NL@%
  4724. %@AB@%                Scroll the information up, and paint at the bottom%@NL@%
  4725. %@AB@%            */%@AE@%%@NL@%
  4726.             ScrollUp(sDelta);%@NL@%
  4727.             Refresh(usDisplayTop + sRows - sDelta, sDelta, sRows - sDelta);%@NL@%
  4728.         }%@NL@%
  4729.     } else {        %@AB@%/* Paint the entire screen */%@AE@%%@NL@%
  4730.         ClearScreen();%@NL@%
  4731.         Refresh(usDisplayTop, sRows, 0);%@NL@%
  4732.     }%@NL@%
  4733.     usOldDispTop = usDisplayTop;%@NL@%
  4734. }%@NL@%
  4735. %@NL@%
  4736. VOID Refresh (USHORT iLine, USHORT usLines, USHORT usStart) {%@NL@%
  4737. %@AB@%/*%@NL@%
  4738. %@AB@%    Updates usLines lines, starting at line iLine in the line%@NL@%
  4739. %@AB@%    buffer, and line usStart on the screen%@NL@%
  4740. %@AB@%*/%@AE@%%@NL@%
  4741.     USHORT usLine;%@NL@%
  4742.     char   *szLine;%@NL@%
  4743. %@NL@%
  4744.     for (usLine = 0; usLine < usLines; usLine++) {%@NL@%
  4745.         %@AB@%/*%@NL@%
  4746. %@AB@%            Read the line, set the cursor, print the line%@NL@%
  4747. %@AB@%        */%@AE@%%@NL@%
  4748.         if (RetrieveLine(&szLine, (iLine + usLine))) break;%@NL@%
  4749.         Move((usStart + usLine), 0);%@NL@%
  4750.         Write(szLine);%@NL@%
  4751.     }%@NL@%
  4752. }%@NL@%
  4753. %@NL@%
  4754. CHAR GetKbdInput(VOID) {%@NL@%
  4755. %@AB@%/*%@NL@%
  4756. %@AB@%    Get chars, then check scan codes and return our own values%@NL@%
  4757. %@AB@%*/%@AE@%%@NL@%
  4758.     KBDKEYINFO kbciKeyInfo;%@NL@%
  4759. %@NL@%
  4760.     %@AB@%/*%@NL@%
  4761. %@AB@%        Wait for characters%@NL@%
  4762. %@AB@%    */%@AE@%%@NL@%
  4763.     KbdCharIn(&kbciKeyInfo, IO_WAIT, 0);%@NL@%
  4764. %@NL@%
  4765.     switch (kbciKeyInfo.chScan) {%@NL@%
  4766.         case ESC:                         %@AB@%/* escape */%@AE@%%@NL@%
  4767.         case LINE_UP:%@NL@%
  4768.         case LINE_DOWN:%@NL@%
  4769.         case PAGE_UP:%@NL@%
  4770.         case PAGE_DOWN:%@NL@%
  4771.         case HOME_KEY:%@NL@%
  4772.         case END_KEY:%@NL@%
  4773.             return kbciKeyInfo.chScan; break;%@NL@%
  4774.         default:%@NL@%
  4775.            return((CHAR) NULL); break;%@NL@%
  4776.     }%@NL@%
  4777. }%@NL@%
  4778. %@NL@%
  4779. %@NL@%
  4780. %@2@%%@AH@%CALC.C%@AE@%%@EH@%%@NL@%
  4781. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CALC\CALC.C%@AE@%%@NL@%
  4782. %@NL@%
  4783. %@AB@%/****************************** Module Header *********************************/%@AE@%%@NL@%
  4784. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4785. %@AB@%/* Module Name:  calc.c - Calc application                                      */%@AE@%%@NL@%
  4786. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4787. %@AB@%/* OS/2 Presentation Manager version of Calc, ported from Windows version     */%@AE@%%@NL@%
  4788. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4789. %@AB@%/* Created by Microsoft Corporation, 1987                                      */%@AE@%%@NL@%
  4790. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4791. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4792. %@NL@%
  4793. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  4794. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  4795. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  4796. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  4797. %@AI@%#define %@AE@%INCL_WINCLIPBOARD %@NL@%
  4798. %@AI@%#define %@AE@%INCL_GPIPRIMITIVES %@NL@%
  4799. %@AI@%#define %@AE@%INCL_GPIBITMAPS %@NL@%
  4800. %@AI@%#define %@AE@%INCL_GPILCIDS %@NL@%
  4801. %@AI@%#define %@AE@%INCL_DEV %@NL@%
  4802. %@AI@%#define %@AE@%INCL_ERRORS %@NL@%
  4803. %@AI@%#define %@AE@%INCL_DOSPROCESS %@NL@%
  4804. %@AI@%#define %@AE@%INCL_DOSSEMAPHORES %@NL@%
  4805. %@AI@%#define %@AE@%INCL_DOSNLS %@NL@%
  4806. %@AI@%#include %@AE@%<os2.h> %@NL@%
  4807. %@AI@%#include %@AE@%<string.h> %@NL@%
  4808. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  4809. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  4810. %@AI@%#include %@AE@%"calc.h" %@NL@%
  4811. %@NL@%
  4812. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4813. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4814. %@AB@%/*  GLOBAL VARIABLES                                                              */%@AE@%%@NL@%
  4815. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4816. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4817. %@NL@%
  4818. CHAR  chLastKey, chCurrKey;%@NL@%
  4819. CHAR  szreg1[20], szreg2[20], szmem[20], szregx[20];%@NL@%
  4820. CHAR  szTitle[30], szErrorString[20], szPlusMinus[2];%@NL@%
  4821. SHORT sCharWidth, sCharHeight;%@NL@%
  4822. extern BOOL fError;%@NL@%
  4823. BOOL  fValueInMemory = FALSE;%@NL@%
  4824. BOOL  fMDown = FALSE;                       %@AB@%/* TRUE iff 'm' key depressed  */%@AE@%%@NL@%
  4825. UCHAR uchMScan = 0;                       %@AB@%/* scan code for 'm' key       */%@AE@%%@NL@%
  4826. %@NL@%
  4827. %@AI@%#define %@AE@%TOLOWER(x)   ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x)) %@NL@%
  4828. %@AI@%#define %@AE@%WIDTHCONST  28 %@NL@%
  4829. %@AI@%#define %@AE@%CXCHARS     37 %@NL@%
  4830. %@AI@%#define %@AE@%CYCHARS     13 %@NL@%
  4831. %@NL@%
  4832. HAB hab;%@NL@%
  4833. HDC hdcLocal;                            %@AB@%/* Local used for button bitmap */%@AE@%%@NL@%
  4834. HPS hpsLocal;%@NL@%
  4835. HDC hdcSqr;                            %@AB@%/* Sqr used for square-root bitmap */%@AE@%%@NL@%
  4836. HPS hpsSqr;%@NL@%
  4837. HBITMAP hbmLocal, hbmSqr;%@NL@%
  4838. HMQ  hmqCalc;%@NL@%
  4839. HWND hwndCalc, hwndMenu;%@NL@%
  4840. HWND hwndCalcFrame;%@NL@%
  4841. HPS  hpsCalc;%@NL@%
  4842. HDC  hdcCalc;%@NL@%
  4843. HPOINTER hptrFinger;%@NL@%
  4844. %@NL@%
  4845. DEVOPENSTRUC dop =                    %@AB@%/* used by DevOpenDC */%@AE@%%@NL@%
  4846. {%@NL@%
  4847.     NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL%@NL@%
  4848. };%@NL@%
  4849. %@NL@%
  4850. static char achKeys[25] =               %@AB@%/* keyboard keys */%@AE@%%@NL@%
  4851. {%@NL@%
  4852.     '\271', '0', '.', '\261', '+', '=',%@NL@%
  4853.     '\272', '1', '2', '3', '-', 'c',%@NL@%
  4854.     '\273', '4', '5', '6', '*', '%',%@NL@%
  4855.     '\274', '7', '8', '9', '/', 'q',%@NL@%
  4856.     NULL%@NL@%
  4857. };%@NL@%
  4858. %@NL@%
  4859. static CHAR achDKeys[25] =    %@AB@%/* 4th key is plusminus */%@AE@%%@NL@%
  4860. {%@NL@%
  4861.     ' ', '0', '.', '+', '+', '=',%@NL@%
  4862.     ' ', '1', '2', '3', '-', 'C',%@NL@%
  4863.     ' ', '4', '5', '6', '*', '%',%@NL@%
  4864.     ' ', '7', '8', '9', '/', ' ',%@NL@%
  4865.     NULL%@NL@%
  4866. };%@NL@%
  4867. %@NL@%
  4868. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4869. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4870. %@AB@%/*  PROCEDURE DECLARATIONS                                                      */%@AE@%%@NL@%
  4871. %@AB@%/*                                                                              */%@AE@%%@NL@%
  4872. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4873. %@NL@%
  4874. VOID FarStrcpy( PSZ, PSZ);%@NL@%
  4875. MPARAM EXPENTRY AboutDlgProc( HWND, USHORT, MPARAM, MPARAM);%@NL@%
  4876. BOOL CalcInit(VOID);%@NL@%
  4877. VOID CalcPaint( HWND, HPS);%@NL@%
  4878. VOID CalcTextOut( HPS, INT, INT, PCH, INT);%@NL@%
  4879. MRESULT EXPENTRY CalcWndProc( HWND, USHORT, MPARAM, MPARAM);%@NL@%
  4880. VOID cdecl main(VOID);%@NL@%
  4881. VOID DataXCopy( VOID);%@NL@%
  4882. VOID DataXPaste( VOID);%@NL@%
  4883. VOID DrawNumbers( HPS);%@NL@%
  4884. VOID Evaluate(BYTE);%@NL@%
  4885. BOOL FlashSqr( HPS, PWPOINT);%@NL@%
  4886. VOID FlipKey( HPS, INT, INT);%@NL@%
  4887. VOID FrameKey( HPS, INT, INT);%@NL@%
  4888. VOID InitCalc( VOID);%@NL@%
  4889. BOOL InterpretChar( CHAR);%@NL@%
  4890. VOID ProcessKey( PWPOINT);%@NL@%
  4891. BOOL PSInit( VOID);%@NL@%
  4892. CHAR Translate( PWPOINT);%@NL@%
  4893. VOID UpdateDisplay( VOID);%@NL@%
  4894. %@NL@%
  4895. %@NL@%
  4896. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4897. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4898. VOID CalcTextOut( hps, iX, iY, pch, iCount)%@NL@%
  4899. %@NL@%
  4900. HPS hps;%@NL@%
  4901. INT iX, iY;%@NL@%
  4902. PCH pch;%@NL@%
  4903. INT iCount;%@NL@%
  4904. {%@NL@%
  4905.     POINTL ptl;%@NL@%
  4906. %@NL@%
  4907.     ptl.x = iX;%@NL@%
  4908.     ptl.y = iY;%@NL@%
  4909. %@NL@%
  4910.     GpiSetColor( hps, CLR_BLACK);%@NL@%
  4911.     GpiCharStringAt( hps, (PPOINTL)&ptl, (LONG)iCount, (PSZ)pch);%@NL@%
  4912. }%@NL@%
  4913. %@NL@%
  4914. %@NL@%
  4915. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4916. %@AB@%/* Write the appropriate number or error string to the display area              */%@AE@%%@NL@%
  4917. %@AB@%/* and mark memory-in-use if appropriate.                                      */%@AE@%%@NL@%
  4918. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4919. VOID%@NL@%
  4920. UpdateDisplay()%@NL@%
  4921. {%@NL@%
  4922.     RECTL rcl;%@NL@%
  4923. %@NL@%
  4924.     rcl.xLeft = (6 * sCharWidth);%@NL@%
  4925.     rcl.yBottom = 1050 * sCharHeight / 100;%@NL@%
  4926.     rcl.xRight = rcl.xLeft + (12 * sCharWidth);%@NL@%
  4927.     rcl.yTop = rcl.yBottom + (3 * sCharHeight) / 2;%@NL@%
  4928. %@NL@%
  4929.     WinFillRect( hpsCalc, &rcl, CLR_WHITE);         %@AB@%/* paint display area white */%@AE@%%@NL@%
  4930.     if( fError)%@NL@%
  4931.         WinDrawText( hpsCalc%@NL@%
  4932.                    , -1%@NL@%
  4933.                    , szErrorString%@NL@%
  4934.                    , &rcl%@NL@%
  4935.                    , CLR_BLACK%@NL@%
  4936.                    , CLR_WHITE%@NL@%
  4937.                    , DT_RIGHT | DT_VCENTER );%@NL@%
  4938.     else%@NL@%
  4939.         WinDrawText( hpsCalc%@NL@%
  4940.                    , -1%@NL@%
  4941.                    , szreg1%@NL@%
  4942.                    , &rcl%@NL@%
  4943.                    , CLR_BLACK%@NL@%
  4944.                    , CLR_WHITE%@NL@%
  4945.                    , DT_RIGHT | DT_VCENTER );%@NL@%
  4946. %@NL@%
  4947.     if (fValueInMemory)                 %@AB@%/* little black square shows mem use */%@AE@%%@NL@%
  4948.     {%@NL@%
  4949.         rcl.xLeft = (6 * sCharWidth);%@NL@%
  4950.         rcl.yBottom = 1050 * sCharHeight / 100;%@NL@%
  4951.         rcl.xRight = rcl.xLeft + (sCharWidth / 2);%@NL@%
  4952.         rcl.yTop = rcl.yBottom + (sCharHeight / 2);%@NL@%
  4953.         WinFillRect( hpsCalc, &rcl, CLR_BLACK);%@NL@%
  4954.     }%@NL@%
  4955. }%@NL@%
  4956. %@NL@%
  4957. %@NL@%
  4958. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4959. %@AB@%/*  Display helpful info                                                      */%@AE@%%@NL@%
  4960. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4961. MPARAM EXPENTRY%@NL@%
  4962. AboutDlgProc( hwnd, msg, mp1, mp2)%@NL@%
  4963. %@NL@%
  4964. HWND   hwnd;%@NL@%
  4965. USHORT msg;%@NL@%
  4966. MPARAM mp1;%@NL@%
  4967. MPARAM mp2;%@NL@%
  4968. {%@NL@%
  4969.     if (msg == WM_COMMAND)%@NL@%
  4970.     {%@NL@%
  4971.         WinDismissDlg(hwnd, TRUE);%@NL@%
  4972.         return(MPFROMSHORT(TRUE));%@NL@%
  4973.     }%@NL@%
  4974.     else return(WinDefDlgProc( hwnd, msg, mp1, mp2));%@NL@%
  4975. }%@NL@%
  4976. %@NL@%
  4977. %@NL@%
  4978. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4979. %@AB@%/*  General initialization                                                      */%@AE@%%@NL@%
  4980. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  4981. BOOL%@NL@%
  4982. CalcInit()%@NL@%
  4983. {%@NL@%
  4984.     hab = WinInitialize( NULL);%@NL@%
  4985. %@NL@%
  4986.     hmqCalc = WinCreateMsgQueue( hab, 0);%@NL@%
  4987.     if( !hmqCalc)%@NL@%
  4988.         return(FALSE);%@NL@%
  4989. %@NL@%
  4990.     WinLoadString( NULL, NULL, 1, 30, (PSZ)szTitle);%@NL@%
  4991.     WinLoadString( NULL, NULL, 2, 20, (PSZ)szErrorString);%@NL@%
  4992.     WinLoadString( NULL, NULL, 3, 2, (PSZ)szPlusMinus);%@NL@%
  4993. %@NL@%
  4994.     if (!WinRegisterClass( hab, szTitle, CalcWndProc, CS_SIZEREDRAW, 0))%@NL@%
  4995.         return(FALSE);%@NL@%
  4996. %@NL@%
  4997.     hptrFinger = WinLoadPointer( HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);%@NL@%
  4998. %@NL@%
  4999.     InitCalc();                         %@AB@%/* arithmetic initialization */%@AE@%%@NL@%
  5000. %@NL@%
  5001.     return(TRUE);%@NL@%
  5002. }%@NL@%
  5003. %@NL@%
  5004. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5005. %@AB@%/*  main procedure                                                              */%@AE@%%@NL@%
  5006. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5007. VOID cdecl%@NL@%
  5008. main()%@NL@%
  5009. {%@NL@%
  5010.     QMSG  qmsg;%@NL@%
  5011.     ULONG ulFCF;%@NL@%
  5012. %@NL@%
  5013.     if (!CalcInit()) {                            %@AB@%/* general initialization */%@AE@%%@NL@%
  5014.         WinAlarm(HWND_DESKTOP, WA_ERROR);%@NL@%
  5015.         goto exit;%@NL@%
  5016.     }%@NL@%
  5017. %@NL@%
  5018.     if (!PSInit()) {                            %@AB@%/* presentation spaces & bitmaps */%@AE@%%@NL@%
  5019.         WinAlarm(HWND_DESKTOP, WA_ERROR);%@NL@%
  5020.         goto exit;%@NL@%
  5021.     }%@NL@%
  5022. %@NL@%
  5023.     ulFCF = FCF_STANDARD & ~(LONG)(FCF_SIZEBORDER | FCF_MAXBUTTON);%@NL@%
  5024.     hwndCalcFrame = WinCreateStdWindow( HWND_DESKTOP%@NL@%
  5025.                                       , WS_VISIBLE | FS_BORDER%@NL@%
  5026.                                       , &ulFCF%@NL@%
  5027.                                       , szTitle%@NL@%
  5028.                                       , NULL%@NL@%
  5029.                                       , 0L%@NL@%
  5030.                                       , NULL%@NL@%
  5031.                                       , IDR_CALC%@NL@%
  5032.                                       , &hwndCalc);%@NL@%
  5033. %@NL@%
  5034.     WinSetWindowPos( hwndCalcFrame%@NL@%
  5035.                    , (HWND)NULL%@NL@%
  5036.                    , 2%@NL@%
  5037.                    , 2%@NL@%
  5038.                    , CXCHARS * sCharWidth%@NL@%
  5039.                    , CYCHARS * sCharHeight%@NL@%
  5040.                              + (SHORT)WinQuerySysValue( HWND_DESKTOP%@NL@%
  5041.                                                       , SV_CYTITLEBAR )%@NL@%
  5042.                              + (SHORT)WinQuerySysValue( HWND_DESKTOP%@NL@%
  5043.                                                       , SV_CYMENU )%@NL@%
  5044.                    , SWP_MOVE | SWP_SIZE );%@NL@%
  5045. %@NL@%
  5046.     while (WinGetMsg( hab, &qmsg, NULL, 0, 0))%@NL@%
  5047.         WinDispatchMsg( hab, &qmsg);%@NL@%
  5048. %@NL@%
  5049. exit:                                            %@AB@%/* clean up */%@AE@%%@NL@%
  5050.     if (hdcSqr)                             %@AB@%/* square-root bitmap */%@AE@%%@NL@%
  5051.     {%@NL@%
  5052.         GpiDestroyPS( hpsSqr);%@NL@%
  5053.         if (hbmSqr)%@NL@%
  5054.             GpiDeleteBitmap( hbmSqr);%@NL@%
  5055.     }%@NL@%
  5056. %@NL@%
  5057.     if (hdcLocal)                            %@AB@%/* keypad button */%@AE@%%@NL@%
  5058.     {%@NL@%
  5059.         GpiDestroyPS( hpsLocal);%@NL@%
  5060.         if (hbmLocal)%@NL@%
  5061.             GpiDeleteBitmap( hbmLocal);%@NL@%
  5062.     }%@NL@%
  5063. %@NL@%
  5064.     WinDestroyWindow(hwndCalcFrame);%@NL@%
  5065. %@NL@%
  5066.     WinDestroyMsgQueue(hmqCalc);%@NL@%
  5067.     WinTerminate(hab);%@NL@%
  5068. %@NL@%
  5069.     DosExit(EXIT_PROCESS, 0);                    %@AB@%/* exit without error */%@AE@%%@NL@%
  5070. }%@NL@%
  5071. %@NL@%
  5072. %@NL@%
  5073. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5074. %@AB@%/* Calc Window Procedure                                                      */%@AE@%%@NL@%
  5075. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5076. MRESULT EXPENTRY%@NL@%
  5077. CalcWndProc(hwnd, msg, mp1, mp2)%@NL@%
  5078. %@NL@%
  5079. HWND        hwnd;%@NL@%
  5080. USHORT        msg;%@NL@%
  5081. MPARAM        mp1;%@NL@%
  5082. MPARAM        mp2;%@NL@%
  5083. {%@NL@%
  5084.     HPS     hps;%@NL@%
  5085.     RECTL   rclPaint;%@NL@%
  5086.     WPOINT  wpt;%@NL@%
  5087.     BOOL    fClip;%@NL@%
  5088.     USHORT  usFmtInfo;%@NL@%
  5089.     RECTL   rcl;%@NL@%
  5090.     SIZEL   sizl;%@NL@%
  5091. %@NL@%
  5092.     switch (msg)%@NL@%
  5093.     {%@NL@%
  5094.     case WM_CREATE:%@NL@%
  5095.         hdcCalc = WinOpenWindowDC( hwnd);%@NL@%
  5096.         WinQueryWindowRect( hwnd, &rcl);%@NL@%
  5097.         sizl.cx = rcl.xRight - rcl.xLeft;%@NL@%
  5098.         sizl.cy = rcl.yTop - rcl.yBottom;%@NL@%
  5099.         hpsCalc = GpiCreatePS( hab%@NL@%
  5100.                              , hdcCalc%@NL@%
  5101.                              , &sizl%@NL@%
  5102.                              , GPIA_ASSOC | PU_PELS );%@NL@%
  5103.         break;%@NL@%
  5104. %@NL@%
  5105.     case WM_DESTROY:%@NL@%
  5106.         WinDestroyPointer(hptrFinger);%@NL@%
  5107.         GpiDestroyPS( hpsSqr);%@NL@%
  5108.         GpiDeleteBitmap( hbmSqr);%@NL@%
  5109.         GpiDestroyPS( hpsLocal);%@NL@%
  5110.         GpiDeleteBitmap( hbmLocal);%@NL@%
  5111.         break;%@NL@%
  5112. %@NL@%
  5113.     case WM_INITMENU:%@NL@%
  5114.         fClip = FALSE;%@NL@%
  5115.         if (WinOpenClipbrd( hab))%@NL@%
  5116.         {%@NL@%
  5117.             fClip = WinQueryClipbrdFmtInfo( hab, CF_TEXT, &usFmtInfo);%@NL@%
  5118.             WinCloseClipbrd( hab);%@NL@%
  5119.         }%@NL@%
  5120.         WinSendMsg((HWND)mp2, MM_SETITEMATTR,%@NL@%
  5121.                    (MPARAM) MAKELONG(CMD_PASTE, TRUE),%@NL@%
  5122.                    (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED));%@NL@%
  5123.         break;%@NL@%
  5124. %@NL@%
  5125.     case WM_PAINT:%@NL@%
  5126.         hps = WinBeginPaint(hwnd, NULL, &rclPaint);%@NL@%
  5127.         CalcPaint( hwnd, hps);                            %@AB@%/* re-draw calculator */%@AE@%%@NL@%
  5128.         WinEndPaint(hps);%@NL@%
  5129.         break;%@NL@%
  5130. %@NL@%
  5131.     case WM_COMMAND:%@NL@%
  5132.         if (fError)%@NL@%
  5133.             break;%@NL@%
  5134.         switch(LOUSHORT(mp1))%@NL@%
  5135.         {%@NL@%
  5136.         case CMD_COPY:%@NL@%
  5137.             DataXCopy();                    %@AB@%/* copy to clipboard */%@AE@%%@NL@%
  5138.             break;%@NL@%
  5139.         case CMD_PASTE:%@NL@%
  5140.             DataXPaste();                    %@AB@%/* paste from clipboard */%@AE@%%@NL@%
  5141.             break;%@NL@%
  5142.         case CMD_EXIT:%@NL@%
  5143.             WinPostMsg( hwndCalcFrame, WM_QUIT, 0L, 0L);%@NL@%
  5144.             break;%@NL@%
  5145.         case CMD_ABOUT:%@NL@%
  5146.             WinDlgBox( HWND_DESKTOP%@NL@%
  5147.                      , hwndCalcFrame%@NL@%
  5148.                      , (PFNWP)AboutDlgProc%@NL@%
  5149.                      , NULL%@NL@%
  5150.                      , 1%@NL@%
  5151.                      , (PSZ)NULL );%@NL@%
  5152.             break;%@NL@%
  5153.         }%@NL@%
  5154.         break;%@NL@%
  5155. %@NL@%
  5156.     case WM_CLOSE:%@NL@%
  5157.         WinPostMsg(hwndCalcFrame, WM_QUIT, 0L, 0L);%@NL@%
  5158.         break;%@NL@%
  5159. %@NL@%
  5160.     case WM_MOUSEMOVE:%@NL@%
  5161.         WinSetPointer( HWND_DESKTOP, hptrFinger);%@NL@%
  5162.         break;%@NL@%
  5163. %@NL@%
  5164.     case WM_BUTTON1DOWN:%@NL@%
  5165.         wpt.x = LOUSHORT(mp1);%@NL@%
  5166.         wpt.y = HIUSHORT(mp1);%@NL@%
  5167.         ProcessKey( &wpt);%@NL@%
  5168.         goto dwp;%@NL@%
  5169.         break;%@NL@%
  5170. %@NL@%
  5171.     case WM_CHAR:%@NL@%
  5172.         if (SHORT1FROMMP(mp1) & KC_KEYUP)%@NL@%
  5173.         {%@NL@%
  5174.             if (CHAR4FROMMP(mp1) == uchMScan)%@NL@%
  5175.                    fMDown = FALSE;                 %@AB@%/* 'm' key went up */%@AE@%%@NL@%
  5176.         }%@NL@%
  5177.         else %@NL@%
  5178.         {%@NL@%
  5179.                 if (SHORT1FROMMP(mp1) & KC_CHAR)%@NL@%
  5180.       {%@NL@%
  5181.              if (InterpretChar((UCHAR)SHORT1FROMMP(mp2)))%@NL@%
  5182.                   {        %@NL@%
  5183.                                 UpdateDisplay();%@NL@%
  5184.                   }%@NL@%
  5185.              else %@NL@%
  5186.                   {%@NL@%
  5187.                                   if (((UCHAR)SHORT1FROMMP(mp2)== 'm') || ((UCHAR)SHORT1FROMMP(mp2)== 'M'))%@NL@%
  5188.                             {%@NL@%
  5189.                                         uchMScan = CHAR4FROMMP(mp1);           %@AB@%/* save 'm' key scan code  */%@AE@%%@NL@%
  5190.                                         fMDown = TRUE;                           %@AB@%/* 'm' key went down       */%@AE@%%@NL@%
  5191.                             }%@NL@%
  5192.         }%@NL@%
  5193.                 }%@NL@%
  5194.         }%@NL@%
  5195.         break;%@NL@%
  5196. %@NL@%
  5197.     case WM_ACTIVATE:%@NL@%
  5198.         if (HIUSHORT(mp1))%@NL@%
  5199.             WinSetFocus( HWND_DESKTOP, hwndCalc);%@NL@%
  5200.         break;%@NL@%
  5201. %@NL@%
  5202.     case WM_SETFOCUS:%@NL@%
  5203.         if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);%@NL@%
  5204.             fMDown = FALSE;                        %@AB@%/* since we are losing focus */%@AE@%%@NL@%
  5205.         break;%@NL@%
  5206. %@NL@%
  5207. dwp:%@NL@%
  5208.     default:%@NL@%
  5209.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  5210.         break;%@NL@%
  5211.     }%@NL@%
  5212.     return(0L);%@NL@%
  5213. }%@NL@%
  5214. %@NL@%
  5215. %@NL@%
  5216. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5217. %@AB@%/*  translate & interpret keys (ie. locate in logical keyboard)               */%@AE@%%@NL@%
  5218. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5219. BOOL%@NL@%
  5220. InterpretChar( ch)%@NL@%
  5221. %@NL@%
  5222. CHAR ch;%@NL@%
  5223. {%@NL@%
  5224.     BOOL fDone;%@NL@%
  5225.     NPCH pchStep;%@NL@%
  5226.     INT  i;%@NL@%
  5227. %@NL@%
  5228.     fDone = FALSE;%@NL@%
  5229.     pchStep = achKeys;%@NL@%
  5230.     switch (ch)%@NL@%
  5231.     {%@NL@%
  5232.     case 'n':%@NL@%
  5233.         ch = szPlusMinus[0];%@NL@%
  5234.         break;%@NL@%
  5235.     case 27:                        %@AB@%/* xlate Escape into 'c' */%@AE@%%@NL@%
  5236.         ch = 'c';%@NL@%
  5237.         break;%@NL@%
  5238.     case '\r':                      %@AB@%/* xlate Enter into '=' */%@AE@%%@NL@%
  5239.         ch = '=';%@NL@%
  5240.         break;%@NL@%
  5241.     }%@NL@%
  5242. %@NL@%
  5243.     if (fMDown)                     %@AB@%/* Do memory keys */%@AE@%%@NL@%
  5244.     {%@NL@%
  5245.         switch (ch)%@NL@%
  5246.         {%@NL@%
  5247.         case 'c':%@NL@%
  5248.         case 'C':%@NL@%
  5249.             ch = '\274';%@NL@%
  5250.             break;%@NL@%
  5251.         case 'r':%@NL@%
  5252.         case 'R':%@NL@%
  5253.             ch = '\273';%@NL@%
  5254.             break;%@NL@%
  5255.         case '+':%@NL@%
  5256.             ch = '\272';%@NL@%
  5257.             break;%@NL@%
  5258.         case '-':%@NL@%
  5259.             ch = '\271';%@NL@%
  5260.             break;%@NL@%
  5261.         }%@NL@%
  5262.     }%@NL@%
  5263. %@NL@%
  5264.     while (!fDone && *pchStep)%@NL@%
  5265.     {%@NL@%
  5266.         if ((CHAR) *pchStep++ == ch)%@NL@%
  5267.             fDone = TRUE;                %@AB@%/* char found in logical keyboard */%@AE@%%@NL@%
  5268.     }%@NL@%
  5269.     if (fDone)%@NL@%
  5270.     {%@NL@%
  5271.         chLastKey = chCurrKey;%@NL@%
  5272.         i = pchStep - achKeys - 1;%@NL@%
  5273.         FlipKey( hpsCalc, i/6, i%6);%@NL@%
  5274.         Evaluate( achKeys[i]);%@NL@%
  5275.     }%@NL@%
  5276.     return (fDone);%@NL@%
  5277. }%@NL@%
  5278. %@NL@%
  5279. %@NL@%
  5280. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5281. %@AB@%/*  briefly reverse the shading on one of the keys                              */%@AE@%%@NL@%
  5282. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5283. VOID%@NL@%
  5284. FlipKey( hps, iRow, iCol)%@NL@%
  5285. %@NL@%
  5286. HPS hps;%@NL@%
  5287. INT iRow, iCol;%@NL@%
  5288. {%@NL@%
  5289.     RECTL rcl;%@NL@%
  5290. %@NL@%
  5291.     rcl.xLeft = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);%@NL@%
  5292.     rcl.yBottom = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);%@NL@%
  5293.     rcl.xRight = rcl.xLeft + (11 * sCharWidth / 3);%@NL@%
  5294.     rcl.yTop = rcl.yBottom + (7 * sCharHeight / 4);%@NL@%
  5295.     WinInvertRect( hps, &rcl);%@NL@%
  5296.     DosSleep( 50L);%@NL@%
  5297.     WinInvertRect( hps, &rcl);%@NL@%
  5298. }%@NL@%
  5299. %@NL@%
  5300. %@NL@%
  5301. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5302. %@AB@%/*  compute whether a point is over a button and flash the button if so       */%@AE@%%@NL@%
  5303. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5304. BOOL%@NL@%
  5305. FlashSqr( hps, pwpt)%@NL@%
  5306. %@NL@%
  5307. HPS         hps;%@NL@%
  5308. PWPOINT  pwpt;%@NL@%
  5309. {%@NL@%
  5310.     INT  iRow, iCol;%@NL@%
  5311.     BOOL fDone;%@NL@%
  5312. %@NL@%
  5313.     %@AB@%/* find x range */%@AE@%%@NL@%
  5314.     fDone = FALSE;%@NL@%
  5315.     iCol = 0;%@NL@%
  5316.     iRow = 3;%@NL@%
  5317.     while (!fDone && iCol<6)%@NL@%
  5318.     {%@NL@%
  5319.         if (pwpt->x <        (iCol * 6 * sCharWidth)%@NL@%
  5320.                        + (14 * sCharWidth / 10)%@NL@%
  5321.                        + (11*sCharWidth/3)         )%@NL@%
  5322.         {%@NL@%
  5323.             if (pwpt->x > (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10))%@NL@%
  5324.                 fDone = TRUE;%@NL@%
  5325.             else%@NL@%
  5326.                 return FALSE;%@NL@%
  5327.         }%@NL@%
  5328.         else%@NL@%
  5329.             iCol++;%@NL@%
  5330.     }%@NL@%
  5331.     if (!fDone)%@NL@%
  5332.         return FALSE;%@NL@%
  5333.     fDone = FALSE;%@NL@%
  5334.     while (!fDone && iRow >= 0)%@NL@%
  5335.     {%@NL@%
  5336.         if (pwpt->y > ((165 * sCharHeight / 100) + (2 * iRow * sCharHeight)))%@NL@%
  5337.         {%@NL@%
  5338.             if (pwpt->y <   (165 * sCharHeight / 100)%@NL@%
  5339.                            + (2 * iRow * sCharHeight)%@NL@%
  5340.                            + (7 * sCharHeight / 4)     )%@NL@%
  5341.                 fDone = TRUE;%@NL@%
  5342.             else%@NL@%
  5343.                 return FALSE;%@NL@%
  5344.         }%@NL@%
  5345.         else%@NL@%
  5346.             iRow--;%@NL@%
  5347.     }%@NL@%
  5348.     if (!fDone)%@NL@%
  5349.         return FALSE;%@NL@%
  5350.     pwpt->x = iCol;%@NL@%
  5351.     pwpt->y = iRow;%@NL@%
  5352.     FlipKey( hps, iRow, iCol);%@NL@%
  5353.     return TRUE;%@NL@%
  5354. }%@NL@%
  5355. %@NL@%
  5356. %@NL@%
  5357. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5358. %@AB@%/*  which key is point on?                                                      */%@AE@%%@NL@%
  5359. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5360. CHAR%@NL@%
  5361. Translate( pwpt)%@NL@%
  5362. %@NL@%
  5363. PWPOINT pwpt;%@NL@%
  5364. {%@NL@%
  5365.     return( achKeys[ pwpt->y * 6 + pwpt->x]);%@NL@%
  5366. }%@NL@%
  5367. %@NL@%
  5368. %@NL@%
  5369. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5370. %@AB@%/*  invoke flashing, point-to-key translation, and result-display update      */%@AE@%%@NL@%
  5371. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5372. VOID%@NL@%
  5373. ProcessKey( pwpt)%@NL@%
  5374. %@NL@%
  5375. PWPOINT pwpt;%@NL@%
  5376. {%@NL@%
  5377.     BOOL fFlashed;%@NL@%
  5378. %@NL@%
  5379.     chLastKey = chCurrKey;%@NL@%
  5380.     fFlashed = FlashSqr( hpsCalc, pwpt);%@NL@%
  5381. %@NL@%
  5382.     if (fFlashed)%@NL@%
  5383.         Evaluate( (BYTE)Translate( pwpt));%@NL@%
  5384.     UpdateDisplay();%@NL@%
  5385. }%@NL@%
  5386. %@NL@%
  5387. %@NL@%
  5388. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5389. %@AB@%/*  draw a blank key                                                              */%@AE@%%@NL@%
  5390. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5391. VOID%@NL@%
  5392. FrameKey(hps, iRow, iCol)%@NL@%
  5393. %@NL@%
  5394. HPS hps;%@NL@%
  5395. INT iRow, iCol;%@NL@%
  5396. {%@NL@%
  5397.     POINTL aptl[3];%@NL@%
  5398. %@NL@%
  5399.     aptl[0].x = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);%@NL@%
  5400.     aptl[0].y = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);%@NL@%
  5401.     aptl[1].x = (11 * sCharWidth / 3) + (aptl[0].x);%@NL@%
  5402.     aptl[1].y = (7 * sCharHeight / 4) + (aptl[0].y);%@NL@%
  5403.     aptl[2].x = 0;%@NL@%
  5404.     aptl[2].y = 0;%@NL@%
  5405.     GpiBitBlt( hps, hpsLocal, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);%@NL@%
  5406. }%@NL@%
  5407. %@NL@%
  5408. %@NL@%
  5409. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5410. %@AB@%/*  draw the keys and fill in numbers                                              */%@AE@%%@NL@%
  5411. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5412. VOID%@NL@%
  5413. DrawNumbers(hps)%@NL@%
  5414. %@NL@%
  5415. HPS hps;%@NL@%
  5416. {%@NL@%
  5417.     INT iRow, iCol;%@NL@%
  5418. %@NL@%
  5419.     %@AB@%/* Draw the keys and fill in the numbers we can */%@AE@%%@NL@%
  5420.     for (iRow = 0; iRow < 4; iRow++)%@NL@%
  5421.     {%@NL@%
  5422.         for (iCol = 0; iCol < 6; iCol++)%@NL@%
  5423.         {%@NL@%
  5424.             FrameKey( hps, iRow, iCol);%@NL@%
  5425.             CalcTextOut( hps%@NL@%
  5426.                        ,   (iCol * 6 * sCharWidth)%@NL@%
  5427.                          + (WIDTHCONST * sCharWidth / 10)%@NL@%
  5428.                        , (iRow + 1) * 2 * sCharHeight%@NL@%
  5429.                        , (PSZ)(achDKeys + (iRow * 6) + iCol)%@NL@%
  5430.                        , 1 );%@NL@%
  5431.         }%@NL@%
  5432.     }%@NL@%
  5433. }%@NL@%
  5434. %@NL@%
  5435. %@NL@%
  5436. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5437. %@AB@%/*  redraw the whole calculator                                               */%@AE@%%@NL@%
  5438. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5439. VOID%@NL@%
  5440. CalcPaint( hwnd, hps)%@NL@%
  5441. %@NL@%
  5442. HWND hwnd;%@NL@%
  5443. HPS  hps;%@NL@%
  5444. {%@NL@%
  5445.     RECTL      rclDst;%@NL@%
  5446.     CHARBUNDLE cbnd;%@NL@%
  5447.     INT        iX, iY;%@NL@%
  5448. %@NL@%
  5449.     WinQueryWindowRect( hwnd, &rclDst);%@NL@%
  5450.     WinFillRect( hps, &rclDst, CLR_GREEN);%@NL@%
  5451. %@NL@%
  5452.     DrawNumbers(hps);%@NL@%
  5453.     CalcTextOut(hps, iX = (11 * sCharWidth / 5) + 1, iY = 2 * sCharHeight,%@NL@%
  5454.                (PSZ)"M-", 2);%@NL@%
  5455.     CalcTextOut(hps, iX, iY + 2 * sCharHeight, (PSZ)"M+", 2);%@NL@%
  5456.     CalcTextOut(hps, iX, iY + 4 * sCharHeight, (PSZ)"MR", 2);%@NL@%
  5457.     CalcTextOut(hps, iX, iY + 6 * sCharHeight, (PSZ)"MC", 2);%@NL@%
  5458. %@NL@%
  5459.     %@AB@%/* Draw the minus of the plus/minus button */%@AE@%%@NL@%
  5460.     cbnd.usBackMixMode = FM_LEAVEALONE;%@NL@%
  5461.     GpiSetAttrs( hps, PRIM_CHAR, CBB_BACK_MIX_MODE, 0L, &cbnd);%@NL@%
  5462.     iX =  (3 * 6 * sCharWidth) + (WIDTHCONST * sCharWidth / 10);%@NL@%
  5463.     CalcTextOut( hps, iX, iY + sCharHeight / 4, (PSZ)"_", 1);%@NL@%
  5464. %@NL@%
  5465.     %@AB@%/* Draw the square root bitmap */%@AE@%%@NL@%
  5466.     rclDst.xLeft = 160 * sCharWidth / 5;%@NL@%
  5467.     rclDst.yBottom = 31 * sCharHeight / 4;%@NL@%
  5468.     rclDst.xRight = rclDst.xLeft + 2 * sCharWidth;%@NL@%
  5469.     rclDst.yTop = rclDst.yBottom + (3 * sCharHeight / 2);%@NL@%
  5470.     WinDrawBitmap( hps%@NL@%
  5471.                  , hbmSqr%@NL@%
  5472.                  , NULL%@NL@%
  5473.                  , (PPOINTL)&rclDst%@NL@%
  5474.                  , CLR_WHITE%@NL@%
  5475.                  , CLR_BLACK%@NL@%
  5476.                  , DBM_STRETCH );%@NL@%
  5477. %@NL@%
  5478.     UpdateDisplay();%@NL@%
  5479. }%@NL@%
  5480. %@NL@%
  5481. %@NL@%
  5482. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5483. %@AB@%/*  initialize the bitmaps for a blank key and for the square-root sign       */%@AE@%%@NL@%
  5484. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5485. BOOL%@NL@%
  5486. PSInit()%@NL@%
  5487. {%@NL@%
  5488.     HPS              hps;%@NL@%
  5489.     FONTMETRICS      fm;%@NL@%
  5490.     POINTL             ptl;%@NL@%
  5491.     SIZEL             sizl;%@NL@%
  5492.     BITMAPINFOHEADER bmp;%@NL@%
  5493.     POINTL             aptl[4];%@NL@%
  5494.     LONG             alCaps[2];%@NL@%
  5495. %@NL@%
  5496.     %@AB@%/**************************************************************************/%@AE@%%@NL@%
  5497.     %@AB@%/*        compute the units of horizontal and vertical distance based on font   */%@AE@%%@NL@%
  5498.     %@AB@%/**************************************************************************/%@AE@%%@NL@%
  5499.     hps = WinGetPS( HWND_DESKTOP);%@NL@%
  5500.     GpiQueryFontMetrics( hps, (LONG)sizeof(FONTMETRICS), &fm);%@NL@%
  5501.     sCharHeight = (SHORT)(fm.lEmHeight); %@AB@%/* avg height of uppercase character */%@AE@%%@NL@%
  5502.     sCharWidth        = (SHORT)(fm.lEmInc);         %@AB@%/* usually 'M' increment              */%@AE@%%@NL@%
  5503.     WinReleasePS( hps);%@NL@%
  5504. %@NL@%
  5505.     %@AB@%/**************************************************************************/%@AE@%%@NL@%
  5506.     %@AB@%/*        prepare the square root bitmap                                              */%@AE@%%@NL@%
  5507.     %@AB@%/**************************************************************************/%@AE@%%@NL@%
  5508.     hdcSqr = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);%@NL@%
  5509.     if( !hdcSqr)%@NL@%
  5510.         return(FALSE);%@NL@%
  5511. %@NL@%
  5512.     sizl.cx = sizl.cy = 0L;%@NL@%
  5513.     hpsSqr = GpiCreatePS( hab%@NL@%
  5514.                         , hdcSqr%@NL@%
  5515.                         , &sizl%@NL@%
  5516.                         , PU_PELS | GPIT_MICRO | GPIA_ASSOC );%@NL@%
  5517.     hbmSqr = GpiLoadBitmap( hpsSqr, NULL, IDB_SQR, 0L, 0L);%@NL@%
  5518. %@NL@%
  5519.     %@AB@%/**************************************************************************/%@AE@%%@NL@%
  5520.     %@AB@%/*        prepare the bitmap of a blank key                                      */%@AE@%%@NL@%
  5521.     %@AB@%/**************************************************************************/%@AE@%%@NL@%
  5522.     hdcLocal = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);%@NL@%
  5523.     if( !hdcLocal)%@NL@%
  5524.         return(FALSE);%@NL@%
  5525. %@NL@%
  5526.     sizl.cx = sizl.cy = 0L;%@NL@%
  5527.     hpsLocal = GpiCreatePS( hab%@NL@%
  5528.                           , hdcLocal%@NL@%
  5529.                           , &sizl%@NL@%
  5530.                           , PU_PELS | GPIT_MICRO | GPIA_ASSOC );%@NL@%
  5531.     bmp.cbFix = 12;%@NL@%
  5532.     bmp.cx = 11 * sCharWidth / 3;%@NL@%
  5533.     bmp.cy = sCharHeight * 2;%@NL@%
  5534.     DevQueryCaps( hdcLocal, CAPS_COLOR_PLANES, 2L, alCaps);%@NL@%
  5535.     bmp.cPlanes = (USHORT)alCaps[0];%@NL@%
  5536.     bmp.cBitCount = (USHORT)alCaps[1];%@NL@%
  5537.     hbmLocal = GpiCreateBitmap( hpsLocal, &bmp, 0L, NULL, NULL);%@NL@%
  5538.     if( !hbmLocal )%@NL@%
  5539.         return(FALSE);%@NL@%
  5540.     GpiSetBitmap( hpsLocal, hbmLocal);%@NL@%
  5541. %@NL@%
  5542.     aptl[0].x = aptl[0].y = 0;%@NL@%
  5543.     aptl[1].x = 11 * sCharWidth / 3;%@NL@%
  5544.     aptl[1].y = 7 * sCharHeight / 4;%@NL@%
  5545.     aptl[2].x = aptl[2].y = 0;%@NL@%
  5546.     aptl[3].x = aptl[1].x;%@NL@%
  5547.     aptl[3].y = aptl[1].y;%@NL@%
  5548.     GpiSetColor( hpsLocal, CLR_GREEN);            %@AB@%/* match the background to client */%@AE@%%@NL@%
  5549.     GpiBitBlt( hpsLocal, NULL, 2L, aptl, ROP_PATCOPY, BBO_IGNORE);%@NL@%
  5550. %@NL@%
  5551.     %@AB@%/* Draw the rounded rect */%@AE@%%@NL@%
  5552.     ptl.x = 0;%@NL@%
  5553.     ptl.y = 0;%@NL@%
  5554.     GpiSetCurrentPosition( hpsLocal, &ptl);%@NL@%
  5555.     ptl.x = (11 * sCharWidth / 3) - 1;%@NL@%
  5556.     ptl.y = (7 * sCharHeight / 4) - 1;%@NL@%
  5557.     GpiSetColor( hpsLocal, CLR_WHITE);            %@AB@%/* white interior                      */%@AE@%%@NL@%
  5558.     GpiBox( hpsLocal%@NL@%
  5559.           , DRO_FILL%@NL@%
  5560.           , &ptl%@NL@%
  5561.           , (LONG)sCharWidth%@NL@%
  5562.           , (LONG)(sCharHeight / 2) );%@NL@%
  5563.     ptl.x = 0;%@NL@%
  5564.     ptl.y = 0;%@NL@%
  5565.     GpiSetCurrentPosition( hpsLocal, &ptl);%@NL@%
  5566.     ptl.x = (11 * sCharWidth / 3) - 1;%@NL@%
  5567.     ptl.y = (7 * sCharHeight / 4) - 1;%@NL@%
  5568.     GpiSetColor( hpsLocal, CLR_BLACK);            %@AB@%/* black border                      */%@AE@%%@NL@%
  5569.     GpiBox( hpsLocal%@NL@%
  5570.           , DRO_OUTLINE%@NL@%
  5571.           , &ptl%@NL@%
  5572.           , (LONG)sCharWidth%@NL@%
  5573.           , (LONG)(sCharHeight / 2) );%@NL@%
  5574.     return( TRUE);%@NL@%
  5575. }%@NL@%
  5576. %@NL@%
  5577. %@NL@%
  5578. %@2@%%@AH@%CALCMATH.C%@AE@%%@EH@%%@NL@%
  5579. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CALC\CALCMATH.C%@AE@%%@NL@%
  5580. %@NL@%
  5581. %@AB@%/****************************** Module Header *********************************/%@AE@%%@NL@%
  5582. %@AB@%/*                                                                              */%@AE@%%@NL@%
  5583. %@AB@%/* Module Name:  calcmath.c - Calc application                                      */%@AE@%%@NL@%
  5584. %@AB@%/*                                                                              */%@AE@%%@NL@%
  5585. %@AB@%/* OS/2 Presentation Manager version of Calc, ported from Windows version     */%@AE@%%@NL@%
  5586. %@AB@%/*                                                                              */%@AE@%%@NL@%
  5587. %@AB@%/* Created by Microsoft Corporation, 1987                                      */%@AE@%%@NL@%
  5588. %@AB@%/*                                                                              */%@AE@%%@NL@%
  5589. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5590. %@NL@%
  5591. %@AI@%#define %@AE@%INCL_WINCLIPBOARD %@NL@%
  5592. %@AI@%#include %@AE@%<os2.h> %@NL@%
  5593. %@AI@%#include %@AE@%<string.h> %@NL@%
  5594. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  5595. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  5596. %@AI@%#include %@AE@%<math.h> %@NL@%
  5597. %@NL@%
  5598. extern BOOL fValueInMemory;%@NL@%
  5599. extern CHAR chLastKey;%@NL@%
  5600. extern CHAR szreg1[20], szreg2[20], szmem[20];%@NL@%
  5601. extern HWND hwndCalc;%@NL@%
  5602. extern CHAR szregx[];%@NL@%
  5603. extern HAB  hab;%@NL@%
  5604. BOOL   fReadNumber;%@NL@%
  5605. CHAR   PendingOperation;%@NL@%
  5606. BOOL   fFirstOperand, fError;%@NL@%
  5607. CHAR   szresult[20];%@NL@%
  5608. SEL    sel;%@NL@%
  5609. %@NL@%
  5610. %@AI@%#define %@AE@%tolower(x)   (((x) >= 'A') && ((x)<='Z')) ? (x) - 'A' + 'a' : (x) %@NL@%
  5611. %@AI@%#define %@AE@%MAXINT        (double)999999999 %@NL@%
  5612. %@AI@%#define %@AE@%MININT (double)-999999999 %@NL@%
  5613. %@AI@%#define %@AE@%ABS(x)                (((x) >= (double)0) ? (x) : (-(x))) %@NL@%
  5614. %@NL@%
  5615. %@NL@%
  5616. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5617. extern VOID UpdateDisplay( VOID);%@NL@%
  5618. extern BOOL InterpretChar( CHAR);%@NL@%
  5619. %@NL@%
  5620. VOID AppendNumber( BYTE);%@NL@%
  5621. VOID BinaryOperator( CHAR);%@NL@%
  5622. VOID Clear( VOID);%@NL@%
  5623. VOID DataXCopy( VOID);%@NL@%
  5624. VOID DataXPaste( VOID);%@NL@%
  5625. VOID Equilibrate( VOID);%@NL@%
  5626. VOID Evaluate( BYTE);%@NL@%
  5627. VOID FarStrcpy( PSZ, PSZ);%@NL@%
  5628. NPCH ftoa( double);%@NL@%
  5629. VOID InitCalc( VOID);%@NL@%
  5630. VOID MClear( VOID);%@NL@%
  5631. VOID MMinus( VOID);%@NL@%
  5632. VOID MPlus( VOID);%@NL@%
  5633. VOID Negate( VOID);%@NL@%
  5634. VOID Number( CHAR);%@NL@%
  5635. VOID Percent( VOID);%@NL@%
  5636. VOID reverse( NPCH);%@NL@%
  5637. VOID Simplify( VOID);%@NL@%
  5638. VOID SquareRoot( VOID);%@NL@%
  5639. %@NL@%
  5640. %@NL@%
  5641. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5642. VOID FarStrcpy( pszDest, pszSrc)%@NL@%
  5643. PSZ  pszDest, pszSrc;%@NL@%
  5644. {%@NL@%
  5645.     while( *pszDest++ = *pszSrc++);%@NL@%
  5646. }%@NL@%
  5647. %@NL@%
  5648. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5649. VOID%@NL@%
  5650. reverse( s)%@NL@%
  5651. %@NL@%
  5652. NPCH s;%@NL@%
  5653. {%@NL@%
  5654.     CHAR ch;%@NL@%
  5655.     register INT iHead, iTail;%@NL@%
  5656. %@NL@%
  5657.     for (iHead = 0, iTail = strlen(s) - 1; iHead<iTail; iHead++, iTail-- ) {%@NL@%
  5658.         ch = s[iHead];%@NL@%
  5659.         s[iHead] = s[iTail];%@NL@%
  5660.         s[iTail] = ch;%@NL@%
  5661.     }%@NL@%
  5662. }%@NL@%
  5663. %@NL@%
  5664. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5665. NPCH%@NL@%
  5666. ftoa( dblNum)%@NL@%
  5667. %@NL@%
  5668. double dblNum;%@NL@%
  5669. {%@NL@%
  5670.     sprintf( szresult, "%.8f", dblNum );%@NL@%
  5671.     return (szresult);%@NL@%
  5672. }%@NL@%
  5673. %@NL@%
  5674. %@NL@%
  5675. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5676. VOID%@NL@%
  5677. Negate()%@NL@%
  5678. {%@NL@%
  5679.     CHAR sztemp[ 20 ];%@NL@%
  5680. %@NL@%
  5681.     if (szreg1[0] ==  '-')%@NL@%
  5682.         strcpy(szreg1, (&szreg1[1]));                     %@AB@%/* get rid of minus sign */%@AE@%%@NL@%
  5683.     else if (szreg1[0] != '0' || (strlen(szreg1) > 2)) { %@AB@%/* can't negate zero */%@AE@%%@NL@%
  5684.              sztemp[0] = '-';%@NL@%
  5685.              strcpy(&sztemp[1], szreg1);%@NL@%
  5686.              strcpy(szreg1, sztemp);%@NL@%
  5687.          }%@NL@%
  5688. }%@NL@%
  5689. %@NL@%
  5690. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5691. VOID%@NL@%
  5692. Number( ch)%@NL@%
  5693. %@NL@%
  5694. CHAR ch;%@NL@%
  5695. {%@NL@%
  5696.     register INT iLen, iSize;%@NL@%
  5697. %@NL@%
  5698.     iSize = 9;%@NL@%
  5699.     if (szreg1[0] == '-') iSize++;%@NL@%
  5700.     if (strchr(szreg1, '.')) iSize++;%@NL@%
  5701.     iLen  = strlen(szreg1 );%@NL@%
  5702.     if (iLen == iSize) return;%@NL@%
  5703.     if (iLen == 1 && szreg1[0] == '0') iLen--;%@NL@%
  5704.     szreg1[ iLen ] = ch;%@NL@%
  5705.     szreg1[min(iLen + 1, 11)] = 0;%@NL@%
  5706. }%@NL@%
  5707. %@NL@%
  5708. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5709. VOID%@NL@%
  5710. AppendNumber ( b)%@NL@%
  5711. %@NL@%
  5712. BYTE b;%@NL@%
  5713. {%@NL@%
  5714.     if (b == '.') {                    %@AB@%/*        if no decimal, add one at end */%@AE@%%@NL@%
  5715.         if (!strchr(szreg1, '.'))   %@NL@%
  5716.             strcat(szreg1, ".");%@NL@%
  5717.     }%@NL@%
  5718.     else if ( b == 0xb1 )%@NL@%
  5719.              Negate();%@NL@%
  5720.          else%@NL@%
  5721.              Number(b);%@NL@%
  5722. }%@NL@%
  5723. %@NL@%
  5724. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5725. VOID%@NL@%
  5726. Equilibrate()%@NL@%
  5727. {%@NL@%
  5728.     double dblResult;%@NL@%
  5729.     double dblX1, dblX2;%@NL@%
  5730. %@NL@%
  5731.     if (chLastKey == '=') return;%@NL@%
  5732.     dblResult = (double)atof(szreg1);%@NL@%
  5733.     dblX1 = (double)atof(szreg1);%@NL@%
  5734.     dblX2 = (double)atof(szreg2);%@NL@%
  5735. %@NL@%
  5736.     switch (PendingOperation) {%@NL@%
  5737.         case '+':%@NL@%
  5738.             if (dblX2>(double)0) {            %@AB@%/* check for overflow */%@AE@%%@NL@%
  5739.                 if (dblX1>(double)0) {%@NL@%
  5740.                     if (dblX1 > (MAXINT - dblX2))%@NL@%
  5741.                         fError = TRUE;%@NL@%
  5742.                 }%@NL@%
  5743.             }%@NL@%
  5744.             else if (dblX2 < (double)0) {%@NL@%
  5745.                      if (dblX1 < (double)0) {%@NL@%
  5746.                          if ( dblX1 < (MININT - dblX2))%@NL@%
  5747.                              fError = TRUE;%@NL@%
  5748.                      }%@NL@%
  5749.                  }%@NL@%
  5750.             if (!fError)%@NL@%
  5751.                 dblResult = dblX2 + dblX1;%@NL@%
  5752.             break;%@NL@%
  5753.         case '-':%@NL@%
  5754.             if (dblX2 < (double)0) {%@NL@%
  5755.                 if (dblX1 > (double)0) {%@NL@%
  5756.                     if (dblX1 > (dblX2 - MININT))%@NL@%
  5757.                         fError = TRUE;%@NL@%
  5758.                 }%@NL@%
  5759.             }%@NL@%
  5760.             else if (dblX2 > (double)0) {%@NL@%
  5761.                     if (dblX1 < (double)0) {%@NL@%
  5762.                         if (dblX1 < (dblX2 - MAXINT))%@NL@%
  5763.                             fError = TRUE;%@NL@%
  5764.                     }%@NL@%
  5765.                  }%@NL@%
  5766.             if (!fError) %@NL@%
  5767.                 dblResult = dblX2 - dblX1;%@NL@%
  5768.             break;%@NL@%
  5769.         case '/':%@NL@%
  5770.             if (dblX1 == (double)0.0)%@NL@%
  5771.                 fError = TRUE;%@NL@%
  5772.             else if (dblX2 > (double)0) {%@NL@%
  5773.                      if (dblX1 > (double)0) {%@NL@%
  5774.                          if (dblX1 < (dblX2 / MAXINT))%@NL@%
  5775.                              fError = TRUE;%@NL@%
  5776.                      }%@NL@%
  5777.                      else {  %@AB@%/* dblX1 < 0 here */%@AE@%%@NL@%
  5778.                         if (dblX1 > (dblX2 / MININT))%@NL@%
  5779.                              fError = TRUE;%@NL@%
  5780.                      }%@NL@%
  5781.                  }%@NL@%
  5782.                  else {  %@AB@%/* dblX2 < 0 here */%@AE@%%@NL@%
  5783.                      if (dblX1 < (double)0) {%@NL@%
  5784.                          if (dblX1 > (dblX2 / MAXINT))%@NL@%
  5785.                              fError = TRUE;%@NL@%
  5786.                      }%@NL@%
  5787.                      else { %@AB@%/* dblX1 > 0 here */%@AE@%%@NL@%
  5788.                          if (dblX1 < (dblX2 / MININT))%@NL@%
  5789.                              fError = TRUE;%@NL@%
  5790.                      }%@NL@%
  5791.                  }%@NL@%
  5792.             if (!fError)%@NL@%
  5793.                 dblResult = dblX2 / dblX1;%@NL@%
  5794.             break;%@NL@%
  5795.         case '*':%@NL@%
  5796.             if (dblX1 == (double)0) return;%@NL@%
  5797.             if (ABS(dblX2) > (double)1) {%@NL@%
  5798.                 if (ABS(dblX1) > (double)1) {%@NL@%
  5799.                     if (ABS(dblX1) > (MAXINT / ABS(dblX2)))%@NL@%
  5800.                         fError = TRUE;%@NL@%
  5801.                     } %@NL@%
  5802.                 }                    %@NL@%
  5803.             if (!fError) dblResult = dblX2 * dblX1;%@NL@%
  5804.             break;%@NL@%
  5805.         }%@NL@%
  5806.     if (!fError) {%@NL@%
  5807.         strcpy(szreg1, ftoa((double)dblResult));%@NL@%
  5808.         strcpy( szreg2, szreg1 );%@NL@%
  5809.         }%@NL@%
  5810.     Simplify();%@NL@%
  5811. }%@NL@%
  5812. %@NL@%
  5813. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5814. VOID%@NL@%
  5815. SquareRoot()%@NL@%
  5816. {%@NL@%
  5817.     double dblResult;%@NL@%
  5818. %@NL@%
  5819.     dblResult = (double)atof(szreg1);%@NL@%
  5820.     if (dblResult < 0.0) {%@NL@%
  5821.         fError = TRUE;%@NL@%
  5822.         return;%@NL@%
  5823.     }%@NL@%
  5824.     if ((dblResult == 0.0) || ((chLastKey == 'q') && (dblResult == 1.0)))%@NL@%
  5825.         return;%@NL@%
  5826.     if ((dblResult < (double) 1.00000002) && (dblResult > (double) 1.0))%@NL@%
  5827.         dblResult = (double)1.0;%@NL@%
  5828.     else%@NL@%
  5829.         dblResult = sqrt(dblResult);%@NL@%
  5830.     strcpy( szreg1, ftoa((double)dblResult));%@NL@%
  5831.     if (atof( szreg1 ) == 0.0)%@NL@%
  5832.         strcpy(szreg1, "0.");%@NL@%
  5833.     Simplify();%@NL@%
  5834. }%@NL@%
  5835. %@NL@%
  5836. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5837. VOID%@NL@%
  5838. BinaryOperator( ch)%@NL@%
  5839. %@NL@%
  5840. CHAR ch;%@NL@%
  5841. {%@NL@%
  5842.     if (fFirstOperand) {%@NL@%
  5843.         fFirstOperand = FALSE;%@NL@%
  5844.         strcpy(szreg2, szreg1);%@NL@%
  5845.     }%@NL@%
  5846.     else {%@NL@%
  5847.         Equilibrate();%@NL@%
  5848.     }%@NL@%
  5849.     PendingOperation = ch;%@NL@%
  5850. }%@NL@%
  5851. %@NL@%
  5852. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5853. VOID%@NL@%
  5854. Clear()%@NL@%
  5855. {%@NL@%
  5856.     fReadNumber = FALSE;%@NL@%
  5857.     fFirstOperand = TRUE;%@NL@%
  5858.     strcpy(szreg1, "0.");%@NL@%
  5859.     if (fError || chLastKey == 'c'){%@NL@%
  5860.         strcpy(szreg2, "0.");%@NL@%
  5861.         PendingOperation = NULL;%@NL@%
  5862.     }%@NL@%
  5863.     fError = FALSE;%@NL@%
  5864. }%@NL@%
  5865. %@NL@%
  5866. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5867. %@AB@%/* trash out trailing zeros, if a '.' is in the number                              */%@AE@%%@NL@%
  5868. %@AB@%/* and leading zeros in all cases.                                              */%@AE@%%@NL@%
  5869. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5870. VOID%@NL@%
  5871. Simplify()%@NL@%
  5872. {%@NL@%
  5873.     register INT iLen, iCount;%@NL@%
  5874.     CHAR         achLocal[20];%@NL@%
  5875. %@NL@%
  5876.     iCount = 0;%@NL@%
  5877.     strcpy(achLocal, szreg1);%@NL@%
  5878.     if (atof(achLocal) != 0.0) {%@NL@%
  5879.         while (achLocal[iCount++] == '0');%@NL@%
  5880.         strcpy(szreg1, &achLocal[iCount-1] );%@NL@%
  5881.     }%@NL@%
  5882.     if (strchr(szreg1, '.')) {%@NL@%
  5883.         iLen = strlen(szreg1);%@NL@%
  5884.         while (szreg1[--iLen] == '0');%@NL@%
  5885.         szreg1[min( iLen + 1, 11)] = 0; %@AB@%/* null terminate */%@AE@%%@NL@%
  5886.     }%@NL@%
  5887. }%@NL@%
  5888. %@NL@%
  5889. %@NL@%
  5890. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5891. VOID%@NL@%
  5892. DataXPaste()%@NL@%
  5893. {%@NL@%
  5894.     PSZ           psz;%@NL@%
  5895.     ULONG          ulText;%@NL@%
  5896.     register CHAR ch;%@NL@%
  5897. %@NL@%
  5898.     if (WinOpenClipbrd( hab))%@NL@%
  5899.     {%@NL@%
  5900.         ulText = WinQueryClipbrdData( hab, CF_TEXT);%@NL@%
  5901.         if (ulText)%@NL@%
  5902.         {%@NL@%
  5903.             psz = MAKEP( (SEL)ulText, 0);%@NL@%
  5904.             while (*psz)%@NL@%
  5905.             {%@NL@%
  5906.                 ch = (CHAR) (tolower(*psz));%@NL@%
  5907.                 if (ch == 'm')%@NL@%
  5908.                 {%@NL@%
  5909.                     psz++;%@NL@%
  5910.                     switch (tolower(*psz))%@NL@%
  5911.                     {%@NL@%
  5912.                         case '-':%@NL@%
  5913.                             ch = '\271';%@NL@%
  5914.                             break;%@NL@%
  5915.                         case '+':%@NL@%
  5916.                             ch = '\272';%@NL@%
  5917.                             break;%@NL@%
  5918.                         case 'r':%@NL@%
  5919.                             ch = '\273';%@NL@%
  5920.                             break;%@NL@%
  5921.                         case 'c':%@NL@%
  5922.                             ch = '\274';%@NL@%
  5923.                             break;%@NL@%
  5924.                         default:%@NL@%
  5925.                             ch = ' ';%@NL@%
  5926.                             break;%@NL@%
  5927.                     }%@NL@%
  5928.                 }%@NL@%
  5929.                 psz++;%@NL@%
  5930.                 InterpretChar(ch);%@NL@%
  5931.                 UpdateDisplay();%@NL@%
  5932.             }%@NL@%
  5933.         }%@NL@%
  5934.     }%@NL@%
  5935.     WinCloseClipbrd( hab);%@NL@%
  5936.     InterpretChar('=');%@NL@%
  5937.     UpdateDisplay();%@NL@%
  5938. }%@NL@%
  5939. %@NL@%
  5940. %@NL@%
  5941. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5942. VOID%@NL@%
  5943. DataXCopy()%@NL@%
  5944. {%@NL@%
  5945.     PSZ  pszText;%@NL@%
  5946. %@NL@%
  5947.     if (WinOpenClipbrd( hab))%@NL@%
  5948.     {%@NL@%
  5949.         WinEmptyClipbrd( hab);%@NL@%
  5950.         DosAllocSeg( 20, (SEL FAR *)&sel, SEG_GIVEABLE);%@NL@%
  5951.         if (sel == NULL) return;%@NL@%
  5952.         pszText = MAKEP(sel, 0);%@NL@%
  5953.         FarStrcpy( pszText, (PSZ)szreg1);%@NL@%
  5954.         WinSetClipbrdData( hab, (ULONG)sel, CF_TEXT, CFI_SELECTOR);%@NL@%
  5955.         WinCloseClipbrd( hab);%@NL@%
  5956.     }%@NL@%
  5957. }%@NL@%
  5958. %@NL@%
  5959. %@NL@%
  5960. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5961. VOID%@NL@%
  5962. MPlus()%@NL@%
  5963. {%@NL@%
  5964.     double dblX1, dblX2, dblResult;%@NL@%
  5965. %@NL@%
  5966.     dblX2 = atof(szmem);%@NL@%
  5967.     dblX1 = atof(szreg1);%@NL@%
  5968. %@NL@%
  5969.     if (dblX2>(double)0) {            %@AB@%/* check for overflow */%@AE@%%@NL@%
  5970.         if (dblX1>(double)0) {%@NL@%
  5971.             if (dblX1 > (MAXINT - dblX2))%@NL@%
  5972.                 fError = TRUE;%@NL@%
  5973.         }%@NL@%
  5974.     }%@NL@%
  5975.     else if (dblX2 < (double)0) {%@NL@%
  5976.              if (dblX1 < (double)0) {%@NL@%
  5977.                  if ( dblX1 < (MININT - dblX2))%@NL@%
  5978.                      fError = TRUE;%@NL@%
  5979.              }%@NL@%
  5980.          }%@NL@%
  5981.     if (!fError) {%@NL@%
  5982.         dblResult = dblX2 + dblX1;%@NL@%
  5983.         strcpy( szmem, ftoa((double)dblResult));%@NL@%
  5984.     }%@NL@%
  5985.     if (dblResult == (double)0.0)%@NL@%
  5986.          fValueInMemory = FALSE; %@NL@%
  5987.     else fValueInMemory = TRUE;%@NL@%
  5988. }%@NL@%
  5989. %@NL@%
  5990. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  5991. VOID%@NL@%
  5992. MClear()%@NL@%
  5993. {%@NL@%
  5994.      strcpy(szmem, "0.");   %@NL@%
  5995.      fValueInMemory = FALSE; %@NL@%
  5996. }%@NL@%
  5997. %@NL@%
  5998. %@NL@%
  5999. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  6000. VOID%@NL@%
  6001. MMinus()%@NL@%
  6002. {%@NL@%
  6003.     double dblX1, dblX2, dblResult;%@NL@%
  6004. %@NL@%
  6005.     dblX2 = atof(szmem);%@NL@%
  6006.     dblX1 = atof(szreg1);%@NL@%
  6007.     if (dblX2 < (double)0) {%@NL@%
  6008.         if (dblX1 > (double)0) {%@NL@%
  6009.             if (dblX1 > (dblX2 - MININT))%@NL@%
  6010.                 fError = TRUE;%@NL@%
  6011.         }%@NL@%
  6012.     }%@NL@%
  6013.     else if (dblX2 > (double)0) {%@NL@%
  6014.             if (dblX1 < (double)0) {%@NL@%
  6015.                 if (dblX1 < (dblX2 - MAXINT))%@NL@%
  6016.                     fError = TRUE;%@NL@%
  6017.             }%@NL@%
  6018.          }%@NL@%
  6019.     if (!fError) {%@NL@%
  6020.         dblResult = dblX2 - dblX1;%@NL@%
  6021.         strcpy( szmem, ftoa((double)dblResult));%@NL@%
  6022.     }%@NL@%
  6023.     if (dblResult == (double)0.0)%@NL@%
  6024.          fValueInMemory = FALSE; %@NL@%
  6025.     else fValueInMemory = TRUE;%@NL@%
  6026. }%@NL@%
  6027. %@NL@%
  6028. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  6029. VOID%@NL@%
  6030. Evaluate( bCommand)%@NL@%
  6031. %@NL@%
  6032. BYTE bCommand;%@NL@%
  6033. {%@NL@%
  6034.     switch( bCommand ) {%@NL@%
  6035.         case '0': case '1': case '2': case '3': case '4': case '5':%@NL@%
  6036.         case '6': case '7': case '8': case '9': case '.': case 0xb1:%@NL@%
  6037.         case 'n': %@AB@%/* n = 'negate'  from keyboard */%@AE@%%@NL@%
  6038.             if ( fReadNumber )%@NL@%
  6039.                 AppendNumber( bCommand );%@NL@%
  6040.             else {%@NL@%
  6041.                       %@AB@%/* if starting a new number */%@AE@%%@NL@%
  6042.                 if (bCommand != 0xb1)%@NL@%
  6043.                     strcpy(szreg1, "0");%@NL@%
  6044.                 AppendNumber( bCommand );%@NL@%
  6045.             }%@NL@%
  6046.             if (bCommand != 0xb1)%@NL@%
  6047.                 fReadNumber = TRUE;%@NL@%
  6048.             break;%@NL@%
  6049.         case '+': case '-': case '/': case '*': case 'p':%@NL@%
  6050.             BinaryOperator(bCommand);%@NL@%
  6051.             fReadNumber = FALSE;%@NL@%
  6052.             break;%@NL@%
  6053.         case '=':%@NL@%
  6054.             fReadNumber = FALSE;%@NL@%
  6055.             Equilibrate();%@NL@%
  6056.             PendingOperation = NULL;%@NL@%
  6057.             break;%@NL@%
  6058.         case 'q':%@NL@%
  6059.             SquareRoot();%@NL@%
  6060.             fReadNumber = FALSE;%@NL@%
  6061.             break;%@NL@%
  6062.         case 0xBB:   %@AB@%/* MR */%@AE@%%@NL@%
  6063.             strcpy(szreg1, szmem);%@NL@%
  6064.             fReadNumber = FALSE;%@NL@%
  6065.             Simplify();%@NL@%
  6066.             break;%@NL@%
  6067.         case 0xBA: %@AB@%/* M+ */%@AE@%%@NL@%
  6068.             MPlus();%@NL@%
  6069.             fReadNumber = FALSE;%@NL@%
  6070.             Simplify();%@NL@%
  6071.             break;%@NL@%
  6072.         case 0xB9: %@AB@%/* M- */%@AE@%%@NL@%
  6073.             MMinus();%@NL@%
  6074.             fReadNumber = FALSE;%@NL@%
  6075.             Simplify();%@NL@%
  6076.             break;%@NL@%
  6077.         case 0xBC:%@NL@%
  6078.             MClear(); %@AB@%/* MC */%@AE@%%@NL@%
  6079.             break;%@NL@%
  6080.         case '%':%@NL@%
  6081.             Percent();%@NL@%
  6082.             fReadNumber = FALSE;%@NL@%
  6083.             break;%@NL@%
  6084.         case 'c':%@NL@%
  6085.             Clear();%@NL@%
  6086.             break;%@NL@%
  6087.         }%@NL@%
  6088. }%@NL@%
  6089. %@NL@%
  6090. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  6091. VOID%@NL@%
  6092. Percent()%@NL@%
  6093. {%@NL@%
  6094.     double dblX1, dblX2, dblResult;%@NL@%
  6095. %@NL@%
  6096.     dblX1 = atof(szreg1) / 100.0;%@NL@%
  6097.     dblX2 = atof(szreg2);%@NL@%
  6098.     if (ABS(dblX2) > (double)1) {%@NL@%
  6099.         if (ABS(dblX1) > (double)1) {%@NL@%
  6100.             if (dblX1 > (MAXINT / dblX2))%@NL@%
  6101.                 fError = TRUE;%@NL@%
  6102.         }%@NL@%
  6103.     }%@NL@%
  6104.     if (!fError) {%@NL@%
  6105.         dblResult = dblX2 * dblX1;%@NL@%
  6106.         strcpy( szreg1, ftoa((double)dblResult));%@NL@%
  6107.     }%@NL@%
  6108.     Simplify();%@NL@%
  6109. }%@NL@%
  6110. %@NL@%
  6111. %@AB@%/******************************************************************************/%@AE@%%@NL@%
  6112. VOID%@NL@%
  6113. InitCalc()%@NL@%
  6114. {%@NL@%
  6115.     fReadNumber = FALSE;%@NL@%
  6116.     fError = FALSE;%@NL@%
  6117.     fFirstOperand = TRUE;%@NL@%
  6118.     PendingOperation = 0;%@NL@%
  6119.     strcpy(szreg1, "0.");%@NL@%
  6120.     strcpy(szmem,  "0.");%@NL@%
  6121. }%@NL@%
  6122. %@NL@%
  6123. %@NL@%
  6124. %@2@%%@AH@%CASCADE.C%@AE@%%@EH@%%@NL@%
  6125. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CASCADE\CASCADE.C%@AE@%%@NL@%
  6126. %@NL@%
  6127. %@AI@%#define %@AE@%INCL_PM %@NL@%
  6128. %@AI@%#include %@AE@%<OS2.H> %@NL@%
  6129. %@AI@%#include %@AE@%"Cascade.H" %@NL@%
  6130. %@NL@%
  6131. char szAppName[] = "Cascade";%@NL@%
  6132. char szAppTitle[] = "Cascading Menu Example";%@NL@%
  6133. %@NL@%
  6134. HAB        hAB;%@NL@%
  6135. HMQ        hmqMsgQueue;%@NL@%
  6136. HWND        hWndMain,%@NL@%
  6137.         hWndFrame;%@NL@%
  6138. %@NL@%
  6139. int cdecl main()%@NL@%
  6140. {%@NL@%
  6141.     QMSG    qmsg;%@NL@%
  6142.     ULONG   ctlData = FCF_STANDARD & ~FCF_ACCELTABLE;%@NL@%
  6143. %@NL@%
  6144.     hAB = WinInitialize (0);%@NL@%
  6145. %@NL@%
  6146.     hmqMsgQueue = WinCreateMsgQueue (hAB, 0);%@NL@%
  6147. %@NL@%
  6148.     if (!WinRegisterClass (hAB,%@NL@%
  6149.                            szAppName,%@NL@%
  6150.                            WndProc,%@NL@%
  6151.                            CS_SYNCPAINT | CS_SIZEREDRAW,%@NL@%
  6152.                            0)) {%@NL@%
  6153.         return(0);%@NL@%
  6154.     }%@NL@%
  6155. %@NL@%
  6156.     hWndFrame = WinCreateStdWindow ( HWND_DESKTOP,%@NL@%
  6157.                                     WS_VISIBLE,%@NL@%
  6158.                                     &ctlData,%@NL@%
  6159.                                     szAppName,%@NL@%
  6160.                                     NULL,%@NL@%
  6161.                                     0L,%@NL@%
  6162.                                     0,%@NL@%
  6163.                                     ID_RESOURCE,%@NL@%
  6164.                                     &hWndMain);%@NL@%
  6165.     WinSetWindowText (hWndFrame, szAppTitle);%@NL@%
  6166.     WinShowWindow (hWndFrame, TRUE);%@NL@%
  6167. %@NL@%
  6168.     while ( WinGetMsg (hAB, &qmsg, NULL, 0, 0)) {%@NL@%
  6169.         WinDispatchMsg (hAB, &qmsg);%@NL@%
  6170.     }%@NL@%
  6171. %@NL@%
  6172.     WinDestroyWindow   (hWndFrame);%@NL@%
  6173.     WinDestroyMsgQueue (hmqMsgQueue);%@NL@%
  6174.     WinTerminate       (hAB);%@NL@%
  6175. }%@NL@%
  6176. %@NL@%
  6177. %@AB@%/*-------------------------------------------------------------------*/%@AE@%%@NL@%
  6178. %@AB@%/*                                                                     */%@AE@%%@NL@%
  6179. %@AB@%/*-------------------------------------------------------------------*/%@AE@%%@NL@%
  6180. %@NL@%
  6181. BOOL CheckAll (HWND hMenu, int item, BOOL check);%@NL@%
  6182. BOOL CheckAll (HWND hMenu, int item, BOOL check)%@NL@%
  6183. {%@NL@%
  6184.     int mPos,max,test;%@NL@%
  6185.     MENUITEM mi;%@NL@%
  6186.     char szText[20];%@NL@%
  6187.     MPARAM  mp1, mp2;%@NL@%
  6188. %@NL@%
  6189.     max =(int) SHORT1FROMMR( WinSendMsg (hMenu, MM_QUERYITEMCOUNT, 0L, 0L) ); %@NL@%
  6190. %@NL@%
  6191.     for (mPos=0; mPos!=(int) max; mPos++) {%@NL@%
  6192.         test =(int) SHORT1FROMMR( WinSendMsg (hMenu, MM_ITEMIDFROMPOSITION, MPFROMSHORT(mPos), 0L) );%@NL@%
  6193.         WinSendMsg (hMenu, MM_QUERYITEMTEXT, MPFROM2SHORT(test,sizeof(szText)), MPFROMP(szText));%@NL@%
  6194.         if (test == item) {%@NL@%
  6195.             mp1 = MPFROM2SHORT (test, TRUE);%@NL@%
  6196.             if (check)%@NL@%
  6197.                 mp2 = MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED);%@NL@%
  6198.             else%@NL@%
  6199.                 mp2 = MPFROM2SHORT(MIA_CHECKED, 0);%@NL@%
  6200.             WinPostMsg (hMenu, MM_SETITEMATTR, mp1, mp2);%@NL@%
  6201.             return TRUE;%@NL@%
  6202.         } else {%@NL@%
  6203.             WinSendMsg (hMenu, MM_QUERYITEM, MPFROM2SHORT(test,FALSE), (MPARAM)&mi);%@NL@%
  6204.             if (mi.hwndSubMenu) {%@NL@%
  6205.                 if (CheckAll(mi.hwndSubMenu, item, check)) {%@NL@%
  6206.                     mp1 = MPFROM2SHORT (test, TRUE);%@NL@%
  6207.                     if (check)%@NL@%
  6208.                         mp2 = MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED);%@NL@%
  6209.                     else%@NL@%
  6210.                         mp2 = MPFROM2SHORT(MIA_CHECKED, 0);%@NL@%
  6211.                     WinPostMsg (hMenu, MM_SETITEMATTR, mp1, mp2);%@NL@%
  6212.                     return TRUE;%@NL@%
  6213.                 }%@NL@%
  6214. %@NL@%
  6215.             }%@NL@%
  6216.         }%@NL@%
  6217.     }%@NL@%
  6218.     return FALSE;%@NL@%
  6219. }%@NL@%
  6220. %@NL@%
  6221. %@AB@%/*-------------------------------------------------------------------*/%@AE@%%@NL@%
  6222. %@AB@%/*                                                                     */%@AE@%%@NL@%
  6223. %@AB@%/*-------------------------------------------------------------------*/%@AE@%%@NL@%
  6224. %@NL@%
  6225. %@NL@%
  6226. MRESULT EXPENTRY WndProc (hWnd, msg, mp1, mp2)%@NL@%
  6227.     HWND    hWnd;%@NL@%
  6228.     USHORT  msg;%@NL@%
  6229.     MPARAM  mp1, mp2;%@NL@%
  6230. {%@NL@%
  6231.     HPS           hPS;%@NL@%
  6232.     HWND   hMenu;%@NL@%
  6233.     static int          prevFont = 0;%@NL@%
  6234.     int thisItem;%@NL@%
  6235. %@NL@%
  6236.     switch (msg) {%@NL@%
  6237. %@NL@%
  6238.         case WM_COMMAND:%@NL@%
  6239.             thisItem = SHORT1FROMMP(mp1);%@NL@%
  6240.             switch (thisItem) {%@NL@%
  6241.                 case IDM_ABOUT:%@NL@%
  6242.                     WinMessageBox (HWND_DESKTOP, hWnd,%@NL@%
  6243.                         "Sample PM Application",%@NL@%
  6244.                         szAppTitle, 1, MB_OK | MB_APPLMODAL | MB_MOVEABLE);%@NL@%
  6245.                     break;%@NL@%
  6246.                 default:%@NL@%
  6247.                     if ((thisItem >= IDM_FIRSTFONT) && (thisItem<= IDM_LASTFONT)) {%@NL@%
  6248.                         hMenu        = WinWindowFromID (%@NL@%
  6249.                                     WinQueryWindow (hWnd, QW_PARENT, FALSE),%@NL@%
  6250.                                     FID_MENU);%@NL@%
  6251.                         CheckAll (hMenu, prevFont, FALSE);%@NL@%
  6252.                         CheckAll (hMenu, thisItem, TRUE);%@NL@%
  6253.                         prevFont = thisItem;%@NL@%
  6254.                     } else {%@NL@%
  6255.                         DosBeep(600,60);%@NL@%
  6256.                     }%@NL@%
  6257.             }%@NL@%
  6258.             break;%@NL@%
  6259. %@NL@%
  6260.         case WM_CLOSE:%@NL@%
  6261.             WinPostMsg (hWnd, WM_QUIT, 0L, 0L);%@NL@%
  6262.             break;%@NL@%
  6263. %@NL@%
  6264.         case WM_ERASEBACKGROUND:%@NL@%
  6265.             return ((MRESULT) TRUE);%@NL@%
  6266.             break;%@NL@%
  6267. %@NL@%
  6268.         case WM_PAINT:%@NL@%
  6269.             hPS = WinBeginPaint (hWnd, NULL, (PWRECT)NULL);%@NL@%
  6270.             WinEndPaint (hPS);%@NL@%
  6271.             break;%@NL@%
  6272. %@NL@%
  6273.         default:%@NL@%
  6274.             return (WinDefWindowProc (hWnd, msg, mp1, mp2));%@NL@%
  6275.             break;%@NL@%
  6276.     }%@NL@%
  6277.     return 0L;%@NL@%
  6278. }%@NL@%
  6279. %@NL@%
  6280. %@NL@%
  6281. %@2@%%@AH@%CHASER.C%@AE@%%@EH@%%@NL@%
  6282. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CHASER\CHASER.C%@AE@%%@NL@%
  6283. %@NL@%
  6284. %@AB@%/*  SWARM%@NL@%
  6285. %@AB@% *  Created by Microsoft Corp. 1986%@NL@%
  6286. %@AB@% *%@NL@%
  6287. %@AB@% *  the idea behind this game is as follows:%@NL@%
  6288. %@AB@% *%@NL@%
  6289. %@AB@% *   You have a collection of objects in the center of the playing field%@NL@%
  6290. %@AB@% *   that you are trying to protect (just one object in current version). You%@NL@%
  6291. %@AB@% *   control your own movements with the mouse. A number of "chasers" start%@NL@%
  6292. %@AB@% *   around the edges of the field and begin moving towards the objects%@NL@%
  6293. %@AB@% *   you want to protect. If you move the mouse on top of a chaser and click%@NL@%
  6294. %@AB@% *   the left button, the chaser will be killed and disappear from the screen.%@NL@%
  6295. %@AB@% *   But as you close in on the chaser, it will detect your presence and try%@NL@%
  6296. %@AB@% *   to dodge you. Meanwhile the other chasers will continue to go after%@NL@%
  6297. %@AB@% *   your objects. If one of the chasers reaches an object, it will begin%@NL@%
  6298. %@AB@% *   dragging it away to the edge of the screen (currently the game just%@NL@%
  6299. %@AB@% *   ends when the single object is reached). When all objects are dragged%@NL@%
  6300. %@AB@% *   away, the game ends. If a chaser is killed while dragging an object, the%@NL@%
  6301. %@AB@% *   object is left where it is and must be protected in place - player cannot%@NL@%
  6302. %@AB@% *   move objects. If you kill all the chasers, a new group of faster ones%@NL@%
  6303. %@AB@% *   will be spawned (currently the speed is constant). Your score is how%@NL@%
  6304. %@AB@% *   many chasers you can kill (no score currently kept), so there is no%@NL@%
  6305. %@AB@% *   advantage in sitting on the object for long periods.%@NL@%
  6306. %@AB@% *%@NL@%
  6307. %@AB@% * Swarm demonstrates several capabilities of OS/2 and the philosphy behind%@NL@%
  6308. %@AB@% * them.  This program is made of three components: Initialization, the%@NL@%
  6309. %@AB@% * mouse driven thread and the attacker thread.  The attacker thread is%@NL@%
  6310. %@AB@% * launched as many times as there are attackers in a game.  Launching%@NL@%
  6311. %@AB@% * the attacker several times takes full advantage of the OS to schedule%@NL@%
  6312. %@AB@% * resources.  The programmer can think of the problem as only one attacker.%@NL@%
  6313. %@AB@% * The system handles multiple instances of the thread.%@NL@%
  6314. %@AB@% *%@NL@%
  6315. %@AB@% * As the main loop launches threads it puts an ID code into the thread's%@NL@%
  6316. %@AB@% * stack.  The code is used to index into the universe data.%@NL@%
  6317. %@AB@% *%@NL@%
  6318. %@AB@% * A ram semaphore is used to control access to global data.%@NL@%
  6319. %@AB@% *%@NL@%
  6320. %@AB@% * This demonstration shows the use of the following OS/2 system calls:%@NL@%
  6321. %@AB@% *%@NL@%
  6322. %@AB@% * Tasking:               VIO API:              Mouse API:%@NL@%
  6323. %@AB@% *%@NL@%
  6324. %@AB@% *   DosSemRequest()         VioScrollUp()               MouOpen()%@NL@%
  6325. %@AB@% *   DosSemClear()         VioWrtCellStr()       MouSetPtrPos()%@NL@%
  6326. %@AB@% *   DosCreateThread()         VioSetCurType()       MouReadEventQue()%@NL@%
  6327. %@AB@% *   DosExit()                 VioSetMode()%@NL@%
  6328. %@AB@% *   DosSleep()%@NL@%
  6329. %@AB@% */%@AE@%%@NL@%
  6330. %@AI@%#include %@AE@%<os2def.h> %@NL@%
  6331. %@AI@%#define %@AE@%INCL_DOSPROCESS %@NL@%
  6332. %@AI@%#define %@AE@%INCL_DOSSEMAPHORES %@NL@%
  6333. %@AI@%#include %@AE@%<bsedos.h> %@NL@%
  6334. %@AI@%#define %@AE@%INCL_SUB %@NL@%
  6335. %@AI@%#include %@AE@%<bsesub.h> %@NL@%
  6336. %@AI@%#include %@AE@%<malloc.h> %@NL@%
  6337. %@AI@%#undef %@AE@%NULL %@NL@%
  6338. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  6339. %@NL@%
  6340. %@AI@%#define %@AE@% STACKSIZE  200 %@NL@%
  6341. %@NL@%
  6342. %@AI@%#define %@AE@% DANGERZONE  3 %@NL@%
  6343. %@NL@%
  6344. %@AI@%#define %@AE@% LONGNAP     500L %@NL@%
  6345. %@AI@%#define %@AE@% SHORTNAP    150L %@NL@%
  6346. %@NL@%
  6347.  WAIT (-1L)                        %@AB@%/* Wait for ram Semaphore */%@AE@%%@NL@%
  6348. %@NL@%
  6349.  CHASER    8                        %@AB@%/* Number of chasers */%@AE@%%@NL@%
  6350. %@NL@%
  6351.  SCREEN_HEIGHT           24                %@AB@%/* Default screen size */%@AE@%%@NL@%
  6352. %@AI@%#define %@AE@% SCREEN_WIDTH           79 %@NL@%
  6353. %@NL@%
  6354.  GOAL univ[CHASER]                %@AB@%/* Macros for constant stuff */%@AE@%%@NL@%
  6355. %@AI@%#define %@AE@% ME univ[ID] %@NL@%
  6356. %@AI@%#define %@AE@% MOUSE univ[CHASER+1] %@NL@%
  6357. %@NL@%
  6358.  ALIVE 1                        %@AB@%/* Flags for attackers/goal */%@AE@%%@NL@%
  6359. %@AI@%#define %@AE@% DEAD 0 %@NL@%
  6360. %@NL@%
  6361. char   Chaser[2] = { 0xE8, 0x20 };   %@AB@%/* character and attribute */%@AE@%%@NL@%
  6362. char        Prize[2] = { 0x03, 0x2C };   %@AB@%/* for our various objects */%@AE@%%@NL@%
  6363. char        Blank[2] = { 0x20, 0x22 };%@NL@%
  6364. char        Blood[2] = { 0x20, 0x44 };%@NL@%
  6365. %@NL@%
  6366. struct {                              %@AB@%/* Universe structure and array */%@AE@%%@NL@%
  6367.     int     row;                        %@AB@%/* univ[0] = chaser     */%@AE@%%@NL@%
  6368.     int     col;                        %@AB@%/* univ[n-1] = chaser     */%@AE@%%@NL@%
  6369.     int     state;                        %@AB@%/* univ[n] = GOAL */%@AE@%%@NL@%
  6370. } univ[CHASER+1];                        %@AB@%/* univ[n+1]= MOUSE */%@AE@%%@NL@%
  6371. %@NL@%
  6372. short                ScreenHeight,                %@AB@%/* Screen attributes */%@AE@%%@NL@%
  6373.                 ScreenWidth;%@NL@%
  6374. %@NL@%
  6375. HMOU                Mouse;                        %@AB@%/* place for mouse handle */%@AE@%%@NL@%
  6376. ULONG                Shortnap;                %@AB@%/* Sleep times for chasers */%@AE@%%@NL@%
  6377. ULONG                Longnap;%@NL@%
  6378. ULONG                Semaphore = 0;                %@AB@%/* Ram semaphore */%@AE@%%@NL@%
  6379. %@NL@%
  6380. struct _VIOCURSORINFO        NewCur;         %@AB@%/* struct for setting cursor type */%@AE@%%@NL@%
  6381. struct _VIOCURSORINFO        OldCur;%@NL@%
  6382. %@NL@%
  6383. struct _VIOMODEINFO        modedata;        %@AB@%/* Data saves for VIO mode */%@AE@%%@NL@%
  6384. struct _VIOMODEINFO        OldVioMode;%@NL@%
  6385. %@NL@%
  6386. %@AB@%/*%@NL@%
  6387. %@AB@% * Define all procedures before main.%@NL@%
  6388. %@AB@% */%@AE@%%@NL@%
  6389. void Defender();%@NL@%
  6390. void CleanUp();%@NL@%
  6391. int InitGame();%@NL@%
  6392. void chaserthread();%@NL@%
  6393. int ParseCmdLine(int,char **);%@NL@%
  6394. %@NL@%
  6395. %@AB@%/*%@NL@%
  6396. %@AB@% * main(ac,av)%@NL@%
  6397. %@AB@% *%@NL@%
  6398. %@AB@% * Top level procedure and MOUSE thread for the GAME demo.%@NL@%
  6399. %@AB@% */%@AE@%%@NL@%
  6400. int main(ac, av)%@NL@%
  6401. int ac;%@NL@%
  6402. char *av[];%@NL@%
  6403. {%@NL@%
  6404.     %@AB@%/*%@NL@%
  6405. %@AB@%     * Parse the command line and perform some initialization.%@NL@%
  6406. %@AB@%     */%@AE@%%@NL@%
  6407.     if (ParseCmdLine(ac,av)) {%@NL@%
  6408.         printf("usage: %s [24|43] [F|M|S]\n",av[0]);%@NL@%
  6409.         DosExit(EXIT_THREAD,1);%@NL@%
  6410.     }%@NL@%
  6411.     if (InitGame())                %@AB@%/* Init game, exit if some problem */%@AE@%%@NL@%
  6412.         DosExit(EXIT_PROCESS,1);%@NL@%
  6413. %@NL@%
  6414.     Defender();                 %@AB@%/* Run mouse loop (defend against the swarm) */%@AE@%%@NL@%
  6415. %@NL@%
  6416.     CleanUp();%@NL@%
  6417. }%@NL@%
  6418. %@NL@%
  6419. %@AB@%/*%@NL@%
  6420. %@AB@% * Defender()%@NL@%
  6421. %@AB@% *%@NL@%
  6422. %@AB@% * This is the main loop of the mouse control thread.%@NL@%
  6423. %@AB@% *%@NL@%
  6424. %@AB@% * The semaphore is used to prevent the other threads from time slicing %@NL@%
  6425. %@AB@% * while this routine is examining and/or modifying the universe.  The %@NL@%
  6426. %@AB@% * Semaphore is grabbed after the read of the Mouse queue so we don't tie%@NL@%
  6427. %@AB@% * up the attackers while waiting for a mouse event.%@NL@%
  6428. %@AB@% */%@AE@%%@NL@%
  6429. void Defender()%@NL@%
  6430. {%@NL@%
  6431.     USHORT ReadType = 1,        %@AB@%/* Wait for mouse events */%@AE@%%@NL@%
  6432.            alive,%@NL@%
  6433.            i;%@NL@%
  6434.     struct _MOUEVENTINFO  MouInfo;    %@AB@%/* mouse event packet structure */%@AE@%%@NL@%
  6435. %@NL@%
  6436.     alive = CHASER;%@NL@%
  6437. %@NL@%
  6438.     do {%@NL@%
  6439.         MouReadEventQue( &MouInfo, &ReadType, Mouse); %@AB@%/* read where mouse is */%@AE@%%@NL@%
  6440. %@NL@%
  6441.         DosSemRequest( &Semaphore, WAIT);%@NL@%
  6442. %@NL@%
  6443.         if( MouInfo.fs & 1) {                      %@AB@%/* If the mouse has moved */%@AE@%%@NL@%
  6444.             MOUSE.row = MouInfo.row;%@NL@%
  6445.             MOUSE.col = MouInfo.col;%@NL@%
  6446.         }%@NL@%
  6447.         if( MouInfo.fs & 4 ) {                       %@AB@%/* if left button pressed, */%@AE@%%@NL@%
  6448.             for (i = 0; i < CHASER; i++ ) {%@NL@%
  6449.                 if( ( MOUSE.row == univ[i].row ) &&%@NL@%
  6450.                     ( MOUSE.col == univ[i].col ) &&  %@AB@%/* see if we hit one */%@AE@%%@NL@%
  6451.                     ( univ[i].state == ALIVE) ) {%@NL@%
  6452.                      univ[i].state = DEAD;        %@NL@%
  6453. %@NL@%
  6454.                      DosBeep(300,75);                     %@AB@%/* make a dying sound */%@AE@%%@NL@%
  6455.                      DosBeep(600,75);%@NL@%
  6456.                      DosBeep(300,85);%@NL@%
  6457. %@NL@%
  6458.                      alive--;                    %@AB@%/* Decrease number alive */%@AE@%%@NL@%
  6459.                      break;                    %@AB@%/* Can only kill one at a time */%@AE@%%@NL@%
  6460.                 }%@NL@%
  6461.             }%@NL@%
  6462.         }%@NL@%
  6463.         if( MouInfo.fs & 16 )              %@AB@%/* If right button pressed... */%@AE@%%@NL@%
  6464.             break;                        %@AB@%/* End game, clean up */%@AE@%%@NL@%
  6465. %@NL@%
  6466.         DosSemClear(&Semaphore);%@NL@%
  6467.     }%@NL@%
  6468.     while (GOAL.state == ALIVE && alive);    %@AB@%/* loop till all are dead */%@AE@%%@NL@%
  6469. }%@NL@%
  6470. %@NL@%
  6471. %@AB@%/*%@NL@%
  6472. %@AB@% * This thread manages the individual attackers.  It is spun off as%@NL@%
  6473. %@AB@% * many times as needed for a game.%@NL@%
  6474. %@AB@% *%@NL@%
  6475. %@AB@% * The interaction of the mouse cursor and the chaser character is sort%@NL@%
  6476. %@AB@% * of funny, hence the funny code, below.  The mouse cursor seems to%@NL@%
  6477. %@AB@% * remember what was under it when it was written.  Hence we cannot erase%@NL@%
  6478. %@AB@% * the chaser if the mouse is "sitting" on it.        If we do, then when the%@NL@%
  6479. %@AB@% * mouse moves it will re-write the original object.  This shows up as%@NL@%
  6480. %@AB@% * phantom chasers.%@NL@%
  6481. %@AB@% */%@AE@%%@NL@%
  6482. void far chasethread(ID)               %@AB@%/* code that controls each "chaser" */%@AE@%%@NL@%
  6483. int ID;%@NL@%
  6484. {%@NL@%
  6485.     short  row, col;               %@AB@%/* Our current position */%@AE@%%@NL@%
  6486.     short  deltaX, deltaY;     %@AB@%/* how far from the mouse are we? */%@AE@%%@NL@%
  6487.     short  danger;               %@AB@%/* flag to indicate not far enough! */%@AE@%%@NL@%
  6488.     short  m;                       %@AB@%/* general purpose indexes */%@AE@%%@NL@%
  6489. %@NL@%
  6490. %@NL@%
  6491.     %@AB@%/* Print out the initial chaser character */%@AE@%%@NL@%
  6492. %@NL@%
  6493.     VioWrtCellStr( Chaser, 2, ME.row, ME.col, 0 );%@NL@%
  6494. %@NL@%
  6495.     %@AB@%/*%@NL@%
  6496. %@AB@%     * Keep running as long as the goal and myself haven't been killed.%@NL@%
  6497. %@AB@%     */%@AE@%%@NL@%
  6498.     for (;;) {%@NL@%
  6499. %@NL@%
  6500.         row = ME.row;                  %@AB@%/* Grab the current position */%@AE@%%@NL@%
  6501.         col = ME.col;%@NL@%
  6502.         %@AB@%/*%@NL@%
  6503. %@AB@%         * If mouse is sitting upon the chaser, do nothing.  Allow%@NL@%
  6504. %@AB@%         * the player some time to kill the chaser%@NL@%
  6505. %@AB@%         */%@AE@%%@NL@%
  6506.         if ((MOUSE.row == row) && (MOUSE.col == col)) {%@NL@%
  6507.             DosSleep( 1L );%@NL@%
  6508.             continue;%@NL@%
  6509.         }%@NL@%
  6510.         DosSemRequest(&Semaphore, WAIT);%@NL@%
  6511.         %@AB@%/*%@NL@%
  6512. %@AB@%         * If either the GOAL or Myself is dead, exit loop and clean up.%@NL@%
  6513. %@AB@%         * This wasn't tested in the for loop since we don't want to exit%@NL@%
  6514. %@AB@%         * if the MOUSE is sitting on the chaser.%@NL@%
  6515. %@AB@%         */%@AE@%%@NL@%
  6516.         if (ME.state != ALIVE || GOAL.state != ALIVE)%@NL@%
  6517.             break;%@NL@%
  6518. %@NL@%
  6519.         deltaX = MOUSE.col - col;        %@AB@%/* calculate how far we are */%@AE@%%@NL@%
  6520.         deltaY = MOUSE.row - row;%@NL@%
  6521. %@NL@%
  6522.         if (((deltaX < -DANGERZONE) || (DANGERZONE < deltaX)) ||%@NL@%
  6523.             ((deltaY < -DANGERZONE) || (DANGERZONE < deltaY))) {%@NL@%
  6524. %@NL@%
  6525.             danger = 0;%@NL@%
  6526. %@NL@%
  6527.             if(GOAL.row < row)                    %@AB@%/* Creep towards the GOAL */%@AE@%%@NL@%
  6528.                 row--;%@NL@%
  6529.             else if (GOAL.row > row)%@NL@%
  6530.                 row++;%@NL@%
  6531.             if(GOAL.col < col)%@NL@%
  6532.                 col--;%@NL@%
  6533.             else if(GOAL.col > col)%@NL@%
  6534.                 col++;%@NL@%
  6535.         }%@NL@%
  6536.         else {%@NL@%
  6537.             danger = 1;                     %@AB@%/* Run away from the mouse */%@AE@%%@NL@%
  6538. %@NL@%
  6539.             if ((MOUSE.row > row) && (row > 0))%@NL@%
  6540.                 row--;%@NL@%
  6541.             else if ((MOUSE.row < row) && (row < ScreenHeight))%@NL@%
  6542.                 row++;%@NL@%
  6543.             if ((MOUSE.col > col) && (col < ScreenWidth))%@NL@%
  6544.                 col--;%@NL@%
  6545.             else if ((MOUSE.col < col) && (col > 0))%@NL@%
  6546.                 col++;%@NL@%
  6547.         }%@NL@%
  6548.         %@AB@%/*%@NL@%
  6549. %@AB@%         * A quick and Dirty hack to prevent chasers from merging%@NL@%
  6550. %@AB@%         */%@AE@%%@NL@%
  6551.         for (m = 0; m < CHASER; m++ ) {%@NL@%
  6552.             if (univ[m].state == ALIVE &&%@NL@%
  6553.                 univ[m].row == row &&%@NL@%
  6554.                 univ[m].col == col &&%@NL@%
  6555.                 m != ID) {%@NL@%
  6556.                row += 1;%@NL@%
  6557.                col += 3;%@NL@%
  6558.             }%@NL@%
  6559.         }%@NL@%
  6560.         %@AB@%/*%@NL@%
  6561. %@AB@%         * Zap the old chaser and print the new.  Release the semaphore%@NL@%
  6562. %@AB@%         * after this, there can be no undesirable interactions now.%@NL@%
  6563. %@AB@%         */%@AE@%%@NL@%
  6564.         VioWrtCellStr( Blank, 2, ME.row, ME.col, 0 );%@NL@%
  6565.         VioWrtCellStr( Chaser, 2, row, col, 0 );%@NL@%
  6566. %@NL@%
  6567.         DosSemClear(&Semaphore);%@NL@%
  6568.         %@AB@%/*%@NL@%
  6569. %@AB@%         * Update the current location%@NL@%
  6570. %@AB@%         */%@AE@%%@NL@%
  6571.         ME.row = row;%@NL@%
  6572.         ME.col = col;%@NL@%
  6573.         %@AB@%/*%@NL@%
  6574. %@AB@%         * See if we have reached the GOAL, if so eat it and exit%@NL@%
  6575. %@AB@%         */%@AE@%%@NL@%
  6576.         if ((row == GOAL.row) && (col == GOAL.col)) {%@NL@%
  6577.             VioWrtCellStr( Blank, 2, row, col, 0 );%@NL@%
  6578.             DosBeep(600,175);%@NL@%
  6579.             DosBeep(1200,175);            %@AB@%/* if we reach the prize, let out a yell */%@AE@%%@NL@%
  6580.             DosBeep(600,185);            %@AB@%/* paint the screen red and end the game */%@AE@%%@NL@%
  6581.             DosBeep(1200,175);%@NL@%
  6582.             VioScrollUp( 0, 0, -1, -1, -1, Blood, 0 );%@NL@%
  6583.             GOAL.state = DEAD;%@NL@%
  6584.         }%@NL@%
  6585.         %@AB@%/*%@NL@%
  6586. %@AB@%         * Sleep an amount of time that varies depending%@NL@%
  6587. %@AB@%         * upon the danger level%@NL@%
  6588. %@AB@%         */%@AE@%%@NL@%
  6589.         if( danger )%@NL@%
  6590.             DosSleep(Shortnap);%@NL@%
  6591.         else%@NL@%
  6592.             DosSleep(Longnap);%@NL@%
  6593. %@NL@%
  6594.     }%@NL@%
  6595.     %@AB@%/*%@NL@%
  6596. %@AB@%     * chaser is now dead or the game is over.%@NL@%
  6597. %@AB@%     * Erase its body and terminate the thread.  Release the semaphore.%@NL@%
  6598. %@AB@%     */%@AE@%%@NL@%
  6599.     DosSemClear(&Semaphore);%@NL@%
  6600. %@NL@%
  6601.     if (GOAL.state == ALIVE) {%@NL@%
  6602.         VioWrtCellStr(Blank, 2, ME.row, ME.col, 0 );%@NL@%
  6603.     }%@NL@%
  6604.     DosExit( EXIT_THREAD ,0);%@NL@%
  6605. }%@NL@%
  6606. %@NL@%
  6607. %@AB@%/*%@NL@%
  6608. %@AB@% * InitGame()%@NL@%
  6609. %@AB@% *%@NL@%
  6610. %@AB@% * Initialize the GOAL, MOUSE and the CHASERS, launch each chase thread.%@NL@%
  6611. %@AB@% *%@NL@%
  6612. %@AB@% * Returns an error if any internal processing errors%@NL@%
  6613. %@AB@% */%@AE@%%@NL@%
  6614. int InitGame()%@NL@%
  6615. {%@NL@%
  6616.     struct _PTRLOC InitMouPos;%@NL@%
  6617.     void far chasethread();                %@AB@%/* code to control chasers */%@AE@%%@NL@%
  6618.     PBYTE Tstack;                        %@AB@%/* stack for new threads */%@AE@%%@NL@%
  6619.     unsigned chaseID;%@NL@%
  6620.     int i, rc;%@NL@%
  6621.     %@AB@%/*%@NL@%
  6622. %@AB@%     * Clear the screen.%@NL@%
  6623. %@AB@%     */%@AE@%%@NL@%
  6624.     VioScrollUp( 0, 0, -1, -1, -1, Blank, 0 );%@NL@%
  6625.     %@AB@%/*%@NL@%
  6626. %@AB@%     * Draw the prize%@NL@%
  6627. %@AB@%     */%@AE@%%@NL@%
  6628.     GOAL.row = ScreenHeight/2;%@NL@%
  6629.     GOAL.col = ScreenWidth /2;%@NL@%
  6630.     GOAL.state = ALIVE;%@NL@%
  6631.     VioWrtCellStr(Prize, 2, GOAL.row, GOAL.col, 0 );%@NL@%
  6632.     %@AB@%/*%@NL@%
  6633. %@AB@%     * Open the mouse pointer device and set it's location.%@NL@%
  6634. %@AB@%     */%@AE@%%@NL@%
  6635.     MouOpen( 0L, &Mouse );%@NL@%
  6636.     InitMouPos.row = GOAL.row;%@NL@%
  6637.     InitMouPos.col = GOAL.col;%@NL@%
  6638.     MouSetPtrPos( &InitMouPos, Mouse);%@NL@%
  6639.     MouDrawPtr(Mouse);%@NL@%
  6640.     %@AB@%/*%@NL@%
  6641. %@AB@%     * A simple minded initialization for the start of each chaser.%@NL@%
  6642. %@AB@%     * Some sort of random placement (based upon system time?) would%@NL@%
  6643. %@AB@%     * be nice.%@NL@%
  6644. %@AB@%     */%@AE@%%@NL@%
  6645.     univ[0].row = 0;  univ[0].col = 0;%@NL@%
  6646.     univ[1].row = 0;  univ[1].col = 25;%@NL@%
  6647.     univ[2].row = 0;  univ[2].col = 55;%@NL@%
  6648.     univ[3].row = 0;  univ[3].col = 79;%@NL@%
  6649.     univ[4].row = ScreenHeight;  univ[4].col = 0;%@NL@%
  6650.     univ[5].row = ScreenHeight;  univ[5].col = 25;%@NL@%
  6651.     univ[6].row = ScreenHeight;  univ[6].col = 55;%@NL@%
  6652.     univ[7].row = ScreenHeight;  univ[7].col = 79;%@NL@%
  6653.     %@AB@%/*%@NL@%
  6654. %@AB@%     * Grab the semaphore to prevent chaser from running until we are done.%@NL@%
  6655. %@AB@%     */%@AE@%%@NL@%
  6656.     DosSemRequest(&Semaphore, WAIT);%@NL@%
  6657. %@NL@%
  6658.     for( i = 0; i < CHASER; i++ ) {                %@AB@%/* for each of our threads... */%@AE@%%@NL@%
  6659.         univ[i].state = ALIVE;                        %@AB@%/* Set each one alive */%@AE@%%@NL@%
  6660.         Tstack = (PBYTE)malloc(sizeof(int) * STACKSIZE);%@NL@%
  6661.         if (Tstack == NULL ) {                        %@AB@%/* Create a stack */%@AE@%%@NL@%
  6662.             printf( "thread %d stack malloc failed\n", i );%@NL@%
  6663.             return(1);%@NL@%
  6664.         }%@NL@%
  6665.         Tstack += sizeof(int)*STACKSIZE; %@AB@%/* set stack pointer to correct end */%@AE@%%@NL@%
  6666.         *--Tstack = HIBYTE(i);%@NL@%
  6667.         *--Tstack = LOBYTE(i);                 %@AB@%/* Push the ID on as a parameter */%@AE@%%@NL@%
  6668. %@NL@%
  6669.         rc = DosCreateThread(chasethread, &chaseID, Tstack);%@NL@%
  6670.         if(rc) {%@NL@%
  6671.             printf( "create of thread %d failed, error: %d\n", i, rc );%@NL@%
  6672.             return (1);%@NL@%
  6673.         }%@NL@%
  6674.     }%@NL@%
  6675.     DosSemClear(&Semaphore);%@NL@%
  6676. %@NL@%
  6677.     return (0);%@NL@%
  6678. }%@NL@%
  6679. %@NL@%
  6680. %@AB@%/*%@NL@%
  6681. %@AB@% * CleanUp()%@NL@%
  6682. %@AB@% *%@NL@%
  6683. %@AB@% * Routine to reset the Video modes back to where they were.%@NL@%
  6684. %@AB@% * (As best as possible).%@NL@%
  6685. %@AB@% */%@AE@%%@NL@%
  6686. void CleanUp()%@NL@%
  6687. {%@NL@%
  6688.     char blank[2];%@NL@%
  6689. %@NL@%
  6690.     DosSleep(1L);             %@AB@%/* Yield the machine so attacker can clean up */%@AE@%%@NL@%
  6691.     VioSetMode( &OldVioMode, 0);%@NL@%
  6692. %@AB@%/*%@NL@%
  6693. %@AB@%    blank[0] = ' ';%@NL@%
  6694. %@AB@%    blank[1] = OldVioMode.color;%@NL@%
  6695. %@AB@%    VioScrollUp( 0, 0, -1, -1, -1, blank, 0 );%@NL@%
  6696. %@AB@%*/%@AE@%%@NL@%
  6697.     VioSetCurType( &OldCur, 0);%@NL@%
  6698.     DosExit(EXIT_PROCESS,0);              %@AB@%/* Exit and terminate all threads. */%@AE@%%@NL@%
  6699. }%@NL@%
  6700. %@NL@%
  6701. %@AB@%/*%@NL@%
  6702. %@AB@% * ParseCmdLine(ac, av)%@NL@%
  6703. %@AB@% *%@NL@%
  6704. %@AB@% * Parses the command line arguments and sets up the game accordingly%@NL@%
  6705. %@AB@% *%@NL@%
  6706. %@AB@% */%@AE@%%@NL@%
  6707. int ParseCmdLine(ac,av)%@NL@%
  6708. int ac;%@NL@%
  6709. char **av;%@NL@%
  6710. {%@NL@%
  6711.     struct _VIOMODEINFO modedata;%@NL@%
  6712.     int    VioMode;%@NL@%
  6713. %@NL@%
  6714.     Longnap = LONGNAP;%@NL@%
  6715.     Shortnap = SHORTNAP;%@NL@%
  6716.     ScreenWidth = SCREEN_WIDTH;%@NL@%
  6717.     ScreenHeight = SCREEN_HEIGHT;%@NL@%
  6718.     VioMode = 25;%@NL@%
  6719. %@NL@%
  6720.     while(--ac) {%@NL@%
  6721.         av++;%@NL@%
  6722.         switch(**av) {%@NL@%
  6723.             case 'f':%@NL@%
  6724.             case 'F':%@NL@%
  6725.                 Longnap = LONGNAP / 2;%@NL@%
  6726.                 Shortnap= SHORTNAP/ 2;%@NL@%
  6727.                 break;%@NL@%
  6728.             case 'm':%@NL@%
  6729.             case 'M':%@NL@%
  6730.                 Longnap = LONGNAP;%@NL@%
  6731.                 Shortnap= SHORTNAP;%@NL@%
  6732.                 break;%@NL@%
  6733.             case 's':%@NL@%
  6734.             case 'S':%@NL@%
  6735.                 Longnap = LONGNAP * 2;%@NL@%
  6736.                 Shortnap= SHORTNAP* 2;%@NL@%
  6737.                 break;%@NL@%
  6738.             case '4':            %@AB@%/* Assume 43 line mode was wanted */%@AE@%%@NL@%
  6739.                 ScreenHeight = 42;%@NL@%
  6740.                 ScreenWidth  = 79;%@NL@%
  6741.                 VioMode = 43;%@NL@%
  6742.                 break;%@NL@%
  6743.             case '2':%@NL@%
  6744.                 ScreenHeight = 24;%@NL@%
  6745.                 ScreenWidth  = 79;%@NL@%
  6746.                 VioMode = 25;%@NL@%
  6747.                 break;%@NL@%
  6748.             default:%@NL@%
  6749.                 return(1);%@NL@%
  6750.         }%@NL@%
  6751.     }%@NL@%
  6752. %@NL@%
  6753.     VioGetCurType(&OldCur, 0);                %@AB@%/* Save old cursor */%@AE@%%@NL@%
  6754. %@NL@%
  6755.     modedata.cb = sizeof(modedata); %@AB@%/* change mode as needed */%@AE@%%@NL@%
  6756.     VioGetMode( &modedata, 0);%@NL@%
  6757.     OldVioMode = modedata;%@NL@%
  6758.     modedata.row = VioMode;%@NL@%
  6759.     VioSetMode( &modedata, 0);%@NL@%
  6760. %@NL@%
  6761.     NewCur.yStart = 0;%@NL@%
  6762.     NewCur.cEnd = 0;%@NL@%
  6763.     NewCur.cx = 1;%@NL@%
  6764.     NewCur.attr = -1;%@NL@%
  6765. %@NL@%
  6766.     VioSetCurType( &NewCur, 0 );         %@AB@%/* make cursor go away */%@AE@%%@NL@%
  6767. %@NL@%
  6768.     return (0);%@NL@%
  6769. }%@NL@%
  6770. %@NL@%
  6771. %@NL@%
  6772. %@2@%%@AH@%CIRCLEQ.C%@AE@%%@EH@%%@NL@%
  6773. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\CIRCLEQ.C%@AE@%%@NL@%
  6774. %@NL@%
  6775. %@AB@%/*%@NL@%
  6776. %@AB@%    Circular Queue buffer implementation (which gets read by AVIO module)%@NL@%
  6777. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  6778. %@AB@%*/%@AE@%%@NL@%
  6779. %@AI@%#define %@AE@%INCL_DOSSEMAPHORES %@NL@%
  6780. <os2.h>                %@AB@%/* Need USHORT for global.h */%@AE@%%@NL@%
  6781. <string.h>                %@AB@%/* One strcpy call */%@AE@%%@NL@%
  6782. %@AI@%#include %@AE@%"global.h" %@NL@%
  6783. %@AI@%#include %@AE@%"circleq.h" %@NL@%
  6784. %@NL@%
  6785.        TIMEOUT        1000L                %@AB@%/* A second */%@AE@%%@NL@%
  6786. %@NL@%
  6787. LineInfo aliRing[QUEUESIZE];        %@AB@%/* The Circular Queue...*/%@AE@%%@NL@%
  6788. int  iHead, iTail;%@NL@%
  6789. BOOL fFirst;                        %@AB@%/* Are we just starting? */%@AE@%%@NL@%
  6790. LONG lSemMyQueue;                %@AB@%/* Queue lock */%@AE@%%@NL@%
  6791. %@NL@%
  6792. void LineCopy(Line, Line);%@NL@%
  6793. void QueFill(void);%@NL@%
  6794. %@NL@%
  6795. %@AI@%#define %@AE@%QueLock()   DosSemRequest(&lSemMyQueue, -1L) %@NL@%
  6796. %@AI@%#define %@AE@%QueUnlock() DosSemClear(&lSemMyQueue) %@NL@%
  6797. %@NL@%
  6798. %@AI@%#define %@AE@%Fix(n) (((n) >= 0) ? (n) : ((n) + QUEUESIZE)) %@NL@%
  6799. %@AI@%#define %@AE@%Circle(x)        ((x) % QUEUESIZE) %@NL@%
  6800. %@AI@%#define %@AE@%Incr(x)         (x = Circle(x + 1)) %@NL@%
  6801. %@AI@%#define %@AE@%Decr(x)                (x = (x > 0) ? (x - 1) : (QUEUESIZE - 1)) %@NL@%
  6802. %@NL@%
  6803. void QueFill(void) {%@NL@%
  6804.     int i, j;%@NL@%
  6805. %@NL@%
  6806.     for (i = 0; i < 25; i++) {%@NL@%
  6807.         aliRing[i].cch = MAXLINELEN;%@NL@%
  6808.         for (j = 0; j < MAXLINELEN; j++)%@NL@%
  6809.             aliRing[i].szText[j] = (char) (((i * j) % 10) + '0');%@NL@%
  6810.     }%@NL@%
  6811.     iHead = 0; iTail = 24;%@NL@%
  6812. }%@NL@%
  6813. %@NL@%
  6814. void QueInit(void) {%@NL@%
  6815.     int i;%@NL@%
  6816. %@NL@%
  6817.     fFirst = TRUE;%@NL@%
  6818.     QueLock();%@NL@%
  6819.     iHead = 0; iTail = 0;%@NL@%
  6820.     for (i = 0; i < QUEUESIZE; i++) aliRing[i].cch = 0;%@NL@%
  6821.     QueUnlock();%@NL@%
  6822. }%@NL@%
  6823. %@NL@%
  6824. void QueAdvance(int n) {%@NL@%
  6825.     QueLock();%@NL@%
  6826.     iHead = Circle(iHead + n);%@NL@%
  6827.     QueUnlock();%@NL@%
  6828. }%@NL@%
  6829. %@NL@%
  6830. Line QueQuery(int LineNum) { return &aliRing[Circle(iHead + LineNum)]; }%@NL@%
  6831. %@NL@%
  6832. BOOL QueInsertLine(Line pli) {%@NL@%
  6833. %@AB@%/*%@NL@%
  6834. %@AB@%    Return FALSE if we try to overwrite the head%@NL@%
  6835. %@AB@%*/%@AE@%%@NL@%
  6836.     QueLock();%@NL@%
  6837.     %@AB@%/*%@NL@%
  6838. %@AB@%        Initialize the queue%@NL@%
  6839. %@AB@%    */%@AE@%%@NL@%
  6840.     if (fFirst) fFirst = FALSE;%@NL@%
  6841.     %@AB@%/*%@NL@%
  6842. %@AB@%        Increment TAIL, act if queue full%@NL@%
  6843. %@AB@%        Overwrite if last entry was incomplete%@NL@%
  6844. %@AB@%    */%@AE@%%@NL@%
  6845.     else if (aliRing[iTail].fComplete && (Incr(iTail) == iHead)) {%@NL@%
  6846.         %@AB@%/*%@NL@%
  6847. %@AB@%            We are overflowing...%@NL@%
  6848. %@AB@%        */%@AE@%%@NL@%
  6849.         Decr(iTail);%@NL@%
  6850.         QueUnlock();%@NL@%
  6851.         return FALSE;%@NL@%
  6852.     }%@NL@%
  6853.     %@AB@%/*%@NL@%
  6854. %@AB@%        Insert the element%@NL@%
  6855. %@AB@%    */%@AE@%%@NL@%
  6856.     LineCopy(pli, &aliRing[iTail]);%@NL@%
  6857.     QueUnlock();%@NL@%
  6858.     return TRUE;%@NL@%
  6859. }%@NL@%
  6860. %@NL@%
  6861. BOOL QueCompleteLine(void) { return aliRing[iTail].fComplete; }%@NL@%
  6862. %@NL@%
  6863. void LineCopy(Line pliSrc, Line pliDst) {%@NL@%
  6864.     int i;%@NL@%
  6865. %@NL@%
  6866.     pliDst->fDrawn                = pliSrc->fDrawn;%@NL@%
  6867.     pliDst->fComplete                = pliSrc->fComplete;%@NL@%
  6868.     pliDst->cch                        = pliSrc->cch;%@NL@%
  6869.     for (i = 0; i < (int) pliSrc->cch; i++) pliDst->szText[i] = pliSrc->szText[i];%@NL@%
  6870. }%@NL@%
  6871. %@NL@%
  6872. int QueUpdateHead(int nRows, BOOL bPage, BOOL bPaging) {%@NL@%
  6873.     int i, nLines;%@NL@%
  6874. %@NL@%
  6875.     nLines = Fix(Circle(iTail - iHead));%@NL@%
  6876.     nLines = (nLines >= nRows) ? (nLines - nRows + 1) : 0;%@NL@%
  6877.     if ((nLines = Min(nLines, nRows)) > 0) {%@NL@%
  6878.         if (bPage) {%@NL@%
  6879.             if (nLines < nRows) {%@NL@%
  6880.                 QueLock();%@NL@%
  6881.                 for (i = nLines; i < nRows; i++)%@NL@%
  6882.                     aliRing[Circle(iHead + nRows + i)].cch = 0;%@NL@%
  6883.                 QueUnlock();%@NL@%
  6884.             }%@NL@%
  6885.             nLines = nRows;%@NL@%
  6886.         }%@NL@%
  6887.         else if (bPaging) nLines = 0;%@NL@%
  6888.         QueLock();%@NL@%
  6889.         iHead = Circle(iHead + nLines);%@NL@%
  6890.         QueUnlock();%@NL@%
  6891.     }%@NL@%
  6892.     return nLines;%@NL@%
  6893. }%@NL@%
  6894. %@NL@%
  6895. Line QueLastLine(void) {%@NL@%
  6896.     QueLock();%@NL@%
  6897.     aliRing[iTail].szText[aliRing[iTail].cch] = '\0';%@NL@%
  6898.     QueUnlock();%@NL@%
  6899.     return &aliRing[iTail];%@NL@%
  6900. }%@NL@%
  6901. %@NL@%
  6902. int QuePageUp(int nRows) {%@NL@%
  6903.     int i, nLines;%@NL@%
  6904. %@NL@%
  6905.     QueLock();%@NL@%
  6906.     nLines = Min((QUEUESIZE - 1) - Fix(Circle(iTail - iHead)), nRows);%@NL@%
  6907.     if (nLines) {%@NL@%
  6908.         iHead = Fix(Circle(iHead - nLines));%@NL@%
  6909.         for (i = 0; i < nLines; i++)%@NL@%
  6910.             aliRing[Circle(iHead + nRows + i)].fDrawn = FALSE;%@NL@%
  6911.     }%@NL@%
  6912.     QueUnlock();%@NL@%
  6913.     return nLines;%@NL@%
  6914. }%@NL@%
  6915. %@NL@%
  6916. %@NL@%
  6917. %@2@%%@AH@%CLIPFILE.C%@AE@%%@EH@%%@NL@%
  6918. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CLIPVIEW\CLIPFILE.C%@AE@%%@NL@%
  6919. %@NL@%
  6920. %@AB@%/*%@NL@%
  6921. %@AB@% * CLIPFILE.C -- File handling for ClipView%@NL@%
  6922. %@AB@% * Created by Microsoft Corporation, 1989%@NL@%
  6923. %@AB@% *%@NL@%
  6924. %@AB@% * This file contains one routine:  SaveClipboard(), which uses%@NL@%
  6925. %@AB@% * the OPENDLG library to put up a File...Save... dialog box.%@NL@%
  6926. %@AB@% *%@NL@%
  6927. %@AB@% * After getting a file name, it tries to save the current rendered format.%@NL@%
  6928. %@AB@% */%@AE@%%@NL@%
  6929. %@AI@%#define %@AE@%INCL_BITMAPFILEFORMAT %@NL@%
  6930. %@AI@%#define %@AE@%       INCL_DOSFILEMGR %@NL@%
  6931. %@AI@%#define %@AE@%INCL_DOSMEMMGR %@NL@%
  6932. %@AI@%#define %@AE@%INCL_GPIBITMAPS %@NL@%
  6933. %@AI@%#define %@AE@%       INCL_GPIMETAFILES %@NL@%
  6934. %@AI@%#define %@AE@%       INCL_WINCLIPBOARD %@NL@%
  6935. %@AI@%#define %@AE@%       INCL_WINERRORS %@NL@%
  6936. %@AI@%#include %@AE@%<os2.h> %@NL@%
  6937. %@AI@%#include %@AE@%<opendlg.h> %@NL@%
  6938. %@AI@%#include %@AE@%<string.h> %@NL@%
  6939. %@AI@%#include %@AE@%"clipview.h" %@NL@%
  6940. %@AB@%/*%@NL@%
  6941. %@AB@% * Globals%@NL@%
  6942. %@AB@% */%@AE@%%@NL@%
  6943. extern HAB        vhab;                        %@AB@%/* Anchor block                */%@AE@%%@NL@%
  6944. extern HWND        vhwndClient;                %@AB@%/* Main client area        */%@AE@%%@NL@%
  6945. %@AB@%/*%@NL@%
  6946. %@AB@%    Macros%@NL@%
  6947. %@AB@%*/%@AE@%%@NL@%
  6948. %@AI@%#define %@AE@%CHK(f) fSuccess = fSuccess && (f) %@NL@%
  6949. %@AI@%#define %@AE@%LOADSTRING(id, sz) WinLoadString(vhab, (HMODULE) NULL, id, MAXLEN, sz) %@NL@%
  6950. %@AB@%/*%@NL@%
  6951. %@AB@%    Private function prototypes%@NL@%
  6952. %@AB@%*/%@AE@%%@NL@%
  6953. BOOL SaveText(HFILE hf, PSZ pszText);%@NL@%
  6954. %@NL@%
  6955. BOOL SaveClipboard(HWND hwnd, USHORT usFormat) {%@NL@%
  6956. %@AB@%/*%@NL@%
  6957. %@AB@%    Save the clipboard contents in several formats.%@NL@%
  6958. %@AB@%    The "Save BITMAP" code is similar to that in the LINEFRAC sample.%@NL@%
  6959. %@AB@%*/%@AE@%%@NL@%
  6960.     BOOL                fSuccess = TRUE;     %@AB@%/* Did we succeed in saving? */%@AE@%%@NL@%
  6961.     ULONG                hItem;                     %@AB@%/* Handle from QueryClipbrdData */%@AE@%%@NL@%
  6962.     %@AB@%/*%@NL@%
  6963. %@AB@%        Variables needed for File...Save... dialog.%@NL@%
  6964. %@AB@%    */%@AE@%%@NL@%
  6965.     DLF                 dlf;                     %@AB@%/* Dialog file */%@AE@%%@NL@%
  6966.     HFILE                hf;                     %@AB@%/* Handle to output file */%@AE@%%@NL@%
  6967.     UCHAR                szExt[8];             %@AB@%/* Default extension */%@AE@%%@NL@%
  6968.     UCHAR                szInst[MAXLEN];      %@AB@%/* Instructions */%@AE@%%@NL@%
  6969.     UCHAR                szMessage[MAXLEN];   %@AB@%/* Various messages */%@AE@%%@NL@%
  6970.     UCHAR                szTitle[MAXTITLELEN];%@AB@%/* Application title */%@AE@%%@NL@%
  6971.     %@AB@%/*%@NL@%
  6972. %@AB@%        Variables needed for saving Metafiles%@NL@%
  6973. %@AB@%    */%@AE@%%@NL@%
  6974.     HMF                 hmfCopy;             %@AB@%/* Clipboard metafile copy */%@AE@%%@NL@%
  6975.     %@AB@%/*%@NL@%
  6976. %@AB@%        Variables needed for saving BITMAPs%@NL@%
  6977. %@AB@%    */%@AE@%%@NL@%
  6978.     BITMAPINFOHEADER        bmp;                %@AB@%/* Header to be queried */%@AE@%%@NL@%
  6979.     HDC                 hdcMemory;        %@AB@%/* Memory DC for the BITMAP */%@AE@%%@NL@%
  6980.     HPS                 hpsMemory;        %@AB@%/* ...and it's associated PS */%@AE@%%@NL@%
  6981.     PBITMAPFILEHEADER        pbfh;                %@AB@%/* bmp + color table */%@AE@%%@NL@%
  6982.     POINTL                ptlOrigin;        %@AB@%/* Bitmap origin */%@AE@%%@NL@%
  6983.     SEL                 selBuffer;        %@AB@%/* Selector to actual BITMAP */%@AE@%%@NL@%
  6984.     SEL                 selHeader;        %@AB@%/* Selector for the BMP header */%@AE@%%@NL@%
  6985.     SIZEL                sizl;                %@AB@%/* Used in PS creation */%@AE@%%@NL@%
  6986.     ULONG                cbBuffer;        %@AB@%/* No. of bytes in buffer */%@AE@%%@NL@%
  6987.     USHORT                cbExtra;        %@AB@%/* No. of bytes in "final" segment */%@AE@%%@NL@%
  6988.     USHORT                cbHeader;        %@AB@%/* No. of bytes in header */%@AE@%%@NL@%
  6989.     USHORT                cbWrite1;        %@AB@%/* No. of bytes to be written... */%@AE@%%@NL@%
  6990.     USHORT                cbWrite2;        %@AB@%/* ...in the two-part sel writes */%@AE@%%@NL@%
  6991.     USHORT                cbWritten;        %@AB@%/* No. of bytes actually written */%@AE@%%@NL@%
  6992.     USHORT                cSegs;                %@AB@%/* No. of segments to write */%@AE@%%@NL@%
  6993.     USHORT                i;                %@AB@%/* Which segment is being written? */%@AE@%%@NL@%
  6994.     USHORT                usHugeShift;%@NL@%
  6995.     %@AB@%/*%@NL@%
  6996. %@AB@%        Open the clipboard%@NL@%
  6997. %@AB@%    */%@AE@%%@NL@%
  6998.     if (!WinOpenClipbrd(vhab))%@NL@%
  6999.         return FALSE;%@NL@%
  7000.     %@AB@%/*%@NL@%
  7001. %@AB@%        Get the clipboard data%@NL@%
  7002. %@AB@%    */%@AE@%%@NL@%
  7003.     if (hItem = WinQueryClipbrdData(vhab, usFormat)) {%@NL@%
  7004.         %@AB@%/*%@NL@%
  7005. %@AB@%            Put up the Save... file dialog with the appropriate extensions%@NL@%
  7006. %@AB@%        */%@AE@%%@NL@%
  7007.         switch (usFormat) {%@NL@%
  7008.             case CF_TEXT:%@NL@%
  7009.             case CF_DSPTEXT:         strcpy(szExt, "\\*.TXT");  break;%@NL@%
  7010. %@NL@%
  7011.             case CF_BITMAP:%@NL@%
  7012.             case CF_DSPBITMAP:         strcpy(szExt, "\\*.BMP");  break;%@NL@%
  7013. %@NL@%
  7014.             case CF_METAFILE:%@NL@%
  7015.             case CF_DSPMETAFILE: strcpy(szExt, "\\*.MET");  break;%@NL@%
  7016. %@NL@%
  7017.             default:                 strcpy(szExt, "\\*.*");    break;%@NL@%
  7018.         }%@NL@%
  7019.         %@AB@%/*%@NL@%
  7020. %@AB@%            Put the string "Saving Format:  <format>" in the Save dialog box%@NL@%
  7021. %@AB@%        */%@AE@%%@NL@%
  7022.         GetFormatName(usFormat, szMessage);%@NL@%
  7023.         LOADSTRING(IDS_SAVETITLE, szTitle);%@NL@%
  7024.         strcat(szTitle, szMessage);%@NL@%
  7025. %@NL@%
  7026.         LOADSTRING(IDS_APPNAME, szMessage);%@NL@%
  7027.         LOADSTRING(IDS_INST, szInst);%@NL@%
  7028. %@NL@%
  7029.         SetupDLF(&dlf, DLG_SAVEDLG, &hf,%@NL@%
  7030.                  (PSZ) szExt, (PSZ) szMessage, (PSZ) szTitle, (PSZ) szInst);%@NL@%
  7031. %@NL@%
  7032.         dlf.szFileName[0] = dlf.szOpenFile[0] = '\0';%@NL@%
  7033.         %@AB@%/*%@NL@%
  7034. %@AB@%            Put up a Save file dialog, and respond appropriately to%@NL@%
  7035. %@AB@%            the return status.%@NL@%
  7036. %@AB@%        */%@AE@%%@NL@%
  7037.         switch (DlgFile(hwnd, &dlf)) {%@NL@%
  7038.             case TDF_ERRMEM:%@NL@%
  7039.             case TDF_INVALID:%@NL@%
  7040.             case TDF_NOSAVE:%@NL@%
  7041.                 fSuccess = FALSE;%@NL@%
  7042. %@NL@%
  7043.                 %@AB@%/* fall through... */%@AE@%%@NL@%
  7044.             default:%@NL@%
  7045.                 break;%@NL@%
  7046.         }%@NL@%
  7047. %@NL@%
  7048.         if (fSuccess) {%@NL@%
  7049.           switch (usFormat) {%@NL@%
  7050. %@NL@%
  7051.             case CF_TEXT:%@NL@%
  7052.             case CF_DSPTEXT:%@NL@%
  7053.                 CHK(SaveText(hf, MAKEP((SEL) hItem, 0)));%@NL@%
  7054.                 DosClose(hf);%@NL@%
  7055.                 break;%@NL@%
  7056. %@NL@%
  7057.             case CF_BITMAP:%@NL@%
  7058.             case CF_DSPBITMAP:%@NL@%
  7059.                 %@AB@%/*%@NL@%
  7060. %@AB@%                    Initialize the Memory DC and its PS%@NL@%
  7061. %@AB@%                */%@AE@%%@NL@%
  7062.                 sizl.cx = sizl.cy = 0L;%@NL@%
  7063.                 hdcMemory = DevOpenDC(vhab, OD_MEMORY, "*", 0L, NULL, NULL);%@NL@%
  7064.                 hpsMemory = GpiCreatePS(vhab, hdcMemory, &sizl,%@NL@%
  7065.                                   GPIA_ASSOC | GPIT_MICRO | PU_PELS);%@NL@%
  7066.                 %@AB@%/*%@NL@%
  7067. %@AB@%                    Draw the BITMAP into the Memory DC%@NL@%
  7068. %@AB@%                */%@AE@%%@NL@%
  7069.                 CHK(GpiSetBitmap(hpsMemory, (HBITMAP) hItem) != HBM_ERROR);%@NL@%
  7070.                 ptlOrigin.x = ptlOrigin.y = 0L;%@NL@%
  7071.                 CHK(WinDrawBitmap(hpsMemory, (HBITMAP) hItem, NULL,%@NL@%
  7072.                            &ptlOrigin, CLR_BLACK, CLR_BACKGROUND, DBM_NORMAL));%@NL@%
  7073.                 %@AB@%/*%@NL@%
  7074. %@AB@%                    Get information about the BITMAP%@NL@%
  7075. %@AB@%                */%@AE@%%@NL@%
  7076.                 CHK(GpiQueryBitmapParameters((HBITMAP) hItem, &bmp) == GPI_OK);%@NL@%
  7077.                 %@AB@%/*%@NL@%
  7078. %@AB@%                    Compute the size of the buffer, and allocate%@NL@%
  7079. %@AB@%                    Make sure that > 64K BITMAPs are handled%@NL@%
  7080. %@AB@%                    (this code is from LFFILE.C)%@NL@%
  7081. %@AB@%                */%@AE@%%@NL@%
  7082.                 cbBuffer = ( ((((ULONG)bmp.cBitCount*(ULONG) bmp.cx)+31L)/32L)%@NL@%
  7083.                                 * 4L * (ULONG) bmp.cy * (ULONG) bmp.cPlanes );%@NL@%
  7084.                 cSegs   = (USHORT) (cbBuffer >> 16);%@NL@%
  7085.                 cbExtra = (USHORT) (cbBuffer & 0xFFFFL);%@NL@%
  7086.                 CHK(!DosAllocHuge(cSegs, cbExtra, &selBuffer, 0, 0));%@NL@%
  7087.                 CHK(!DosGetHugeShift(&usHugeShift));%@NL@%
  7088.                 %@AB@%/*%@NL@%
  7089. %@AB@%                    Compute the size of the BITMAPFILEHEADER + color table...%@NL@%
  7090. %@AB@%                    ...then allocate it.%@NL@%
  7091. %@AB@%                */%@AE@%%@NL@%
  7092.                 cbHeader = (USHORT) (sizeof(BITMAPFILEHEADER)%@NL@%
  7093.                                 + (sizeof(RGB) << bmp.cBitCount));%@NL@%
  7094.                 CHK(!DosAllocSeg(cbHeader, &selHeader, SEG_NONSHARED));%@NL@%
  7095.                 pbfh = MAKEP(selHeader, 0);%@NL@%
  7096.                 %@AB@%/*%@NL@%
  7097. %@AB@%                    Copy the BITMAP information from the BITMAPINFOHEADER%@NL@%
  7098. %@AB@%                */%@AE@%%@NL@%
  7099.                 pbfh->bmp.cbFix     = 12;%@NL@%
  7100.                 pbfh->bmp.cx            = bmp.cx;%@NL@%
  7101.                 pbfh->bmp.cy            = bmp.cy;%@NL@%
  7102.                 pbfh->bmp.cPlanes   = bmp.cPlanes;%@NL@%
  7103.                 pbfh->bmp.cBitCount = bmp.cBitCount;%@NL@%
  7104.                 %@AB@%/*%@NL@%
  7105. %@AB@%                    Get the actual BITMAP bits%@NL@%
  7106. %@AB@%                */%@AE@%%@NL@%
  7107.                 CHK(GpiQueryBitmapBits(hpsMemory, 0L, (LONG) bmp.cy,%@NL@%
  7108.                        MAKEP(selBuffer, 0), (PBITMAPINFO) &(pbfh->bmp))%@NL@%
  7109.                     != GPI_ALTERROR);%@NL@%
  7110.                 %@AB@%/*%@NL@%
  7111. %@AB@%                    Set up the file header%@NL@%
  7112. %@AB@%                */%@AE@%%@NL@%
  7113.                 pbfh->usType            = BFT_BMAP;%@NL@%
  7114.                 pbfh->cbSize            = cbHeader + cbBuffer;%@NL@%
  7115.                 pbfh->xHotspot            = bmp.cx / 2;        %@AB@%/* Anywhere will do */%@AE@%%@NL@%
  7116.                 pbfh->yHotspot            = bmp.cy / 2;%@NL@%
  7117.                 pbfh->offBits            = cbHeader;%@NL@%
  7118.             %@AB@%/*%@NL@%
  7119. %@AB@%                Blast the BITMAP to a file...%@NL@%
  7120. %@AB@%            */%@AE@%%@NL@%
  7121.                 %@AB@%/*%@NL@%
  7122. %@AB@%                    ...first, the header...%@NL@%
  7123. %@AB@%                */%@AE@%%@NL@%
  7124.                 CHK(!DosWrite(hf, pbfh, cbHeader, &cbWritten));%@NL@%
  7125.                 %@AB@%/*%@NL@%
  7126. %@AB@%                    ...then, the possibly large BITMAP itself%@NL@%
  7127. %@AB@%                */%@AE@%%@NL@%
  7128.                 for (i = 0; i <= cSegs; ++i) {%@NL@%
  7129.                     if (i < cSegs) {%@NL@%
  7130.                     %@AB@%/*%@NL@%
  7131. %@AB@%                        If we a 64K segment, write it in two%@NL@%
  7132. %@AB@%                        parts.         This must be done because%@NL@%
  7133. %@AB@%                        DosWrite() can only write 64K - 1%@NL@%
  7134. %@AB@%                        characters at once.%@NL@%
  7135. %@AB@%                    */%@AE@%%@NL@%
  7136.                         cbWrite1 = cbWrite2 = 0x8000;%@NL@%
  7137.                     } else {%@NL@%
  7138.                     %@AB@%/*%@NL@%
  7139. %@AB@%                        The last segment is always small enough%@NL@%
  7140. %@AB@%                        to write entirely.%@NL@%
  7141. %@AB@%                    */%@AE@%%@NL@%
  7142.                         cbWrite1 = cbExtra; cbWrite2 = 0;%@NL@%
  7143.                     }%@NL@%
  7144. %@NL@%
  7145.                     if (cbWrite1) {%@NL@%
  7146.                         CHK(!DosWrite(hf,%@NL@%
  7147.                                 MAKEP((selBuffer + (i << usHugeShift)), 0),%@NL@%
  7148.                                 cbWrite1, &cbWritten));%@NL@%
  7149.                         if (cbWrite2) {%@NL@%
  7150.                             CHK(!DosWrite(hf,%@NL@%
  7151.                                 MAKEP((selBuffer + (i<<usHugeShift)),cbWrite1),%@NL@%
  7152.                                 cbWrite2, &cbWritten));%@NL@%
  7153.                         }%@NL@%
  7154.                     }%@NL@%
  7155.                 }%@NL@%
  7156.                 %@AB@%/*%@NL@%
  7157. %@AB@%                    Clean up%@NL@%
  7158. %@AB@%%@NL@%
  7159. %@AB@%                    Error codes are not checked here because the file has%@NL@%
  7160. %@AB@%                    already been saved.%@NL@%
  7161. %@AB@%                */%@AE@%%@NL@%
  7162.                 DosClose(hf);%@NL@%
  7163.                 GpiSetBitmap(hpsMemory, NULL);%@NL@%
  7164.                 GpiDestroyPS(hpsMemory);%@NL@%
  7165.                 DevCloseDC(hdcMemory);%@NL@%
  7166.                 break;%@NL@%
  7167. %@NL@%
  7168.             case CF_METAFILE:%@NL@%
  7169.             case CF_DSPMETAFILE:%@NL@%
  7170.                 %@AB@%/*%@NL@%
  7171. %@AB@%                    Save metafile%@NL@%
  7172. %@AB@%%@NL@%
  7173. %@AB@%                    We close and delete the file, because GpiSaveMetaFile()%@NL@%
  7174. %@AB@%                    only allows the user to create a new file.%@NL@%
  7175. %@AB@%%@NL@%
  7176. %@AB@%                    We copy the metafile because GpiSaveMetafile()%@NL@%
  7177. %@AB@%                    removes the data from the application's memory.%@NL@%
  7178. %@AB@%                */%@AE@%%@NL@%
  7179.                 DosClose(hf);%@NL@%
  7180.                 CHK(!DosDelete(dlf.szFileName, 0L));%@NL@%
  7181.                 CHK((hmfCopy = GpiCopyMetaFile((HMF) hItem)) != GPI_ERROR);%@NL@%
  7182.                 CHK(GpiSaveMetaFile(hmfCopy, dlf.szFileName) != GPI_ERROR);%@NL@%
  7183.                 break;%@NL@%
  7184. %@NL@%
  7185.             default:%@NL@%
  7186.                 %@AB@%/*%@NL@%
  7187. %@AB@%                    It may be reasonable to add support for other formats%@NL@%
  7188. %@AB@%                    here, by saving a bitmap of the current window contents.%@NL@%
  7189. %@AB@%%@NL@%
  7190. %@AB@%                    But for now, close the file and return an error message.%@NL@%
  7191. %@AB@%                */%@AE@%%@NL@%
  7192.                 DosClose(hf);%@NL@%
  7193.                 fSuccess = FALSE;%@NL@%
  7194.                 break;%@NL@%
  7195.           }%@NL@%
  7196.         }%@NL@%
  7197.     } else%@NL@%
  7198.         fSuccess = FALSE;        %@AB@%/* Couldn't query the clipboard format! */%@AE@%%@NL@%
  7199.     %@AB@%/*%@NL@%
  7200. %@AB@%        Clean up%@NL@%
  7201. %@AB@%    */%@AE@%%@NL@%
  7202.     WinCloseClipbrd(vhab);%@NL@%
  7203.     return fSuccess;%@NL@%
  7204. }%@NL@%
  7205. %@NL@%
  7206. BOOL SaveText(HFILE hf, PSZ pszText) {%@NL@%
  7207. %@AB@%/*%@NL@%
  7208. %@AB@%    Save text format%@NL@%
  7209. %@AB@%%@NL@%
  7210. %@AB@%    Count the number of characters, then write them.%@NL@%
  7211. %@AB@%*/%@AE@%%@NL@%
  7212.     PSZ     pszCounter;     %@AB@%/* Temporary to count chars in sel */%@AE@%%@NL@%
  7213.     ULONG   ulcch = 0;            %@AB@%/* The number of characters */%@AE@%%@NL@%
  7214.     USHORT  cbWritten;            %@AB@%/* No. of bytes actually written */%@AE@%%@NL@%
  7215. %@NL@%
  7216.     pszCounter = pszText;%@NL@%
  7217.     while (*pszCounter++) ulcch++;%@NL@%
  7218. %@NL@%
  7219.     return(!DosWrite(hf, pszText, (USHORT) ulcch, &cbWritten));%@NL@%
  7220. }%@NL@%
  7221. %@NL@%
  7222. %@NL@%
  7223. %@2@%%@AH@%CLIPVIEW.C%@AE@%%@EH@%%@NL@%
  7224. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CLIPVIEW\CLIPVIEW.C%@AE@%%@NL@%
  7225. %@NL@%
  7226. %@AB@%/*%@NL@%
  7227. %@AB@% * CLIPVIEW.C -- Clipboard Viewing application%@NL@%
  7228. %@AB@% * Created by Microsoft Corporation, 1989%@NL@%
  7229. %@AB@% *%@NL@%
  7230. %@AB@% * This program registers itself as the clipboard viewer, if no clipboard%@NL@%
  7231. %@AB@% * viewer exists.  Then, it intercepts WM_DRAWCLIPBOARD messages.%@NL@%
  7232. %@AB@% *%@NL@%
  7233. %@AB@% * This file contains the routines which handle the client/frame windows,%@NL@%
  7234. %@AB@% * the dialog routines, and the clipboard rendering code.%@NL@%
  7235. %@AB@% */%@AE@%%@NL@%
  7236. %@AI@%#define %@AE@%       INCL_GPIBITMAPS %@NL@%
  7237. %@AI@%#define %@AE@%       INCL_GPIMETAFILES %@NL@%
  7238. %@AI@%#define %@AE@%INCL_WINATOM %@NL@%
  7239. %@AI@%#define %@AE@%       INCL_WINCLIPBOARD %@NL@%
  7240. %@AI@%#define %@AE@%       INCL_WINFRAMEMGR %@NL@%
  7241. %@AI@%#define %@AE@%       INCL_WINLISTBOXES %@NL@%
  7242. %@AI@%#define %@AE@%       INCL_WINMENUS %@NL@%
  7243. %@AI@%#define %@AE@%       INCL_WINMLE %@NL@%
  7244. %@AI@%#define %@AE@%       INCL_WINSCROLLBARS %@NL@%
  7245. %@AI@%#define %@AE@%       INCL_WINSYS %@NL@%
  7246. %@AI@%#define %@AE@%       INCL_WINWINDOWMGR %@NL@%
  7247. %@AI@%#include %@AE@%<os2.h> %@NL@%
  7248. %@AI@%#include %@AE@%<string.h> %@NL@%
  7249. %@AI@%#include %@AE@%"clipview.h" %@NL@%
  7250. %@AB@%/*%@NL@%
  7251. %@AB@% * Globals%@NL@%
  7252. %@AB@% */%@AE@%%@NL@%
  7253. BITMAPINFOHEADER vbmp;                        // Dimensions of current BITMAP%@NL@%
  7254. BOOL        vfUpdate        = FALSE;        // Are we updating the clipboard?%@NL@%
  7255. BOOL        vfViewBitmap        = FALSE;        // Are we currently viewing a...?%@NL@%
  7256. HAB        vhab;                                // Anchor block%@NL@%
  7257. HDC        vhdcMemory;                        // A memory DC for BitBlt-ing images%@NL@%
  7258. HDC        vhdcWindow        = NULL;         // Client window DC%@NL@%
  7259. HMQ        vhmqClip;                        // Message queue%@NL@%
  7260. HPS        vhpsMemory;                        // A PS associated with vhdcMemory%@NL@%
  7261. HWND        vhwndClient;                        // Main client area%@NL@%
  7262. HWND        vhwndClipFrame = NULL;                // Main frame window%@NL@%
  7263. HWND        vhwndHSB        = NULL;         // Horizontal scroll bar%@NL@%
  7264. HWND        vhwndMLE        = NULL;         // Handle to the MLE%@NL@%
  7265. HWND        vhwndTitlebar        = NULL;         // Title-bar handle%@NL@%
  7266. HWND        vhwndVSB        = NULL;         // Vertical scroll bar%@NL@%
  7267. SHORT        vcMaxHSB;                        // Maximum scroll range for HSB%@NL@%
  7268. SHORT        vcMaxVSB;                        // ...and for the VSB%@NL@%
  7269. SHORT        vcUpdate        = -1;                // Counter for scroll bar updating%@NL@%
  7270. USHORT        vausFormats[MAXFORMATS];        // All available formats%@NL@%
  7271. USHORT        vcFmts;                         // How many formats?%@NL@%
  7272. USHORT        vusFormat;                        // What is the current format?%@NL@%
  7273. USHORT        vfsFmtInfo;                        // Clipboard Format Information%@NL@%
  7274. %@AB@%/*%@NL@%
  7275. %@AB@%    Macros%@NL@%
  7276. %@AB@%*/%@AE@%%@NL@%
  7277. %@AI@%#define %@AE@%LOADSTRING(id, sz) WinLoadString(vhab, (HMODULE) NULL, id, MAXLEN, sz) %@NL@%
  7278. %@AI@%#define %@AE@%MESSAGE(sz) WinMessageBox(HWND_DESKTOP, vhwndClient, sz, NULL, 0, \ %@NL@%
  7279.                         MB_OK | MB_ICONASTERISK | MB_SYSTEMMODAL);%@NL@%
  7280. %@AB@%/*%@NL@%
  7281. %@AB@% * Main routine...initializes window and message queue%@NL@%
  7282. %@AB@% */%@AE@%%@NL@%
  7283. int cdecl main( ) {%@NL@%
  7284.     QMSG    qmsg;                    %@AB@%/* Message queue */%@AE@%%@NL@%
  7285.     ULONG   ctldata;                    %@AB@%/* FCF_ flags */%@AE@%%@NL@%
  7286.     BOOL    fViewer;                    %@AB@%/* Does a viewer already exist? */%@AE@%%@NL@%
  7287.     UCHAR   szAlready[MAXLEN];            %@AB@%/* Already extant... message */%@AE@%%@NL@%
  7288.     UCHAR   szClassName[MAXLEN];    %@AB@%/* New class name */%@AE@%%@NL@%
  7289.     %@AB@%/*%@NL@%
  7290. %@AB@%        Start up our PM application%@NL@%
  7291. %@AB@%    */%@AE@%%@NL@%
  7292.     vhab = WinInitialize(0);%@NL@%
  7293.     vhmqClip = WinCreateMsgQueue(vhab, 0);%@NL@%
  7294.     %@AB@%/*%@NL@%
  7295. %@AB@%        We create the client window first to try to avoid%@NL@%
  7296. %@AB@%        synchronization problems.%@NL@%
  7297. %@AB@%    */%@AE@%%@NL@%
  7298.     LOADSTRING(IDS_CLIPCLASS, szClassName);%@NL@%
  7299.     if (!WinRegisterClass( vhab, (PCH)szClassName, (PFNWP)ClipWndProc,%@NL@%
  7300.                 CS_SIZEREDRAW, 0))%@NL@%
  7301.         return( 0 );%@NL@%
  7302.     %@AB@%/*%@NL@%
  7303. %@AB@%        Create the window (hidden)%@NL@%
  7304. %@AB@%    */%@AE@%%@NL@%
  7305.     ctldata = (FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL)%@NL@%
  7306.                             & ~(FCF_ACCELTABLE);%@NL@%
  7307. %@NL@%
  7308.     vhwndClipFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE, &ctldata,%@NL@%
  7309.                                          szClassName, "",%@NL@%
  7310.                                          WS_VISIBLE, (HMODULE) NULL, ID_RESOURCE,%@NL@%
  7311.                                          (PHWND) &vhwndClient );%@NL@%
  7312.     %@AB@%/*%@NL@%
  7313. %@AB@%        If there is no other clipboard viewer...%@NL@%
  7314. %@AB@%    */%@AE@%%@NL@%
  7315.     if (fViewer = !WinQueryClipbrdViewer(vhab, FALSE)) {%@NL@%
  7316.         %@AB@%/*%@NL@%
  7317. %@AB@%            ...we'll be the viewer.  Show the clipboard window.%@NL@%
  7318. %@AB@%        */%@AE@%%@NL@%
  7319.         WinSetClipbrdViewer(vhab, vhwndClient);%@NL@%
  7320.         %@AB@%/*%@NL@%
  7321. %@AB@%            Poll messages from event queue%@NL@%
  7322. %@AB@%        */%@AE@%%@NL@%
  7323.         while( WinGetMsg( vhab, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )%@NL@%
  7324.             WinDispatchMsg( vhab, (PQMSG)&qmsg );%@NL@%
  7325.         %@AB@%/*%@NL@%
  7326. %@AB@%            Stop being the clipboard viewer.%@NL@%
  7327. %@AB@%        */%@AE@%%@NL@%
  7328.         if (vhwndMLE)%@NL@%
  7329.             WinDestroyWindow(vhwndMLE);%@NL@%
  7330.         WinSetClipbrdViewer(vhab, NULL);%@NL@%
  7331.     } else {%@NL@%
  7332.         %@AB@%/*%@NL@%
  7333. %@AB@%            ...otherwise, notify the user, then terminate.%@NL@%
  7334. %@AB@%        */%@AE@%%@NL@%
  7335.         LOADSTRING(IDS_ALREADY, szAlready);%@NL@%
  7336.         MESSAGE(szAlready);%@NL@%
  7337.     }%@NL@%
  7338.     %@AB@%/*%@NL@%
  7339. %@AB@%        Clean up%@NL@%
  7340. %@AB@%    */%@AE@%%@NL@%
  7341.     WinDestroyWindow( vhwndClipFrame );%@NL@%
  7342.     WinDestroyMsgQueue( vhmqClip );%@NL@%
  7343.     WinTerminate( vhab );%@NL@%
  7344. %@NL@%
  7345.     return !fViewer;%@NL@%
  7346. }%@NL@%
  7347. %@NL@%
  7348. MRESULT CALLBACK ClipWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  7349. %@AB@%/*%@NL@%
  7350. %@AB@%%@NL@%
  7351. %@AB@% * This routine processes WM_COMMAND, WM_CREATE, WM_DRAWCLIPBOARD, WM_PAINT.%@NL@%
  7352. %@AB@% * Everything else is passed to the Default Window Procedure.%@NL@%
  7353. %@AB@% */%@AE@%%@NL@%
  7354.     HPS                hpsWindow;%@NL@%
  7355.     RECTL        rcl;%@NL@%
  7356.     SWP         swp;%@NL@%
  7357.     SIZEL        sizl;%@NL@%
  7358.     UCHAR        szMessage[MAXLEN];%@NL@%
  7359. %@NL@%
  7360.     switch (msg) {%@NL@%
  7361. %@NL@%
  7362.         case WM_CREATE:%@NL@%
  7363.             %@AB@%/*%@NL@%
  7364. %@AB@%                Create a memory DC/PS to BitBlt BITMAPs around.%@NL@%
  7365. %@AB@%            */%@AE@%%@NL@%
  7366.             sizl.cx = sizl.cy = 0L;%@NL@%
  7367.             vhdcMemory = DevOpenDC(vhab, OD_MEMORY, "*", 0L, NULL, NULL);%@NL@%
  7368.             vhpsMemory = GpiCreatePS(vhab, vhdcMemory, &sizl,%@NL@%
  7369.                 GPIA_ASSOC | GPIF_DEFAULT | GPIT_MICRO | PU_PELS);%@NL@%
  7370.             break;%@NL@%
  7371. %@NL@%
  7372.         case WM_COMMAND:%@NL@%
  7373.             switch (COMMANDMSG(&msg)->cmd) {%@NL@%
  7374.                 %@AB@%/*%@NL@%
  7375. %@AB@%                    About... dialog box%@NL@%
  7376. %@AB@%                */%@AE@%%@NL@%
  7377.                 case IDM_ABOUT:%@NL@%
  7378.                     WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc,%@NL@%
  7379.                               (HMODULE) NULL, IDD_ABOUT, NULL);%@NL@%
  7380.                     return 0;%@NL@%
  7381.                 %@AB@%/*%@NL@%
  7382. %@AB@%                    Render... dialog box%@NL@%
  7383. %@AB@%                */%@AE@%%@NL@%
  7384.                 case IDM_RENDER:%@NL@%
  7385.                     WinDlgBox(HWND_DESKTOP, hwnd, RenderDlgProc,%@NL@%
  7386.                               (HMODULE) NULL, IDD_RENDER, NULL);%@NL@%
  7387.                     return 0;%@NL@%
  7388.                 %@AB@%/*%@NL@%
  7389. %@AB@%                    Save... dialog box%@NL@%
  7390. %@AB@%                */%@AE@%%@NL@%
  7391.                 case IDM_SAVE:%@NL@%
  7392.                     if (!SaveClipboard(hwnd, vusFormat)) {%@NL@%
  7393.                         LOADSTRING(IDS_NOTSAVED, szMessage);%@NL@%
  7394.                         MESSAGE(szMessage);%@NL@%
  7395.                     }%@NL@%
  7396.                     return 0;%@NL@%
  7397. %@NL@%
  7398.                 default: break;%@NL@%
  7399.             }%@NL@%
  7400.             break;%@NL@%
  7401. %@NL@%
  7402.         case WM_ERASEBACKGROUND:%@NL@%
  7403.             return (MRESULT) TRUE;%@NL@%
  7404.             break;%@NL@%
  7405. %@NL@%
  7406.         case WM_PAINT:%@NL@%
  7407.             %@AB@%/* Open the presentation space */%@AE@%%@NL@%
  7408.             hpsWindow = WinBeginPaint(hwnd, NULL, &rcl);%@NL@%
  7409. %@NL@%
  7410.             %@AB@%/* Fill in the background */%@AE@%%@NL@%
  7411.             WinFillRect(hpsWindow, &rcl, CLR_BACKGROUND);%@NL@%
  7412. %@NL@%
  7413.             %@AB@%/* Paint in the clipboard */%@AE@%%@NL@%
  7414.             UpdateScreen(hwnd, vusFormat);%@NL@%
  7415. %@NL@%
  7416.             %@AB@%/* Finish painting */%@AE@%%@NL@%
  7417.             WinEndPaint(hpsWindow);%@NL@%
  7418.             break;%@NL@%
  7419. %@NL@%
  7420.         case WM_DRAWCLIPBOARD:%@NL@%
  7421.             %@AB@%/* Update the clipboard contents */%@AE@%%@NL@%
  7422.             GetAllFormats();%@NL@%
  7423.             vfUpdate = TRUE;%@NL@%
  7424.             WinPostMsg(hwnd, WM_PAINT, 0L, 0L);%@NL@%
  7425.             break;%@NL@%
  7426. %@NL@%
  7427.         case WM_HSCROLL:%@NL@%
  7428.             if (vfViewBitmap) {%@NL@%
  7429.                 %@AB@%/*%@NL@%
  7430. %@AB@%                    Handle the appropriate scrolling messages%@NL@%
  7431. %@AB@%                */%@AE@%%@NL@%
  7432.                 DoScrolling(hwnd, TRUE, HIUSHORT(mp2));%@NL@%
  7433.             } else%@NL@%
  7434.                 %@AB@%/*%@NL@%
  7435. %@AB@%                    If an ownerdraw format, let the owner handle it.%@NL@%
  7436. %@AB@%                */%@AE@%%@NL@%
  7437.                 SendOwnerMsg(WM_HSCROLLCLIPBOARD, (MPARAM) hwnd, mp2);%@NL@%
  7438.             break;%@NL@%
  7439. %@NL@%
  7440.         case WM_VSCROLL:%@NL@%
  7441.             if (vfViewBitmap) {%@NL@%
  7442.                 %@AB@%/*%@NL@%
  7443. %@AB@%                    Handle the appropriate scrolling messages%@NL@%
  7444. %@AB@%                */%@AE@%%@NL@%
  7445.                 DoScrolling(hwnd, FALSE, HIUSHORT(mp2));%@NL@%
  7446.             } else%@NL@%
  7447.                 %@AB@%/*%@NL@%
  7448. %@AB@%                    If an ownerdraw format, let the owner handle it.%@NL@%
  7449. %@AB@%                */%@AE@%%@NL@%
  7450.                 SendOwnerMsg(WM_VSCROLLCLIPBOARD, (MPARAM) hwnd, mp2);%@NL@%
  7451.             break;%@NL@%
  7452. %@NL@%
  7453.         case WM_SIZE:%@NL@%
  7454.             %@AB@%/*%@NL@%
  7455. %@AB@%                If the MLE is processing a text selector,%@NL@%
  7456. %@AB@%                tell it to resize itself.  If we have%@NL@%
  7457. %@AB@%                owner-draw data, tell the clipboard owner.%@NL@%
  7458. %@AB@%                If we have a BITMAP, readjust the scroll%@NL@%
  7459. %@AB@%                bar ranges.%@NL@%
  7460. %@AB@%            */%@AE@%%@NL@%
  7461.             if (vhwndMLE) {%@NL@%
  7462.                 WinQueryWindowPos(vhwndMLE, &swp);%@NL@%
  7463.                 swp.cx = SHORT1FROMMP(mp2);%@NL@%
  7464.                 swp.cy = SHORT2FROMMP(mp2);%@NL@%
  7465.                 WinSetMultWindowPos(vhab, &swp, 1);%@NL@%
  7466.             } else if (vfViewBitmap) {%@NL@%
  7467.                 WinQueryWindowPos(hwnd, &swp);%@NL@%
  7468.                 if ((vcMaxHSB = vbmp.cx - swp.cx) < 0)%@NL@%
  7469.                     vcMaxHSB = 0;%@NL@%
  7470.                 if ((vcMaxVSB = vbmp.cy - swp.cy) < 0)%@NL@%
  7471.                     vcMaxVSB = 0;%@NL@%
  7472.                 WinSendMsg(vhwndHSB, SBM_SETSCROLLBAR,%@NL@%
  7473.                     0L, MPFROM2SHORT(0, vcMaxHSB));%@NL@%
  7474.                 WinSendMsg(vhwndVSB, SBM_SETSCROLLBAR,%@NL@%
  7475.                     MPFROMSHORT(vcMaxVSB),%@NL@%
  7476.                     MPFROM2SHORT(0, vcMaxVSB));%@NL@%
  7477.             } else {%@NL@%
  7478.                 rcl.xLeft = rcl.yBottom = 0L;%@NL@%
  7479.                 rcl.xLeft = (LONG) SHORT1FROMMP(mp2) - 1;%@NL@%
  7480.                 rcl.yTop  = (LONG) SHORT2FROMMP(mp2) - 1;%@NL@%
  7481.                 SendOwnerMsg(WM_SIZECLIPBOARD, (MPARAM) hwnd, &rcl);%@NL@%
  7482.             }%@NL@%
  7483.             break;%@NL@%
  7484. %@NL@%
  7485.         default:%@NL@%
  7486.             return WinDefWindowProc(hwnd, msg, mp1, mp2);%@NL@%
  7487.             break;%@NL@%
  7488.     }%@NL@%
  7489.     return 0L;%@NL@%
  7490. }%@NL@%
  7491. %@NL@%
  7492. MRESULT CALLBACK RenderDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  7493. {%@NL@%
  7494. %@AB@%/*%@NL@%
  7495. %@AB@%    Render... dialog procedure%@NL@%
  7496. %@AB@%*/%@AE@%%@NL@%
  7497.     HWND        hwndListbox;                %@AB@%/* Listbox of possible formats */%@AE@%%@NL@%
  7498.     UCHAR        szFmtName[MAXLEN];        %@AB@%/* Format name */%@AE@%%@NL@%
  7499.     UCHAR        szMessage[MAXLEN];%@NL@%
  7500.     USHORT        i;%@NL@%
  7501.     USHORT        usFormat;                %@AB@%/* Format to render */%@AE@%%@NL@%
  7502.     MRESULT        mrItem;                 %@AB@%/* Which listbox item selected? */%@AE@%%@NL@%
  7503. %@NL@%
  7504.     switch(msg) {%@NL@%
  7505. %@NL@%
  7506.         case WM_INITDLG:%@NL@%
  7507.             %@AB@%/*%@NL@%
  7508. %@AB@%                Put all the possible formats into the listbox, and%@NL@%
  7509. %@AB@%                select the first item by default.%@NL@%
  7510. %@AB@%            */%@AE@%%@NL@%
  7511.             hwndListbox = WinWindowFromID(hwndDlg, IDL_RENDER);%@NL@%
  7512.             WinSendMsg(hwndListbox, LM_DELETEALL, 0L, 0L);%@NL@%
  7513.             for (i = 0; i < vcFmts; i++) {%@NL@%
  7514.                 GetFormatName(vausFormats[i], szFmtName);%@NL@%
  7515.                 WinSendMsg(hwndListbox, LM_INSERTITEM,%@NL@%
  7516.                         MPFROMSHORT(LIT_END), MPFROMP((PVOID) szFmtName));%@NL@%
  7517.             }%@NL@%
  7518.             WinSendMsg(hwndListbox, LM_SELECTITEM, 0L, MPFROMSHORT(TRUE));%@NL@%
  7519.             break;%@NL@%
  7520. %@NL@%
  7521.         case WM_CONTROL:%@NL@%
  7522.             %@AB@%/*%@NL@%
  7523. %@AB@%                If the user makes a selection, quit!%@NL@%
  7524. %@AB@%            */%@AE@%%@NL@%
  7525.             if ((SHORT1FROMMP(mp1) == IDL_RENDER)%@NL@%
  7526.                 && (SHORT2FROMMP(mp1) == LN_ENTER))%@NL@%
  7527.                     WinPostMsg(hwndDlg, WM_COMMAND, MPFROMSHORT(DID_OK), 0L);%@NL@%
  7528.             break;%@NL@%
  7529. %@NL@%
  7530.         case WM_COMMAND:%@NL@%
  7531.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  7532.                 case DID_OK:%@NL@%
  7533.                     %@AB@%/*%@NL@%
  7534. %@AB@%                        Since the user chose a selection, try to render it.%@NL@%
  7535. %@AB@%                    */%@AE@%%@NL@%
  7536.                     hwndListbox = WinWindowFromID(hwndDlg, IDL_RENDER);%@NL@%
  7537.                     mrItem = WinSendMsg(hwndListbox, LM_QUERYSELECTION, 0L, 0L);%@NL@%
  7538.                     if (mrItem != (MRESULT) LIT_NONE) {%@NL@%
  7539.                         usFormat = vausFormats[SHORT1FROMMR(mrItem)];%@NL@%
  7540.                         if (usFormat != vusFormat) {%@NL@%
  7541.                             %@AB@%/*%@NL@%
  7542. %@AB@%                                If the clipboard format is not rendered,%@NL@%
  7543. %@AB@%                                tell the user.%@NL@%
  7544. %@AB@%                            */%@AE@%%@NL@%
  7545.                             vfUpdate = TRUE;%@NL@%
  7546.                             if (!UpdateScreen(vhwndClient, usFormat)) {%@NL@%
  7547.                                 LOADSTRING(IDS_NODISPLAY, szMessage);%@NL@%
  7548.                                 MESSAGE(szMessage);%@NL@%
  7549.                             }%@NL@%
  7550.                         }%@NL@%
  7551.                     }%@NL@%
  7552. %@NL@%
  7553.                     %@AB@%/* fall through */%@AE@%%@NL@%
  7554. %@NL@%
  7555.                 case DID_CANCEL:%@NL@%
  7556.                     WinDismissDlg(hwndDlg, TRUE);%@NL@%
  7557. %@NL@%
  7558.                 default: break;%@NL@%
  7559.             }%@NL@%
  7560.         default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);%@NL@%
  7561.     }%@NL@%
  7562.     return FALSE;%@NL@%
  7563. }%@NL@%
  7564. %@NL@%
  7565. MRESULT CALLBACK AboutDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  7566. {%@NL@%
  7567. %@AB@%/*%@NL@%
  7568. %@AB@%    About... dialog procedure%@NL@%
  7569. %@AB@%*/%@AE@%%@NL@%
  7570.     switch(msg) {%@NL@%
  7571.         case WM_COMMAND:%@NL@%
  7572.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  7573.                 case DID_OK: WinDismissDlg(hwndDlg, TRUE);%@NL@%
  7574.                 default: break;%@NL@%
  7575.             }%@NL@%
  7576.         default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);%@NL@%
  7577.     }%@NL@%
  7578.     return FALSE;%@NL@%
  7579. }%@NL@%
  7580. %@NL@%
  7581. VOID ReadSelector(HWND hwndMLE, PSZ pszText) {%@NL@%
  7582. %@AB@%/*%@NL@%
  7583. %@AB@%    Compute the length of the text selector, in bytes.%@NL@%
  7584. %@AB@%    Allocate space, and copy the text selector into an MLE.%@NL@%
  7585. %@AB@%*/%@AE@%%@NL@%
  7586.     IPT ipt;%@NL@%
  7587.     ULONG ulcch = 0;%@NL@%
  7588.     PSZ        pszCounter;%@NL@%
  7589. %@NL@%
  7590.     pszCounter = pszText;%@NL@%
  7591.     while (*pszCounter++) ulcch++;%@NL@%
  7592.     WinSendMsg(hwndMLE, MLM_FORMAT, MPFROMSHORT(MLFIE_CFTEXT), 0L);%@NL@%
  7593.     WinSendMsg(hwndMLE, MLM_SETIMPORTEXPORT, pszText, (MPARAM) ulcch);%@NL@%
  7594.     WinSendMsg(hwndMLE, MLM_IMPORT, &ipt, (MPARAM) ulcch);%@NL@%
  7595. }%@NL@%
  7596. %@NL@%
  7597. VOID FixFrame(VOID) {%@NL@%
  7598. %@AB@%/*%@NL@%
  7599. %@AB@%    This routine tells the frame to update the scroll bars.%@NL@%
  7600. %@AB@%%@NL@%
  7601. %@AB@%    First, make it so that the scroll bars cannot update themselves.%@NL@%
  7602. %@AB@%    Let the frame update the controls.  Then, re-enable the scroll bars.%@NL@%
  7603. %@AB@%*/%@AE@%%@NL@%
  7604.     if (!(vcUpdate--)) {%@NL@%
  7605.         WinEnableWindowUpdate(vhwndHSB, FALSE);%@NL@%
  7606.         WinEnableWindowUpdate(vhwndVSB, FALSE);%@NL@%
  7607.     }%@NL@%
  7608. %@NL@%
  7609.     WinSendMsg(vhwndClipFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_HORZSCROLL), 0L);%@NL@%
  7610.     WinSendMsg(vhwndClipFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_VERTSCROLL), 0L);%@NL@%
  7611. %@NL@%
  7612.     if (!(++vcUpdate)) {%@NL@%
  7613.         WinEnableWindowUpdate(vhwndHSB, TRUE);%@NL@%
  7614.         WinEnableWindowUpdate(vhwndVSB, TRUE);%@NL@%
  7615.     }%@NL@%
  7616. }%@NL@%
  7617. %@NL@%
  7618. VOID NeedScrollBars(BOOL fNeed) {%@NL@%
  7619. %@AB@%/*%@NL@%
  7620. %@AB@%    This routine hides changes the scroll bar state to correspond with%@NL@%
  7621. %@AB@%    fNeed, showing or hiding them as necessary.%@NL@%
  7622. %@AB@%*/%@AE@%%@NL@%
  7623.     static BOOL fNeeded = TRUE;                %@AB@%/* The last scroll bar state */%@AE@%%@NL@%
  7624. %@NL@%
  7625.     %@AB@%/*%@NL@%
  7626. %@AB@%        Get the scroll bar handles, if we haven't already.%@NL@%
  7627. %@AB@%    */%@AE@%%@NL@%
  7628.     if (!vhwndHSB) {%@NL@%
  7629.         vhwndHSB = WinWindowFromID(vhwndClipFrame, FID_HORZSCROLL);%@NL@%
  7630.         vhwndVSB = WinWindowFromID(vhwndClipFrame, FID_VERTSCROLL);%@NL@%
  7631.     }%@NL@%
  7632.     %@AB@%/*%@NL@%
  7633. %@AB@%        Case 1:  We need scroll bars, so enable them.%@NL@%
  7634. %@AB@%    */%@AE@%%@NL@%
  7635.     if (fNeed) {%@NL@%
  7636.         if (!fNeeded) {%@NL@%
  7637.             WinSetParent(vhwndHSB, vhwndClipFrame, TRUE);%@NL@%
  7638.             WinSetParent(vhwndVSB, vhwndClipFrame, TRUE);%@NL@%
  7639.             FixFrame();%@NL@%
  7640.         }%@NL@%
  7641.     %@AB@%/*%@NL@%
  7642. %@AB@%        Case 2:  We don't need scroll bars, so hide them.%@NL@%
  7643. %@AB@%    */%@AE@%%@NL@%
  7644.     } else {%@NL@%
  7645.         if (fNeeded) {%@NL@%
  7646.             WinSetParent(vhwndHSB, HWND_OBJECT, TRUE);%@NL@%
  7647.             WinSetParent(vhwndVSB, HWND_OBJECT, TRUE);%@NL@%
  7648.             FixFrame();%@NL@%
  7649.         }%@NL@%
  7650.     }%@NL@%
  7651.     %@AB@%/*%@NL@%
  7652. %@AB@%        Save state for next invocation%@NL@%
  7653. %@AB@%    */%@AE@%%@NL@%
  7654.     fNeeded = fNeed;%@NL@%
  7655. }%@NL@%
  7656. %@NL@%
  7657. %@AB@%/*%@NL@%
  7658. %@AB@%    RenderFormat()%@NL@%
  7659. %@AB@%%@NL@%
  7660. %@AB@%    Input:                Clipboard format to render, and handle to client area%@NL@%
  7661. %@AB@%    Side effects:        Renders the image in the client area%@NL@%
  7662. %@AB@%*/%@AE@%%@NL@%
  7663. BOOL RenderFormat(HWND hwnd, USHORT usFormat) {%@NL@%
  7664.     BOOL    fRendered = TRUE;%@NL@%
  7665.     HMF            hmfCopy;%@NL@%
  7666.     HPS     hpsWindow;%@NL@%
  7667.     LONG    alOptions[8];%@NL@%
  7668.     RECTL   rclWindow;%@NL@%
  7669.     SIZEL   sizl;%@NL@%
  7670.     SWP            swpWindow;%@NL@%
  7671.     ULONG   hItem;%@NL@%
  7672.     POINTL  aptl[3];%@NL@%
  7673.     %@AB@%/*%@NL@%
  7674. %@AB@%        Open the clipboard%@NL@%
  7675. %@AB@%    */%@AE@%%@NL@%
  7676.     if (!WinOpenClipbrd(vhab))%@NL@%
  7677.         return FALSE;%@NL@%
  7678.     %@AB@%/*%@NL@%
  7679. %@AB@%        Open up the window DC and PS%@NL@%
  7680. %@AB@%    */%@AE@%%@NL@%
  7681.     if (!vhdcWindow)%@NL@%
  7682.         vhdcWindow = WinOpenWindowDC(hwnd);%@NL@%
  7683. %@NL@%
  7684.     sizl.cx = sizl.cy = 0L;%@NL@%
  7685.     hpsWindow = GpiCreatePS(vhab, vhdcWindow, &sizl, GPIA_ASSOC | PU_ARBITRARY);%@NL@%
  7686.     %@AB@%/*%@NL@%
  7687. %@AB@%        Enable the scroll bars, if necessary.  This affects the size%@NL@%
  7688. %@AB@%        of the client area.%@NL@%
  7689. %@AB@%    */%@AE@%%@NL@%
  7690.     if (vfUpdate)%@NL@%
  7691.         NeedScrollBars( (vfViewBitmap =%@NL@%
  7692.                 (usFormat == CF_BITMAP) || (usFormat == CF_DSPBITMAP)) );%@NL@%
  7693. %@NL@%
  7694.     WinQueryWindowRect(hwnd, &rclWindow);%@NL@%
  7695.     %@AB@%/*%@NL@%
  7696. %@AB@%        Get the clipboard data%@NL@%
  7697. %@AB@%    */%@AE@%%@NL@%
  7698.     WinQueryClipbrdFmtInfo(vhab, usFormat, &vfsFmtInfo);%@NL@%
  7699.     if (!(hItem = WinQueryClipbrdData(vhab, usFormat))) {%@NL@%
  7700.         fRendered = FALSE;%@NL@%
  7701.     } else {%@NL@%
  7702.       %@AB@%/*%@NL@%
  7703. %@AB@%        Display the new format, as appropriate.%@NL@%
  7704. %@AB@%      */%@AE@%%@NL@%
  7705.       switch (usFormat) {%@NL@%
  7706.         case CF_TEXT:%@NL@%
  7707.         case CF_DSPTEXT:%@NL@%
  7708.             if (vfUpdate) {%@NL@%
  7709.                 %@AB@%/*%@NL@%
  7710. %@AB@%                    Create a new MLE and read the text into it.%@NL@%
  7711. %@AB@%                */%@AE@%%@NL@%
  7712.                 vhwndMLE = WinCreateWindow(hwnd, WC_MLE, "",%@NL@%
  7713.                     WS_VISIBLE | MLS_READONLY | MLS_HSCROLL | MLS_VSCROLL,%@NL@%
  7714.                     0, 0,%@NL@%
  7715.                     (SHORT) rclWindow.xRight, (SHORT) rclWindow.yTop,%@NL@%
  7716.                     hwnd, HWND_TOP, 0, NULL, NULL);%@NL@%
  7717. %@NL@%
  7718.                 ReadSelector(vhwndMLE, MAKEP((SEL) hItem, 0));%@NL@%
  7719.             }%@NL@%
  7720.             break;%@NL@%
  7721. %@NL@%
  7722.         case CF_BITMAP:%@NL@%
  7723.         case CF_DSPBITMAP:%@NL@%
  7724.             if (vfUpdate) {%@NL@%
  7725.                 %@AB@%/*%@NL@%
  7726. %@AB@%                    Get the BITMAP dimensions, for scroll bar processing%@NL@%
  7727. %@AB@%                */%@AE@%%@NL@%
  7728.                 if (GpiQueryBitmapParameters((HBITMAP) hItem, &vbmp)%@NL@%
  7729.                         != GPI_OK) {%@NL@%
  7730.                     return FALSE;%@NL@%
  7731.                 }%@NL@%
  7732.                 %@AB@%/*%@NL@%
  7733. %@AB@%                    Set the scroll bar ranges from 0 to vbmp.max - client.max%@NL@%
  7734. %@AB@%                */%@AE@%%@NL@%
  7735.                 WinQueryWindowPos(hwnd, &swpWindow);%@NL@%
  7736. %@NL@%
  7737.                 if ((vcMaxHSB = vbmp.cx - swpWindow.cx) < 0)%@NL@%
  7738.                     vcMaxHSB = 0;%@NL@%
  7739.                 if ((vcMaxVSB = vbmp.cy - swpWindow.cy) < 0)%@NL@%
  7740.                     vcMaxVSB = 0;%@NL@%
  7741.                 WinSendMsg(vhwndHSB, SBM_SETSCROLLBAR,%@NL@%
  7742.                     0L, MPFROM2SHORT(0, vcMaxHSB));%@NL@%
  7743.                 WinSendMsg(vhwndVSB, SBM_SETSCROLLBAR,%@NL@%
  7744.                     MPFROMSHORT(vcMaxVSB),%@NL@%
  7745.                     MPFROM2SHORT(0, vcMaxVSB));%@NL@%
  7746.             }%@NL@%
  7747.             %@AB@%/*%@NL@%
  7748. %@AB@%                Draw the BITMAP, based on the scroll bar settings.%@NL@%
  7749. %@AB@%            */%@AE@%%@NL@%
  7750.             GpiSetBitmap(vhpsMemory, (HBITMAP) hItem);%@NL@%
  7751. %@NL@%
  7752.             aptl[0].x = rclWindow.xLeft;        %@AB@%/* Target bottom left */%@AE@%%@NL@%
  7753.             aptl[0].y = rclWindow.yBottom;%@NL@%
  7754.             aptl[1].x = rclWindow.xRight;        %@AB@%/* Target top right */%@AE@%%@NL@%
  7755.             aptl[1].y = rclWindow.yTop;%@NL@%
  7756.                                                 %@AB@%/* Source bottom left */%@AE@%%@NL@%
  7757.             aptl[2].x = (LONG) WinSendMsg(vhwndHSB, SBM_QUERYPOS, 0L, 0L);%@NL@%
  7758.             aptl[2].y = vcMaxVSB%@NL@%
  7759.                 - (LONG) WinSendMsg(vhwndVSB, SBM_QUERYPOS, 0L, 0L);%@NL@%
  7760. %@NL@%
  7761.             GpiBitBlt(hpsWindow, vhpsMemory, 3L, aptl, ROP_SRCCOPY, 0L);%@NL@%
  7762.             GpiSetBitmap(vhpsMemory, NULL);%@NL@%
  7763.             break;%@NL@%
  7764. %@NL@%
  7765.         case CF_METAFILE:%@NL@%
  7766.         case CF_DSPMETAFILE:%@NL@%
  7767.             %@AB@%/*%@NL@%
  7768. %@AB@%                Set up the alOptions for displaying the metafile, and%@NL@%
  7769. %@AB@%                let the system do the rest of the work.%@NL@%
  7770. %@AB@%            */%@AE@%%@NL@%
  7771.             alOptions[PMF_SEGBASE]            = 0L;%@NL@%
  7772.             alOptions[PMF_LOADTYPE]            = LT_DEFAULT;%@NL@%
  7773.             alOptions[PMF_RESOLVE]            = 0L;%@NL@%
  7774.             alOptions[PMF_LCIDS]            = LC_LOADDISC;%@NL@%
  7775.             alOptions[PMF_RESET]            = RES_DEFAULT;%@NL@%
  7776.             alOptions[PMF_SUPPRESS]            = SUP_DEFAULT;%@NL@%
  7777.             alOptions[PMF_COLORTABLES]            = CTAB_NOMODIFY;%@NL@%
  7778.             alOptions[PMF_COLORREALIZABLE]  = CREA_DEFAULT;%@NL@%
  7779.             hmfCopy = GpiCopyMetaFile((HMF) hItem);%@NL@%
  7780.             GpiPlayMetaFile(hpsWindow, hmfCopy, 8L, alOptions, 0L, 0L, NULL);%@NL@%
  7781.             break;%@NL@%
  7782. %@NL@%
  7783.         case CF_EMPTY:%@NL@%
  7784.             %@AB@%/*%@NL@%
  7785. %@AB@%                Don't do anything.%@NL@%
  7786. %@AB@%            */%@AE@%%@NL@%
  7787.             break;%@NL@%
  7788. %@NL@%
  7789.         default:%@NL@%
  7790.             %@AB@%/*%@NL@%
  7791. %@AB@%                If it's an owner-draw format that we can display...%@NL@%
  7792. %@AB@%                ...try to get the owner to paint the clipboard.%@NL@%
  7793. %@AB@%                (return if we were successful or not)%@NL@%
  7794. %@AB@%            */%@AE@%%@NL@%
  7795.             fRendered = SendOwnerMsg(WM_PAINTCLIPBOARD, MPFROMHWND(hwnd), 0L);%@NL@%
  7796.             break;%@NL@%
  7797.       }%@NL@%
  7798.     }%@NL@%
  7799.     %@AB@%/*%@NL@%
  7800. %@AB@%        Tell everybody that the client area is valid now%@NL@%
  7801. %@AB@%    */%@AE@%%@NL@%
  7802.     WinValidateRect(hwnd, (PRECTL) NULL, FALSE);%@NL@%
  7803.     %@AB@%/*%@NL@%
  7804. %@AB@%        Clean up%@NL@%
  7805. %@AB@%    */%@AE@%%@NL@%
  7806.     GpiAssociate(hpsWindow, NULL);%@NL@%
  7807.     GpiDestroyPS(hpsWindow);%@NL@%
  7808.     WinCloseClipbrd(vhab);%@NL@%
  7809.     return fRendered;%@NL@%
  7810. }%@NL@%
  7811. %@NL@%
  7812. BOOL UpdateScreen(HWND hwnd, USHORT usFormat) {%@NL@%
  7813. %@AB@%/*%@NL@%
  7814. %@AB@%    Render the format, change the title bar.%@NL@%
  7815. %@AB@%    The title bar will look like:  "<appname> (<format>)"%@NL@%
  7816. %@AB@%*/%@AE@%%@NL@%
  7817.     BOOL  fRendered = TRUE;%@NL@%
  7818.     HPS   hpsWindow;%@NL@%
  7819.     RECTL rcl;%@NL@%
  7820.     UCHAR szFormat[MAXLEN];%@NL@%
  7821.     UCHAR szTitle[MAXTITLELEN];%@NL@%
  7822. %@NL@%
  7823.     if (vfUpdate) {%@NL@%
  7824.         %@AB@%/* If the MLE exists, destroy it */%@AE@%%@NL@%
  7825.         if (vhwndMLE) {%@NL@%
  7826.             WinDestroyWindow(vhwndMLE);%@NL@%
  7827.             vhwndMLE = NULL;%@NL@%
  7828.         }%@NL@%
  7829. %@NL@%
  7830.         %@AB@%/* Clear the client area */%@AE@%%@NL@%
  7831.         WinQueryWindowRect(hwnd, &rcl);%@NL@%
  7832.         WinInvalidateRect(hwnd, &rcl, FALSE);%@NL@%
  7833.         hpsWindow = WinBeginPaint(hwnd, NULL, NULL);%@NL@%
  7834.         WinFillRect(hpsWindow, &rcl, CLR_BACKGROUND);%@NL@%
  7835.         WinEndPaint(hpsWindow);%@NL@%
  7836.     }%@NL@%
  7837.     if (usFormat)                        // Check that usFormat != CF_EMPTY%@NL@%
  7838.         fRendered = RenderFormat(hwnd, usFormat);%@NL@%
  7839.     %@AB@%/*%@NL@%
  7840. %@AB@%        Set the title bar appropriately%@NL@%
  7841. %@AB@%    */%@AE@%%@NL@%
  7842.     if (!vhwndTitlebar && vhwndClipFrame)%@NL@%
  7843.         vhwndTitlebar = WinWindowFromID(vhwndClipFrame, FID_TITLEBAR);%@NL@%
  7844. %@NL@%
  7845.     if (vhwndTitlebar) {%@NL@%
  7846.         GetFormatName(usFormat, szFormat);%@NL@%
  7847.         LOADSTRING(IDS_APPNAME, szTitle);%@NL@%
  7848.         strcat(szTitle, "("); strcat(szTitle, szFormat); strcat(szTitle, ")");%@NL@%
  7849.         WinSetWindowText(vhwndTitlebar, szTitle);%@NL@%
  7850.     }%@NL@%
  7851.     %@AB@%/*%@NL@%
  7852. %@AB@%        Save the rendered format.%@NL@%
  7853. %@AB@%    */%@AE@%%@NL@%
  7854.     vusFormat = usFormat;%@NL@%
  7855.     return fRendered;%@NL@%
  7856. }%@NL@%
  7857. %@NL@%
  7858. VOID GetAllFormats(VOID) {%@NL@%
  7859.     USHORT usFormat;                // Temporary used when enumerating%@NL@%
  7860.     %@AB@%/*%@NL@%
  7861. %@AB@%        Put ourselves into a clean state%@NL@%
  7862. %@AB@%    */%@AE@%%@NL@%
  7863.     usFormat = vcFmts = 0;%@NL@%
  7864.     %@AB@%/*%@NL@%
  7865. %@AB@%        Cycle through the available clipboard formats%@NL@%
  7866. %@AB@%    */%@AE@%%@NL@%
  7867.     while (usFormat = WinEnumClipbrdFmts(vhab, usFormat)) {%@NL@%
  7868.         vausFormats[vcFmts++] = usFormat;%@NL@%
  7869.     }%@NL@%
  7870.     %@AB@%/*%@NL@%
  7871. %@AB@%        Set the current clipboard format to the first one, if possible%@NL@%
  7872. %@AB@%        (in preparation for the WM_PAINT which will follow).%@NL@%
  7873. %@AB@%    */%@AE@%%@NL@%
  7874.     vusFormat = (vcFmts ? vausFormats[0] : CF_EMPTY);%@NL@%
  7875. }%@NL@%
  7876. %@NL@%
  7877. VOID GetFormatName(USHORT usFormat, UCHAR szFmtName[]) {%@NL@%
  7878. %@AB@%/*%@NL@%
  7879. %@AB@%    GetFormatName()%@NL@%
  7880. %@AB@%%@NL@%
  7881. %@AB@%    This routine returns a format name in szFmtName which corresponds%@NL@%
  7882. %@AB@%    to the format usFormat.  Basically, either we know the format, or%@NL@%
  7883. %@AB@%    we get the name from the system atom table.  If we can't find it,%@NL@%
  7884. %@AB@%    we set it to CF_UNKNOWN.%@NL@%
  7885. %@AB@%*/%@AE@%%@NL@%
  7886.     switch (usFormat) {%@NL@%
  7887.         %@AB@%/*%@NL@%
  7888. %@AB@%            If we know the format, we can read it from the string table.%@NL@%
  7889. %@AB@%        */%@AE@%%@NL@%
  7890.         case CF_EMPTY:%@NL@%
  7891.         case CF_TEXT:%@NL@%
  7892.         case CF_DSPTEXT:%@NL@%
  7893.         case CF_BITMAP:%@NL@%
  7894.         case CF_DSPBITMAP:%@NL@%
  7895.         case CF_METAFILE:%@NL@%
  7896.         case CF_DSPMETAFILE:%@NL@%
  7897.             LOADSTRING(usFormat, szFmtName);%@NL@%
  7898.             break;%@NL@%
  7899. %@NL@%
  7900.         default:%@NL@%
  7901.             %@AB@%/*%@NL@%
  7902. %@AB@%                Get the format name from the system atom table.%@NL@%
  7903. %@AB@%                If not found, tag it as an unknown format.%@NL@%
  7904. %@AB@%            */%@AE@%%@NL@%
  7905.             if (!WinQueryAtomName(WinQuerySystemAtomTable(),%@NL@%
  7906.                    usFormat, szFmtName, MAXLEN))%@NL@%
  7907. %@NL@%
  7908.                 LOADSTRING(CF_UNKNOWN, szFmtName);%@NL@%
  7909. %@NL@%
  7910.             break;%@NL@%
  7911.     }%@NL@%
  7912. }%@NL@%
  7913. %@NL@%
  7914. BOOL SendOwnerMsg(USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  7915.     BOOL    rc;%@NL@%
  7916.     HWND    hwndOwner;%@NL@%
  7917.     %@AB@%/*%@NL@%
  7918. %@AB@%        If we are an OWNERDISPLAY format,%@NL@%
  7919. %@AB@%            lock the owner window, tell it to perform the operation, return%@NL@%
  7920. %@AB@%    */%@AE@%%@NL@%
  7921.     if ( rc = ( (vfsFmtInfo & CFI_OWNERDISPLAY)%@NL@%
  7922.          && (hwndOwner = WinQueryClipbrdOwner(vhab, TRUE)) ) ) {%@NL@%
  7923. %@NL@%
  7924.         WinSendMsg(hwndOwner, msg, mp1, mp2);%@NL@%
  7925.         WinLockWindow(hwndOwner, FALSE);%@NL@%
  7926.     }%@NL@%
  7927.     return rc;%@NL@%
  7928. }%@NL@%
  7929. %@NL@%
  7930. BOOL DoScrolling(HWND hwnd, BOOL fHorz, USHORT sbCmd) {%@NL@%
  7931. %@AB@%/*%@NL@%
  7932. %@AB@%    This routine depends on the fact that the thumb cannot be set past the%@NL@%
  7933. %@AB@%    range of the scroll bar.  Since this is handled in the system SBM_SETPOS%@NL@%
  7934. %@AB@%    code already, we need not worry about it.%@NL@%
  7935. %@AB@%%@NL@%
  7936. %@AB@%    We return TRUE if the scroll bar message is processed.%@NL@%
  7937. %@AB@%*/%@AE@%%@NL@%
  7938.     HWND   hwndSB;                %@AB@%/* Scroll bar handle */%@AE@%%@NL@%
  7939.     USHORT cpels;                %@AB@%/* Page length/width for PAGExxxx commands */%@AE@%%@NL@%
  7940.     SWP    swp;                        %@AB@%/* Dimensions of the client area */%@AE@%%@NL@%
  7941.     USHORT usOld;                %@AB@%/* The current scroll bar position */%@AE@%%@NL@%
  7942.     USHORT usNew;                %@AB@%/* The new scroll bar position */%@AE@%%@NL@%
  7943.     %@AB@%/*%@NL@%
  7944. %@AB@%        Set the scroll bar-specific parameters%@NL@%
  7945. %@AB@%    */%@AE@%%@NL@%
  7946.     WinQueryWindowPos(hwnd, &swp);%@NL@%
  7947.     if (fHorz) {        %@AB@%/* Horizontal scroll bar */%@AE@%%@NL@%
  7948.         hwndSB = vhwndHSB;%@NL@%
  7949.         cpels = swp.cx;%@NL@%
  7950.     } else {                %@AB@%/* Vertical scroll bar */%@AE@%%@NL@%
  7951.         hwndSB = vhwndVSB;%@NL@%
  7952.         cpels = swp.cy;%@NL@%
  7953.     }%@NL@%
  7954.     %@AB@%/*%@NL@%
  7955. %@AB@%        Handle both scroll bars with one common routine%@NL@%
  7956. %@AB@%%@NL@%
  7957. %@AB@%        Basically, the scroll bar has been set so that %@NL@%
  7958. %@AB@%        the thumb value corresponds to the offset that%@NL@%
  7959. %@AB@%        the bitmap is drawn from.  So, to scroll by a%@NL@%
  7960. %@AB@%        page, compute the number of pels of the page,%@NL@%
  7961. %@AB@%        and move the thumb by that amount.%@NL@%
  7962. %@AB@%%@NL@%
  7963. %@AB@%        This code is simplified by the fact that SB_SETPOS%@NL@%
  7964. %@AB@%        will not allow the thumb to be set outside of the%@NL@%
  7965. %@AB@%        range of the scroll bar, but will "stop" it at the%@NL@%
  7966. %@AB@%        appropriate bound.%@NL@%
  7967. %@AB@%    */%@AE@%%@NL@%
  7968.     usOld = SHORT1FROMMR( WinSendMsg(hwndSB, SBM_QUERYPOS, 0L, 0L));%@NL@%
  7969. %@NL@%
  7970.     switch (sbCmd) {%@NL@%
  7971.         case SB_PAGERIGHT:        %@AB@%/* SB_PAGEDOWN */%@AE@%%@NL@%
  7972.             WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld + cpels), 0L);%@NL@%
  7973.             break;%@NL@%
  7974. %@NL@%
  7975.         case SB_PAGELEFT:        %@AB@%/* SB_PAGEUP */%@AE@%%@NL@%
  7976.             WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld - cpels), 0L);%@NL@%
  7977.             break;%@NL@%
  7978. %@NL@%
  7979.         case SB_LINERIGHT:        %@AB@%/* SB_LINEDOWN */%@AE@%%@NL@%
  7980.             WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld + LINE), 0L);%@NL@%
  7981.             break;%@NL@%
  7982. %@NL@%
  7983.         case SB_LINELEFT:        %@AB@%/* SB_LINEUP */%@AE@%%@NL@%
  7984.             WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld - LINE), 0L);%@NL@%
  7985.             break;%@NL@%
  7986. %@NL@%
  7987.         case SB_SLIDERPOSITION:%@NL@%
  7988.             %@AB@%/*%@NL@%
  7989. %@AB@%                It would be nice to be consistent with the other%@NL@%
  7990. %@AB@%                SB_ cases, but the problem is that when this message%@NL@%
  7991. %@AB@%                is sent, the position is *already* set to "usPosition".%@NL@%
  7992. %@AB@%%@NL@%
  7993. %@AB@%                So, just invalidate the entire region, and hope that most%@NL@%
  7994. %@AB@%                of these types of operations will be large scrolls.%@NL@%
  7995. %@AB@%            */%@AE@%%@NL@%
  7996.             // WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(LOUSHORT(mp2)), 0L);%@NL@%
  7997.             WinInvalidateRect(hwnd, NULL, TRUE);%@NL@%
  7998.             break;%@NL@%
  7999. %@NL@%
  8000.         default:%@NL@%
  8001.             return FALSE;%@NL@%
  8002.     }%@NL@%
  8003.     %@AB@%/*%@NL@%
  8004. %@AB@%        Now, we find out where the new thumb position is,%@NL@%
  8005. %@AB@%        scroll the window contents appropriately, and specify%@NL@%
  8006. %@AB@%        SW_INVALIDATERGN so that the remainder will be%@NL@%
  8007. %@AB@%        invalidated/repainted.%@NL@%
  8008. %@AB@%    */%@AE@%%@NL@%
  8009.     usNew = SHORT1FROMMR( WinSendMsg(hwndSB, SBM_QUERYPOS, 0L, 0L));%@NL@%
  8010.     if (fHorz)%@NL@%
  8011.         WinScrollWindow(hwnd, (SHORT) (usOld - usNew), 0, %@NL@%
  8012.             NULL, NULL, NULL, NULL, SW_INVALIDATERGN);%@NL@%
  8013.     else%@NL@%
  8014.         WinScrollWindow(hwnd, 0, (SHORT) (usNew - usOld),%@NL@%
  8015.             NULL, NULL, NULL, NULL, SW_INVALIDATERGN);%@NL@%
  8016. %@NL@%
  8017.     return TRUE;%@NL@%
  8018. }%@NL@%
  8019. %@NL@%
  8020. %@NL@%
  8021. %@2@%%@AH@%CLOCK.C%@AE@%%@EH@%%@NL@%
  8022. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CLOCK\CLOCK.C%@AE@%%@NL@%
  8023. %@NL@%
  8024. %@AB@%/*%@NL@%
  8025. %@AB@%    clock.c        Presentation Manager Analog Clock Application%@NL@%
  8026. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  8027. %@AB@%*/%@AE@%%@NL@%
  8028. %@AI@%#define %@AE@%INCL_PM %@NL@%
  8029. %@AI@%#include %@AE@%<os2.h> %@NL@%
  8030. %@AI@%#include %@AE@%<string.h> %@NL@%
  8031. %@AI@%#include %@AE@%"res.h" %@NL@%
  8032. %@NL@%
  8033. extern MRESULT EXPENTRY ClkWndProc ( HWND , USHORT , MPARAM , MPARAM ) ;%@NL@%
  8034. %@NL@%
  8035. int cdecl main ( int argc , char * argv [ ] ) ;%@NL@%
  8036. BOOL ClkInit ( VOID ) ;%@NL@%
  8037. HWND hwndFrame ;%@NL@%
  8038. HAB hab ;%@NL@%
  8039. HMQ hmq ;%@NL@%
  8040. HSWITCH hsw ;%@NL@%
  8041. extern HPS hps ;%@NL@%
  8042. BOOL fStartAsIcon = FALSE ;%@NL@%
  8043. %@NL@%
  8044. %@AB@%/*%@NL@%
  8045. %@AB@%    main(argc, argv)        Main program%@NL@%
  8046. %@AB@%*/%@AE@%%@NL@%
  8047. int cdecl main ( int argc , char * argv [ ] )%@NL@%
  8048. {%@NL@%
  8049.     QMSG qmsg ;%@NL@%
  8050. %@NL@%
  8051.     %@AB@%/* have we been asked to start ourselves as an icon? */%@AE@%%@NL@%
  8052.     if (argc > 0) {%@NL@%
  8053.         if ( strcmpi ( argv [ 1 ] , "iconic" ) == 0 )%@NL@%
  8054.             fStartAsIcon = TRUE ;%@NL@%
  8055.     }%@NL@%
  8056. %@NL@%
  8057.     if ( ClkInit ( ) ) {%@NL@%
  8058. %@NL@%
  8059.         while ( WinGetMsg ( hab , & qmsg , NULL , 0 , 0 ) )%@NL@%
  8060.             WinDispatchMsg ( hab , & qmsg ) ;%@NL@%
  8061. %@NL@%
  8062.         %@AB@%/* Clean up code */%@AE@%%@NL@%
  8063.         GpiDestroyPS( hps );%@NL@%
  8064.         WinRemoveSwitchEntry ( hsw ) ;%@NL@%
  8065.         WinDestroyWindow ( hwndFrame ) ;%@NL@%
  8066.         WinDestroyMsgQueue ( hmq ) ;%@NL@%
  8067.         WinTerminate ( hab ) ;%@NL@%
  8068.     }%@NL@%
  8069. %@NL@%
  8070.     return 0 ;%@NL@%
  8071. }%@NL@%
  8072. %@NL@%
  8073. %@AB@%/*%@NL@%
  8074. %@AB@%    ClkInit()                Clock Initialization routine%@NL@%
  8075. %@AB@%    Returns TRUE if successful.%@NL@%
  8076. %@AB@%*/%@AE@%%@NL@%
  8077. BOOL ClkInit ( )%@NL@%
  8078. {%@NL@%
  8079.     %@AB@%/* application name, switch list info, and frame creation flags */%@AE@%%@NL@%
  8080.     static PSZ pszClkName = "Clock" ;%@NL@%
  8081.     static SWCNTRL swctl = { 0 , 0 , 0 , 0 , 0 , SWL_VISIBLE ,%@NL@%
  8082.                              SWL_JUMPABLE , "Clock" , 0 } ;%@NL@%
  8083.     static LONG fcf = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_MINMAX%@NL@%
  8084.                       | FCF_SYSMENU ;%@NL@%
  8085. %@NL@%
  8086.     HWND hwndClient ;%@NL@%
  8087.     PID pid ;%@NL@%
  8088.     TID tid ;%@NL@%
  8089. %@NL@%
  8090.     if ( ( hab = WinInitialize ( 0 ) ) == NULL )%@NL@%
  8091.         return FALSE ;%@NL@%
  8092. %@NL@%
  8093.     if ( ( hmq = WinCreateMsgQueue ( hab , 0 ) ) == NULL ) {%@NL@%
  8094.         WinTerminate ( hab ) ;%@NL@%
  8095.         return FALSE ;%@NL@%
  8096.     }%@NL@%
  8097. %@NL@%
  8098.     if ( ! WinRegisterClass ( hab , pszClkName , ClkWndProc ,%@NL@%
  8099.                               CS_SIZEREDRAW , 0 ) ) {%@NL@%
  8100.         WinDestroyMsgQueue ( hmq ) ;%@NL@%
  8101.         WinTerminate ( hab ) ;%@NL@%
  8102.         return FALSE ;%@NL@%
  8103.     }%@NL@%
  8104. %@NL@%
  8105.     hwndFrame = WinCreateStdWindow ( HWND_DESKTOP , ( ULONG ) NULL , & fcf ,%@NL@%
  8106.                                      pszClkName , pszClkName , WS_VISIBLE ,%@NL@%
  8107.                                      (HMODULE) NULL , ID_RESOURCE , & hwndClient ) ;%@NL@%
  8108. %@NL@%
  8109.     if ( hwndFrame == NULL ) {%@NL@%
  8110.         WinDestroyMsgQueue ( hmq ) ;%@NL@%
  8111.         WinTerminate ( hab ) ;%@NL@%
  8112.         return FALSE ;%@NL@%
  8113.     }%@NL@%
  8114. %@NL@%
  8115.     %@AB@%/* add ourselves to the switch list */%@AE@%%@NL@%
  8116.     WinQueryWindowProcess ( hwndFrame , & pid , & tid ) ;%@NL@%
  8117.     swctl . hwnd = hwndFrame ;%@NL@%
  8118.     swctl . idProcess = pid ;%@NL@%
  8119.     hsw = WinAddSwitchEntry ( & swctl ) ;%@NL@%
  8120. %@NL@%
  8121.     return TRUE ;%@NL@%
  8122. }%@NL@%
  8123. %@NL@%
  8124. %@NL@%
  8125. %@2@%%@AH@%COMPORT.C%@AE@%%@EH@%%@NL@%
  8126. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\COMPORT.C%@AE@%%@NL@%
  8127. %@NL@%
  8128. %@AB@%/*%@NL@%
  8129. %@AB@%   comport.c -- This file contains the sources for COM port manipulation.%@NL@%
  8130. %@AB@%   Created by Microsoft Corporation, 1989%@NL@%
  8131. %@AB@%*/%@AE@%%@NL@%
  8132. %@AI@%#define %@AE@% INCL_DOSFILEMGR %@NL@%
  8133. %@AI@%#define %@AE@%        INCL_DOSDEVICES %@NL@%
  8134. %@AI@%#define %@AE@%        INCL_DOSDEVIOCTL %@NL@%
  8135. %@AI@%#include %@AE@%<os2.h> %@NL@%
  8136. %@AI@%#include %@AE@%"global.h" %@NL@%
  8137. %@AI@%#include %@AE@%"comport.h" %@NL@%
  8138. %@AB@%/*%@NL@%
  8139. %@AB@%   Constants%@NL@%
  8140. %@AB@%*/%@AE@%%@NL@%
  8141.        XON        0x11        %@AB@%/* Ctrl Q */%@AE@%%@NL@%
  8142.        XOFF        0x13        %@AB@%/* Ctrl S */%@AE@%%@NL@%
  8143. char        CRLF[2] = { 0x0d, 0x0a };%@NL@%
  8144. %@NL@%
  8145. %@AB@%/*%@NL@%
  8146. %@AB@%    Variables%@NL@%
  8147. %@AB@%*/%@AE@%%@NL@%
  8148. DCBINFO                dcbinfo;        %@AB@%/* Device control block for Ioctl 53H, 73H */%@AE@%%@NL@%
  8149. HFILE                hPort;%@NL@%
  8150. LINECONTROL        lnctlBuf;%@NL@%
  8151. int                rc;%@NL@%
  8152. USHORT                usErrWord;%@NL@%
  8153. %@NL@%
  8154. int ComFlush(void) {%@NL@%
  8155. %@AB@%/*%@NL@%
  8156. %@AB@%    Flush the COM port with Category 11 functions%@NL@%
  8157. %@AB@%*/%@AE@%%@NL@%
  8158.     BYTE Data, Zero = 0;%@NL@%
  8159. %@NL@%
  8160.     %@AB@%/* Call Category 11 Functions 1H, 2H  Flush Input, Output Buffers */%@AE@%%@NL@%
  8161.     if (rc = DosDevIOCtl(&Data, &Zero, 0x01, 11, hPort)) return rc;%@NL@%
  8162.     if (rc = DosDevIOCtl(&Data, &Zero, 0x02, 11, hPort)) return rc;%@NL@%
  8163.     return 0;%@NL@%
  8164. }%@NL@%
  8165. %@NL@%
  8166. int ComInit(COM comTerm) {%@NL@%
  8167. %@AB@%/*%@NL@%
  8168. %@AB@%    Open the COM port according to the specifications%@NL@%
  8169. %@AB@%*/%@AE@%%@NL@%
  8170.     USHORT action;%@NL@%
  8171. %@NL@%
  8172.     %@AB@%/* Get File Handle for COM port (shared read/write access) */%@AE@%%@NL@%
  8173.     if (rc = DosOpen(comTerm.szPort,&hPort, &action, 0L, 0, 0x0001, 0x0042, 0L))%@NL@%
  8174.         return rc;%@NL@%
  8175. %@NL@%
  8176.     %@AB@%/* Call Category 1 Function 41H   Set Baud Rate */%@AE@%%@NL@%
  8177.     if (rc = DosDevIOCtl(NULL, &comTerm.usBaud, 0x41, 1, hPort)) return rc;%@NL@%
  8178. %@NL@%
  8179.     %@AB@%/* Call Category 1 Function 42H   Set Line Characteristics */%@AE@%%@NL@%
  8180.     lnctlBuf.bDataBits        = comTerm.bData;%@NL@%
  8181.     lnctlBuf.bParity        = comTerm.bParity;%@NL@%
  8182.     lnctlBuf.bStopBits        = (BYTE) (comTerm.bStop - 20);        %@AB@%/* IDD_ONESTOP = 20 */%@AE@%%@NL@%
  8183.     if (rc = DosDevIOCtl(NULL, &lnctlBuf, 0x42, 1, hPort)) return rc;%@NL@%
  8184. %@NL@%
  8185.     %@AB@%/* Call Category 1 Function 73H   Query Device Control Block */%@AE@%%@NL@%
  8186.     if (rc = DosDevIOCtl(&dcbinfo, 0L, 0x73, 1, hPort)) return rc;%@NL@%
  8187. %@NL@%
  8188.     %@AB@%/*%@NL@%
  8189. %@AB@%        Do we want software handshaking?%@NL@%
  8190. %@AB@%    */%@AE@%%@NL@%
  8191.     dcbinfo.fbFlowReplace        &= ~(0x03);        %@AB@%/* Clear bits 0 and 1 */%@AE@%%@NL@%
  8192.     dcbinfo.fbFlowReplace        |=%@NL@%
  8193.         (comTerm.fSoftware)        ? (MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE) : 0;%@NL@%
  8194.     %@AB@%/*%@NL@%
  8195. %@AB@%        Do we want hardware handshaking?%@NL@%
  8196. %@AB@%    */%@AE@%%@NL@%
  8197.     %@AB@%/* Turn on DTR, if appropriate */%@AE@%%@NL@%
  8198.     dcbinfo.fbCtlHndShake        &= ~(0x03);        %@AB@%/* Clear bits 0 and 1 */%@AE@%%@NL@%
  8199.     dcbinfo.fbCtlHndShake        |= ((comTerm.fHardware) ? MODE_DTR_CONTROL : 0);%@NL@%
  8200. %@NL@%
  8201.     %@AB@%/* Turn on RTS, if appropriate */%@AE@%%@NL@%
  8202.     dcbinfo.fbFlowReplace        &= ~(0xc0);        %@AB@%/* Clear bits 6 and 7 */%@AE@%%@NL@%
  8203.     dcbinfo.fbFlowReplace        |= ((comTerm.fHardware) ? MODE_RTS_CONTROL : 0);%@NL@%
  8204. %@NL@%
  8205.     %@AB@%/* Adjust CTS output handshaking */%@AE@%%@NL@%
  8206.     dcbinfo.fbCtlHndShake        &= ~MODE_CTS_HANDSHAKE;     %@AB@%/* Clear bit 3 */%@AE@%%@NL@%
  8207.     dcbinfo.fbCtlHndShake        |= ((comTerm.fHardware)?MODE_CTS_HANDSHAKE:0);%@NL@%
  8208. %@NL@%
  8209.     %@AB@%/* Adjust DSR output handshaking */%@AE@%%@NL@%
  8210.     dcbinfo.fbCtlHndShake        &= ~MODE_DSR_HANDSHAKE;     %@AB@%/* Clear bit 4 */%@AE@%%@NL@%
  8211.     dcbinfo.fbCtlHndShake        |= ((comTerm.fHardware)?MODE_DSR_HANDSHAKE:0);%@NL@%
  8212. %@NL@%
  8213.     %@AB@%/* Turn off DCD output handshaking */%@AE@%%@NL@%
  8214.     dcbinfo.fbCtlHndShake        &= ~MODE_DCD_HANDSHAKE;     %@AB@%/* Clear bit 5 */%@AE@%%@NL@%
  8215. %@NL@%
  8216.     %@AB@%/* Adjust DSR input sensitivity */%@AE@%%@NL@%
  8217.     dcbinfo.fbCtlHndShake        &= ~MODE_DSR_SENSITIVITY;   %@AB@%/* Clear bit 6 */%@AE@%%@NL@%
  8218.     dcbinfo.fbCtlHndShake        |= ((comTerm.fHardware)?MODE_DSR_SENSITIVITY:0);%@NL@%
  8219.     %@AB@%/*%@NL@%
  8220. %@AB@%        Set the line to Wait for Character, Read mode%@NL@%
  8221. %@AB@%    */%@AE@%%@NL@%
  8222.     dcbinfo.fbTimeout                &= ~(0x06);        %@AB@%/* Clear bits, then set */%@AE@%%@NL@%
  8223.     dcbinfo.fbTimeout                |= MODE_WAIT_READ_TIMEOUT;%@NL@%
  8224.     dcbinfo.usReadTimeout        = -1;                %@AB@%/* Never! */%@AE@%%@NL@%
  8225.  %@NL@%
  8226.     %@AB@%/* Call Category 1 Function 53H   Set Device Control Block */%@AE@%%@NL@%
  8227.     if (rc = DosDevIOCtl(0L, &dcbinfo, 0x53, 1, hPort)) return rc;%@NL@%
  8228. %@NL@%
  8229.     %@AB@%/* Get ready to start */%@AE@%%@NL@%
  8230.     return ComFlush();%@NL@%
  8231. }%@NL@%
  8232. %@NL@%
  8233. USHORT ComRead(Line pli) {%@NL@%
  8234. %@AB@%/*%@NL@%
  8235. %@AB@%    Reads all characters present%@NL@%
  8236. %@AB@%    Returns:        0 if successful%@NL@%
  8237. %@AB@%                nonzero (Dos Error or Com Error Word) if unsuccessful%@NL@%
  8238. %@AB@%*/%@AE@%%@NL@%
  8239.     %@AB@%/* Read from the port... And snatch as many as you can! (blocking read) */%@AE@%%@NL@%
  8240.     if (rc = DosRead(hPort, pli->szText, MAXLINELEN, &(pli->cch))) return rc;%@NL@%
  8241. %@NL@%
  8242.     %@AB@%/* Check the COM Error Word */%@AE@%%@NL@%
  8243.     if (rc = DosDevIOCtl(&usErrWord, NULL, 0x6d, 1, hPort)) return rc;%@NL@%
  8244. %@NL@%
  8245.     %@AB@%/* ...then return it */%@AE@%%@NL@%
  8246.     return usErrWord;%@NL@%
  8247. }%@NL@%
  8248. %@NL@%
  8249. int ComWrite(char ch) {%@NL@%
  8250. %@AB@%/*%@NL@%
  8251. %@AB@%    Write a character at a time%@NL@%
  8252. %@AB@%%@NL@%
  8253. %@AB@%    Okay as long as you don't type too fast%@NL@%
  8254. %@AB@%*/%@AE@%%@NL@%
  8255.     USHORT nCharsWritten;%@NL@%
  8256. %@NL@%
  8257.     return DosWrite(hPort, &ch, 1, &nCharsWritten);%@NL@%
  8258. }%@NL@%
  8259. %@NL@%
  8260. int ComClose(void) {%@NL@%
  8261. %@AB@%/*%@NL@%
  8262. %@AB@%    Close the COM port%@NL@%
  8263. %@AB@%*/%@AE@%%@NL@%
  8264.     if (rc = ComFlush()) return rc;%@NL@%
  8265.     return DosClose(hPort);%@NL@%
  8266. } %@NL@%
  8267. %@NL@%
  8268. int ComBreak(void) {%@NL@%
  8269. %@AB@%/*%@NL@%
  8270. %@AB@%    Set BREAK mode ON%@NL@%
  8271. %@AB@%*/%@AE@%%@NL@%
  8272.     USHORT ComErr;%@NL@%
  8273. %@NL@%
  8274.     %@AB@%/* Call Category 1 Function 4BH -- Set Break On */%@AE@%%@NL@%
  8275.     return DosDevIOCtl(&ComErr, NULL, 0x4b, 1, hPort);%@NL@%
  8276. }%@NL@%
  8277. %@NL@%
  8278. int ComUnbreak(void) {%@NL@%
  8279. %@AB@%/*%@NL@%
  8280. %@AB@%    Set BREAK mode OFF%@NL@%
  8281. %@AB@%*/%@AE@%%@NL@%
  8282.     USHORT ComErr;%@NL@%
  8283. %@NL@%
  8284.     %@AB@%/* Call Category 1 Function 45H -- Set Break Off */%@AE@%%@NL@%
  8285.     return DosDevIOCtl(&ComErr, NULL, 0x45, 1, hPort);%@NL@%
  8286. }%@NL@%
  8287. %@NL@%
  8288. int ComError(void) { return (int) usErrWord; }%@NL@%
  8289. %@NL@%
  8290. %@NL@%
  8291. %@2@%%@AH@%COMTALK.C%@AE@%%@EH@%%@NL@%
  8292. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\COMTALK.C%@AE@%%@NL@%
  8293. %@NL@%
  8294. %@AB@%/*%@NL@%
  8295. %@AB@%   comtalk.c -- Main routines%@NL@%
  8296. %@AB@%   Created by Microsoft Corporation, 1989%@NL@%
  8297. %@AB@%%@NL@%
  8298. %@AB@%   This file contains the sources for the dialog box manipulation, and menu%@NL@%
  8299. %@AB@%   managment, and other aspects of interfacing with the user.%@NL@%
  8300. %@AB@%*/%@AE@%%@NL@%
  8301. %@AI@%#define %@AE@%INCL_WIN %@NL@%
  8302. %@AI@%#include %@AE@%<os2.h> %@NL@%
  8303. "comtalk.h"        %@AB@%/* definition of COM from Global, and Resource IDs */%@AE@%%@NL@%
  8304. "avio.h"        %@AB@%/* Routines needed to manage AVIO Presentation Space */%@AE@%%@NL@%
  8305. "threads.h"        %@AB@%/* Thread initialization and control routines */%@AE@%%@NL@%
  8306. <stdio.h>        %@AB@%/* Only needed for file I/O */%@AE@%%@NL@%
  8307. <string.h>        %@AB@%/* one strcpy call */%@AE@%%@NL@%
  8308. %@AB@%/*%@NL@%
  8309. %@AB@%    Variables%@NL@%
  8310. %@AB@%*/%@AE@%%@NL@%
  8311. CHAR                 szCaption[] = "";%@NL@%
  8312. HAB                hAB;%@NL@%
  8313. COM                comTerm;%@NL@%
  8314. COM                comTemp;%@NL@%
  8315. HWND                hWndMenu;%@NL@%
  8316. CLASSINFO        clsi;%@NL@%
  8317. PFNWP                pfnOldFrameWndProc;%@NL@%
  8318. BOOL                fConnected        = FALSE;%@NL@%
  8319. BOOL                fPaging;%@NL@%
  8320. int                iUpdate;%@NL@%
  8321. BOOL                fFreeze                = TRUE;%@NL@%
  8322. int                iError;%@NL@%
  8323. %@AB@%/*%@NL@%
  8324. %@AB@%    Macros%@NL@%
  8325. %@AB@%*/%@AE@%%@NL@%
  8326. %@AI@%#define %@AE@%InRange(x, a, b) ((x >= a) && (x <= b)) %@NL@%
  8327. %@NL@%
  8328. %@AB@%/*%@NL@%
  8329. %@AB@%    Shorthand for sending messages, querying%@NL@%
  8330. %@AB@%*/%@AE@%%@NL@%
  8331. %@AI@%#define %@AE@%Parent(h) \ %@NL@%
  8332.     WinQueryWindow(h, QW_PARENT, FALSE)%@NL@%
  8333. %@NL@%
  8334. %@AI@%#define %@AE@%EnableMenuItem(id) \ %@NL@%
  8335.     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \%@NL@%
  8336.                MPFROM2SHORT(MIA_DISABLED,0))%@NL@%
  8337. %@NL@%
  8338. %@AI@%#define %@AE@%DisableMenuItem(id) \ %@NL@%
  8339.     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \%@NL@%
  8340.                MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED))%@NL@%
  8341. %@NL@%
  8342. %@AI@%#define %@AE@%CheckMenuItem(id) \ %@NL@%
  8343.     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \%@NL@%
  8344.                MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED)) %@NL@%
  8345. %@NL@%
  8346. %@AI@%#define %@AE@%UnCheckMenuItem(id) \ %@NL@%
  8347.     WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \%@NL@%
  8348.                MPFROM2SHORT(MIA_CHECKED, 0))%@NL@%
  8349. %@NL@%
  8350. %@AI@%#define %@AE@%PushButton(h, id) \ %@NL@%
  8351.     WinSendDlgItemMsg(h, id, BM_SETCHECK, MPFROM2SHORT(TRUE, 0), 0L) %@NL@%
  8352. %@NL@%
  8353. %@AI@%#define %@AE@%Valid(bData, bStop) \ %@NL@%
  8354.     (((bData == IDD_FIVE) && (bStop != IDD_TWOSTOP)) \%@NL@%
  8355.     || ((bData != IDD_FIVE) && (bStop != IDD_ONEFIVE)))%@NL@%
  8356. %@NL@%
  8357. %@AI@%#define %@AE@%ErrMsg(h, s) \ %@NL@%
  8358.     WinMessageBox(HWND_DESKTOP, h, s, NULL, 0, MB_OK | MB_ICONEXCLAMATION)%@NL@%
  8359. %@NL@%
  8360. char Ctrl(char ch) {%@NL@%
  8361.     return  (CHAR) ((('a' <= ch) && (ch <= 'z')) ?  (ch - 'a' + '\001') :%@NL@%
  8362.           ((('A' <= ch) && (ch <= 'Z')) ? (ch - 'A' + '\001') : ch));%@NL@%
  8363. }%@NL@%
  8364. %@NL@%
  8365. %@AB@%/*%@NL@%
  8366. %@AB@%    Local/Private routines%@NL@%
  8367. %@AB@%*/%@AE@%%@NL@%
  8368. void ReadOpts(HWND);%@NL@%
  8369. void InitTerm(void);%@NL@%
  8370. void Initialize(HWND);%@NL@%
  8371. void ChangeSystemMenu(HWND);%@NL@%
  8372. BOOL Filter(USHORT, char, USHORT);%@NL@%
  8373. %@NL@%
  8374. void main (void) {%@NL@%
  8375.      static CHAR szClientClass[] = "Terminal";%@NL@%
  8376.      HMQ        hmq;%@NL@%
  8377.      HWND        hWndClient, hWndFrame;%@NL@%
  8378.      QMSG        qmsg;%@NL@%
  8379.      ULONG        flFrameFlags = FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL;%@NL@%
  8380.      ULONG         flFrameStyle = WS_VISIBLE | FS_SCREENALIGN;%@NL@%
  8381.      %@NL@%
  8382.      hAB = WinInitialize(0);%@NL@%
  8383.      hmq = WinCreateMsgQueue(hAB, 0);%@NL@%
  8384. %@NL@%
  8385.      WinRegisterClass(hAB, szClientClass, ClientWndProc, CS_SYNCPAINT, 0);%@NL@%
  8386. %@NL@%
  8387.      hWndFrame = WinCreateStdWindow(HWND_DESKTOP, flFrameStyle,%@NL@%
  8388.                                     &flFrameFlags, szClientClass, szCaption,%@NL@%
  8389.                                      0L, (HMODULE) NULL, ID_RESOURCE, &hWndClient);%@NL@%
  8390. %@NL@%
  8391.      %@AB@%/* Setup AVIO PS and force a paint */%@AE@%%@NL@%
  8392.      AvioInit(hWndFrame, hWndClient);%@NL@%
  8393.      WinSendMsg(hWndClient, WM_PAINT, NULL, NULL);%@NL@%
  8394. %@NL@%
  8395.      %@AB@%/* Try to subclass the Frame window... */%@AE@%%@NL@%
  8396.      pfnOldFrameWndProc = WinSubclassWindow(hWndFrame, NewFrameWndProc);%@NL@%
  8397. %@NL@%
  8398.      while (WinGetMsg(hAB, &qmsg, NULL, 0, 0)) WinDispatchMsg(hAB, &qmsg);%@NL@%
  8399. %@NL@%
  8400.      %@AB@%/* Blast the AVIO PS */%@AE@%%@NL@%
  8401.      AvioClose();%@NL@%
  8402. %@NL@%
  8403.      WinDestroyWindow(hWndFrame);%@NL@%
  8404.      WinDestroyMsgQueue(hmq);%@NL@%
  8405.      WinTerminate(hAB);%@NL@%
  8406.      DosExit(EXIT_PROCESS, 0);%@NL@%
  8407. }%@NL@%
  8408. %@NL@%
  8409. MRESULT CALLBACK ClientWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  8410. %@AB@%/*%@NL@%
  8411. %@AB@%     Window Procedure which traps messages to the Client area%@NL@%
  8412. %@AB@%*/%@AE@%%@NL@%
  8413.      switch (msg) {%@NL@%
  8414.           case WM_AVIOUPDATE:%@NL@%
  8415.                 fNoUpdate = AvioUpdateLines(FALSE, &fPaging);%@NL@%
  8416.                 if (fConnected && fPaging) {%@NL@%
  8417.                     CheckMenuItem(IDM_PAGING);%@NL@%
  8418.                 }%@NL@%
  8419.                 break;%@NL@%
  8420. %@NL@%
  8421.           case WM_MSGBOX:%@NL@%
  8422.                 iUpdate = (int)SHORT1FROMMP( mp2);%@NL@%
  8423.                 switch ((int)SHORT1FROMMP(mp1)) {%@NL@%
  8424.                     case (int) MBE_COMREAD:%@NL@%
  8425.                         if (iError = iUpdate) EnableMenuItem(IDM_ERRORS);%@NL@%
  8426.                         iUpdate = 0;%@NL@%
  8427.                         break;%@NL@%
  8428. %@NL@%
  8429.                     default:%@NL@%
  8430.                         ErrMsg(hWnd, aszMessage[SHORT1FROMMP(mp1)]);%@NL@%
  8431.                         break;%@NL@%
  8432.                 }%@NL@%
  8433.                 if (iUpdate) {        %@AB@%/* Page down because queue is full */%@AE@%%@NL@%
  8434.                     fNoUpdate = AvioUpdateLines(TRUE, &fPaging);%@NL@%
  8435.                     if (fConnected && fPaging) CheckMenuItem(IDM_PAGING);%@NL@%
  8436.                     else UnCheckMenuItem(IDM_PAGING);%@NL@%
  8437.                     ThdReset();%@NL@%
  8438.                 }%@NL@%
  8439.                 break;%@NL@%
  8440. %@NL@%
  8441.           case WM_CREATE:%@NL@%
  8442.                 ChangeSystemMenu(hWnd);%@NL@%
  8443.                 %@AB@%/*%@NL@%
  8444. %@AB@%                    Initialize the Dialog Options%@NL@%
  8445. %@AB@%                */%@AE@%%@NL@%
  8446.                 Initialize(hWnd);%@NL@%
  8447.                 %@AB@%/*%@NL@%
  8448. %@AB@%                    Get the Handle so you can enable/disable menu items%@NL@%
  8449. %@AB@%                    Thanks again to Charles Petzold%@NL@%
  8450. %@AB@%                */%@AE@%%@NL@%
  8451.                 hWndMenu = WinWindowFromID(Parent(hWnd), FID_MENU);%@NL@%
  8452.                 %@AB@%/*%@NL@%
  8453. %@AB@%                    Disable some entries (can do this in the resource file)%@NL@%
  8454. %@AB@%                */%@AE@%%@NL@%
  8455.                 DisableMenuItem(IDM_CLOSE);%@NL@%
  8456.                 DisableMenuItem(IDM_BREAK);%@NL@%
  8457.                 DisableMenuItem(IDM_COMMANDMENU);%@NL@%
  8458.                 break;%@NL@%
  8459. %@NL@%
  8460.           case WM_PAINT:                %@AB@%/* Paint the AVIO way! */%@AE@%%@NL@%
  8461.                 AvioPaint(hWnd);%@NL@%
  8462.                 break;%@NL@%
  8463. %@NL@%
  8464.           case WM_SIZE:                        %@AB@%/* Size the AVIO way!  */%@AE@%%@NL@%
  8465.                 fNoUpdate = AvioUpdateLines(FALSE, &fPaging);%@NL@%
  8466.                 if (fConnected && fPaging) {%@NL@%
  8467.                     CheckMenuItem(IDM_PAGING);%@NL@%
  8468.                 }%@NL@%
  8469.                 return AvioSize(hWnd, msg, mp1, mp2);%@NL@%
  8470.                 break;%@NL@%
  8471. %@NL@%
  8472.           case WM_HSCROLL:%@NL@%
  8473.                 AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), TRUE);%@NL@%
  8474.                 break;%@NL@%
  8475. %@NL@%
  8476.           case WM_VSCROLL:%@NL@%
  8477.                 AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), FALSE);%@NL@%
  8478.                 break;%@NL@%
  8479. %@NL@%
  8480.           case WM_ERASEBACKGROUND:%@NL@%
  8481.                 return 0;%@NL@%
  8482.                 break;%@NL@%
  8483. %@NL@%
  8484.           case WM_COMMAND:%@NL@%
  8485.                 switch (COMMANDMSG(&msg)->cmd) {%@NL@%
  8486.                     case IDM_ABOUT:%@NL@%
  8487.                         WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,%@NL@%
  8488.                                   (HMODULE) NULL, IDD_ABOUT, NULL);%@NL@%
  8489.                         return 0;%@NL@%
  8490. %@NL@%
  8491.                     case IDM_HELP:%@NL@%
  8492.                         WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,%@NL@%
  8493.                                   (HMODULE) NULL, IDD_MAINHELPBOX, NULL);%@NL@%
  8494.                         return 0;%@NL@%
  8495. %@NL@%
  8496.                     case IDM_SETTINGS:%@NL@%
  8497.                         WinDlgBox(HWND_DESKTOP, hWnd, SetDlgProc,%@NL@%
  8498.                                   (HMODULE) NULL, IDD_SET, NULL);%@NL@%
  8499.                         return 0;%@NL@%
  8500. %@NL@%
  8501.                     case IDM_CONNECT:%@NL@%
  8502.                         AvioStartup(hWnd);%@NL@%
  8503.                         ThdInitialize(hWnd, comTerm);        %@AB@%/* Spawn 3 threads  */%@AE@%%@NL@%
  8504.                         %@AB@%/*%@NL@%
  8505. %@AB@%                            Disable/Enable Menu Items%@NL@%
  8506. %@AB@%                        */%@AE@%%@NL@%
  8507.                         DisableMenuItem(IDM_CONNECT);%@NL@%
  8508.                         DisableMenuItem(IDM_SETTINGS);%@NL@%
  8509.                         DisableMenuItem(IDM_ERRORS);%@NL@%
  8510. %@NL@%
  8511.                         EnableMenuItem(IDM_CLOSE);%@NL@%
  8512.                         EnableMenuItem(IDM_BREAK);%@NL@%
  8513.                         EnableMenuItem(IDM_COMMANDMENU);%@NL@%
  8514.                         fConnected = TRUE;%@NL@%
  8515.                         return 0;%@NL@%
  8516. %@NL@%
  8517.                     case IDM_CLOSE:%@NL@%
  8518.                         fConnected = FALSE;%@NL@%
  8519.                         ThdTerminate();                %@AB@%/* Might have to wait? */%@AE@%%@NL@%
  8520.                         %@AB@%/*%@NL@%
  8521. %@AB@%                            Update menu items%@NL@%
  8522. %@AB@%                        */%@AE@%%@NL@%
  8523.                         UnCheckMenuItem(IDM_BREAK);%@NL@%
  8524. %@NL@%
  8525.                         DisableMenuItem(IDM_CLOSE);%@NL@%
  8526.                         DisableMenuItem(IDM_BREAK);%@NL@%
  8527.                         DisableMenuItem(IDM_COMMANDMENU);%@NL@%
  8528. %@NL@%
  8529.                         EnableMenuItem(IDM_CONNECT);%@NL@%
  8530.                         EnableMenuItem(IDM_SETTINGS);%@NL@%
  8531. %@NL@%
  8532.                         return 0;%@NL@%
  8533. %@NL@%
  8534.                     case IDM_BREAK:%@NL@%
  8535.                         ThdDoBreak();%@NL@%
  8536.                         return 0;%@NL@%
  8537. %@NL@%
  8538.                     case IDM_ERRORS:%@NL@%
  8539.                         if (iError & 1)%@NL@%
  8540.                             ErrMsg(hWnd, "Receive Queue Overrun");%@NL@%
  8541.                         if (iError & 2)%@NL@%
  8542.                             ErrMsg(hWnd, "Receive Hardware Overrun");%@NL@%
  8543.                         if (iError & 4)%@NL@%
  8544.                             ErrMsg(hWnd, "Parity Error");%@NL@%
  8545.                         if (iError & 8)%@NL@%
  8546.                             ErrMsg(hWnd, "Framing Error");%@NL@%
  8547.                         DisableMenuItem(IDM_ERRORS);%@NL@%
  8548.                         return 0;%@NL@%
  8549. %@NL@%
  8550.                     case IDM_PAGE:%@NL@%
  8551.                         fNoUpdate = AvioUpdateLines(TRUE, &fPaging);%@NL@%
  8552.                         if (fPaging) CheckMenuItem(IDM_PAGING);%@NL@%
  8553.                         else UnCheckMenuItem(IDM_PAGING);%@NL@%
  8554.                         return 0;%@NL@%
  8555. %@NL@%
  8556.                     case IDM_UP:%@NL@%
  8557.                         AvioPageUp();%@NL@%
  8558.                         return 0;%@NL@%
  8559. %@NL@%
  8560.                     case IDM_PAGING:%@NL@%
  8561.                         if (fPaging = !fPaging) {%@NL@%
  8562.                             CheckMenuItem(IDM_PAGING);%@NL@%
  8563.                         } else {%@NL@%
  8564.                             UnCheckMenuItem(IDM_PAGING);%@NL@%
  8565.                         }%@NL@%
  8566.                         return 0;%@NL@%
  8567. %@NL@%
  8568.                     default: return 0;%@NL@%
  8569.                 }%@NL@%
  8570. %@NL@%
  8571.           case WM_CHAR:                %@AB@%/* Put characters in typeahead buffer */%@AE@%%@NL@%
  8572.                 if (fConnected && !(CHARMSG(&msg)->fs & KC_KEYUP)) %@NL@%
  8573.                     if (Filter( CHARMSG(&msg)->fs,%@NL@%
  8574.                          (char)        CHARMSG(&msg)->chr,%@NL@%
  8575.                                 CHARMSG(&msg)->vkey))%@NL@%
  8576.                         ErrMsg(hWnd, "Error Writing COM Port");%@NL@%
  8577.                 break;%@NL@%
  8578. %@NL@%
  8579.           case WM_TRACKFRAME:%@NL@%
  8580.                 AvioTrackFrame(hWnd, mp1);%@NL@%
  8581.                 break;%@NL@%
  8582. %@NL@%
  8583.           case WM_MINMAXFRAME: %@AB@%/* Trap MAXIMIZE messages */%@AE@%%@NL@%
  8584.                 AvioMinMax((PSWP) mp1);%@NL@%
  8585. %@NL@%
  8586.           default: return WinDefWindowProc(hWnd, msg, mp1, mp2);%@NL@%
  8587.      }%@NL@%
  8588.      return 0;%@NL@%
  8589. }%@NL@%
  8590. %@NL@%
  8591. MRESULT CALLBACK AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  8592. %@AB@%/*%@NL@%
  8593. %@AB@%    Dialog box control for the ABOUT COMTALK... dialog box%@NL@%
  8594. %@AB@%*/%@AE@%%@NL@%
  8595.     switch(msg) {%@NL@%
  8596.         case WM_COMMAND:%@NL@%
  8597.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  8598.                 case DID_OK: WinDismissDlg(hDlg, TRUE); break;%@NL@%
  8599.                 default: break;%@NL@%
  8600.             }%@NL@%
  8601.         default: return WinDefDlgProc(hDlg, msg, mp1, mp2);%@NL@%
  8602.     }%@NL@%
  8603.     return FALSE;%@NL@%
  8604. }%@NL@%
  8605. %@NL@%
  8606. void WriteOpts(void) {%@NL@%
  8607. %@AB@%/*%@NL@%
  8608. %@AB@%    Write Settings to file COMTALK.INI%@NL@%
  8609. %@AB@%*/%@AE@%%@NL@%
  8610.     FILE *fp;%@NL@%
  8611. %@NL@%
  8612.     fp = fopen("comtalk.ini", "w+");%@NL@%
  8613.     fprintf(fp, "%d %d %d %d %d %d %d %s\n", comTerm.usBaud, comTerm.bParity,%@NL@%
  8614.                 comTerm.bData, comTerm.bStop, comTerm.fWrap,%@NL@%
  8615.                 comTerm.fHardware, comTerm.fSoftware, comTerm.szPort);%@NL@%
  8616.     fclose(fp);%@NL@%
  8617. }%@NL@%
  8618. %@NL@%
  8619. void ReadOpts(HWND hWnd) {%@NL@%
  8620. %@AB@%/*%@NL@%
  8621. %@AB@%    Read Settings from COMTALK.INI%@NL@%
  8622. %@AB@%*/%@AE@%%@NL@%
  8623.     FILE *fp;%@NL@%
  8624. %@NL@%
  8625.     %@AB@%/* Use InitTerm() if we have reading problems */%@AE@%%@NL@%
  8626.     if ((fp = fopen("comtalk.ini", "r")) == NULL) InitTerm();%@NL@%
  8627.     else if (fscanf(fp, "%d%d%d%d%d%d%d%s", &comTerm.usBaud, &comTerm.bParity,%@NL@%
  8628.         &comTerm.bData, &comTerm.bStop, &comTerm.fWrap,%@NL@%
  8629.         &comTerm.fHardware, &comTerm.fSoftware, comTerm.szPort) == EOF)%@NL@%
  8630.         InitTerm();%@NL@%
  8631.     if (!Valid(comTerm.bData, comTerm.bStop)) {%@NL@%
  8632.         ErrMsg(hWnd, "Invalid terminal setting");%@NL@%
  8633.         InitTerm();%@NL@%
  8634.     }%@NL@%
  8635.     fclose(fp);%@NL@%
  8636. }%@NL@%
  8637. %@NL@%
  8638. void InitTerm(void) {%@NL@%
  8639. %@AB@%/*%@NL@%
  8640. %@AB@%    Initialize the TERM structure to DosDevIOCtl defaults%@NL@%
  8641. %@AB@%*/%@AE@%%@NL@%
  8642.     strcpy(comTerm.szPort, "com1");%@NL@%
  8643.     comTerm.usBaud = 9600; comTerm.bParity = IDD_EVENP;%@NL@%
  8644.     comTerm.bData = IDD_SEVEN; comTerm.bStop = IDD_ONESTOP;%@NL@%
  8645.     comTerm.fWrap = comTerm.fSoftware = TRUE; comTerm.fHardware = FALSE;%@NL@%
  8646. }%@NL@%
  8647. %@NL@%
  8648. MRESULT CALLBACK SetDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  8649. %@AB@%/*%@NL@%
  8650. %@AB@%    The Settings Dialog Box control routine%@NL@%
  8651. %@AB@%*/%@AE@%%@NL@%
  8652.     BOOL        rc;%@NL@%
  8653.     BYTE        bTemp;%@NL@%
  8654. %@NL@%
  8655.     switch(msg) {%@NL@%
  8656.         case WM_INITDLG:%@NL@%
  8657.             WinSetDlgItemText(hDlg, IDD_PORT, comTerm.szPort);%@NL@%
  8658.             WinSetDlgItemShort(hDlg, IDD_BAUD, comTerm.usBaud, FALSE);%@NL@%
  8659. %@NL@%
  8660.             PushButton(hDlg, comTerm.bParity);%@NL@%
  8661.             PushButton(hDlg, comTerm.bData);%@NL@%
  8662.             PushButton(hDlg, comTerm.bStop);%@NL@%
  8663.             if (comTerm.fWrap) PushButton(hDlg, IDD_WRAP);%@NL@%
  8664.             if (comTerm.fHardware) PushButton(hDlg, IDD_HW);%@NL@%
  8665.             if (comTerm.fSoftware) PushButton(hDlg, IDD_SW);%@NL@%
  8666. %@NL@%
  8667.             comTemp.bParity        = comTerm.bParity;%@NL@%
  8668.             comTemp.bData        = comTerm.bData;%@NL@%
  8669.             comTemp.bStop        = comTerm.bStop;%@NL@%
  8670.             comTemp.fWrap        = comTerm.fWrap;%@NL@%
  8671.             comTemp.fHardware        = comTerm.fHardware;%@NL@%
  8672.             comTemp.fSoftware   = comTerm.fSoftware;%@NL@%
  8673.             break; %@NL@%
  8674. %@NL@%
  8675.         case WM_HELP:%@NL@%
  8676.             WinDlgBox(HWND_DESKTOP, hDlg, AboutDlgProc,%@NL@%
  8677.                       (HMODULE) NULL, IDD_SETHELPBOX, NULL);%@NL@%
  8678.             break;%@NL@%
  8679. %@NL@%
  8680.         case WM_CONTROL:%@NL@%
  8681.             %@AB@%/*%@NL@%
  8682. %@AB@%                The fact that these are AutoRadioButtons makes life easy.%@NL@%
  8683. %@AB@%            */%@AE@%%@NL@%
  8684.             bTemp = (BYTE) SHORT1FROMMP(mp1);        %@AB@%/* Which button pushed? */%@AE@%%@NL@%
  8685.             if InRange(bTemp, IDD_NOP, IDD_SPACEP) %@NL@%
  8686.                  { %@NL@%
  8687.                         comTemp.bParity = bTemp; %@NL@%
  8688.             } %@NL@%
  8689.                 else %@NL@%
  8690.                 {%@NL@%
  8691.                         if InRange(bTemp, IDD_FIVE, IDD_EIGHT) %@NL@%
  8692.                         {%@NL@%
  8693.                                 comTemp.bData = bTemp;%@NL@%
  8694.                     } %@NL@%
  8695.                         else %@NL@%
  8696.                         {%@NL@%
  8697.                                 if InRange(bTemp, IDD_ONESTOP, IDD_TWOSTOP) %@NL@%
  8698.                                 {%@NL@%
  8699.                                         comTemp.bStop = bTemp;%@NL@%
  8700.                                 }%@NL@%
  8701.                              else %@NL@%
  8702.                                 {%@NL@%
  8703.                                         switch (bTemp) {%@NL@%
  8704.                                         case IDD_WRAP: comTemp.fWrap     = !comTemp.fWrap;     break;%@NL@%
  8705.                                         case IDD_HW  : comTemp.fHardware = !comTemp.fHardware; break;%@NL@%
  8706.                                         case IDD_SW  : comTemp.fSoftware = !comTemp.fSoftware; break;%@NL@%
  8707.                                         default:                                               break;%@NL@%
  8708.                                     }%@NL@%
  8709.                                 }%@NL@%
  8710.                         }%@NL@%
  8711.                 }%@NL@%
  8712.             break;%@NL@%
  8713.         case WM_COMMAND:        %@AB@%/* Ready to exit... */%@AE@%%@NL@%
  8714.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  8715.                 case IDD_SAVE:%@NL@%
  8716.                 case DID_OK:%@NL@%
  8717.                     if (!Valid(comTemp.bData, comTemp.bStop)) {%@NL@%
  8718.                         ErrMsg(hDlg,"Data and Stop Bits Incompatible");%@NL@%
  8719.                         break;        %@AB@%/* No-op...Dialog not dismissed */%@AE@%%@NL@%
  8720.                     }%@NL@%
  8721.                     WinQueryDlgItemText(hDlg, IDD_PORT, 5, comTerm.szPort);%@NL@%
  8722.                     WinQueryDlgItemShort(hDlg, IDD_BAUD, &comTerm.usBaud, rc);%@NL@%
  8723.                     comTerm.bParity        = comTemp.bParity;%@NL@%
  8724.                     comTerm.bData        = comTemp.bData;%@NL@%
  8725.                     comTerm.bStop        = comTemp.bStop;%@NL@%
  8726.                     comTerm.fWrap        = comTemp.fWrap;%@NL@%
  8727.                     comTerm.fHardware        = comTemp.fHardware;%@NL@%
  8728.                     comTerm.fSoftware        = comTemp.fSoftware;%@NL@%
  8729.                     if (COMMANDMSG(&msg)->cmd == IDD_SAVE) WriteOpts();%@NL@%
  8730.                 case DID_CANCEL: WinDismissDlg(hDlg, FALSE);%@NL@%
  8731.                 default: break;%@NL@%
  8732.             }%@NL@%
  8733.             break;%@NL@%
  8734.         default: return WinDefDlgProc(hDlg, msg, mp1, mp2);%@NL@%
  8735.     }%@NL@%
  8736.     return FALSE;%@NL@%
  8737. }%@NL@%
  8738. %@NL@%
  8739. void Initialize(HWND hWnd) {%@NL@%
  8740.     ReadOpts(hWnd);%@NL@%
  8741.     fPaging = FALSE;%@NL@%
  8742. }%@NL@%
  8743. %@NL@%
  8744. void ChangeSystemMenu(HWND hWnd) {%@NL@%
  8745. %@AB@%/*%@NL@%
  8746. %@AB@%    Insert items into the System Menu (with thanks to Charles Petzold)%@NL@%
  8747. %@AB@%*/%@AE@%%@NL@%
  8748.     static CHAR *x[2] = { NULL, "~About ComTalk..." }; %@AB@%/* Items to add */%@AE@%%@NL@%
  8749.     static MENUITEM mi[2] = {        %@AB@%/* The RESOURCE definitions */%@AE@%%@NL@%
  8750.         MIT_END, MIS_SEPARATOR, 0x0000, 0, NULL, 0,%@NL@%
  8751.         MIT_END, MIS_TEXT, 0x0000, IDM_ABOUT, NULL, 0%@NL@%
  8752.     };%@NL@%
  8753.     HWND        hSM, hSSM;        %@AB@%/* Menu and submenu handles */%@AE@%%@NL@%
  8754.     MENUITEM        miSM;                %@AB@%/* System Menu Menuitem     */%@AE@%%@NL@%
  8755.     SHORT        idSM;                %@AB@%/* ID of the System Menu    */%@AE@%%@NL@%
  8756.     %@AB@%/*%@NL@%
  8757. %@AB@%        Get ahold of the system menu%@NL@%
  8758. %@AB@%    */%@AE@%%@NL@%
  8759.     hSM = WinWindowFromID(Parent(hWnd), FID_SYSMENU);%@NL@%
  8760.     idSM = SHORT1FROMMR( WinSendMsg(hSM, MM_ITEMIDFROMPOSITION, NULL, NULL));%@NL@%
  8761.     WinSendMsg(hSM, MM_QUERYITEM, MPFROM2SHORT(idSM, FALSE), MPFROMP(&miSM));%@NL@%
  8762.     %@AB@%/*%@NL@%
  8763. %@AB@%        Manipulate the System SubMenu%@NL@%
  8764. %@AB@%    */%@AE@%%@NL@%
  8765.     hSSM = miSM.hwndSubMenu;%@NL@%
  8766.     WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi), MPFROMP(x[0]));%@NL@%
  8767.     WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi+1), MPFROMP(x[1]));%@NL@%
  8768. }%@NL@%
  8769. %@NL@%
  8770. MRESULT CALLBACK NewFrameWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  8771. %@AB@%/*%@NL@%
  8772. %@AB@%    Force the frame to stay small enough%@NL@%
  8773. %@AB@%*/%@AE@%%@NL@%
  8774.     BOOL rc;                %@AB@%/* Return code for WM_QueryTrackInfo */%@AE@%%@NL@%
  8775. %@NL@%
  8776.     switch(msg) {%@NL@%
  8777.         case WM_ADJUSTWINDOWPOS:        %@AB@%/* Calculate, then show scrollbars */%@AE@%%@NL@%
  8778.             AvioAdjustFrame(mp1);%@NL@%
  8779.             break;%@NL@%
  8780.         case WM_QUERYTRACKINFO:%@NL@%
  8781.             rc = (BOOL)SHORT1FROMMR ((*pfnOldFrameWndProc)(hWnd, msg, mp1, mp2));%@NL@%
  8782.             AvioQueryTrackInfo((PTRACKINFO) mp2);%@NL@%
  8783.             return (MRESULT) rc;%@NL@%
  8784.         default: break;%@NL@%
  8785.     }%@NL@%
  8786.     return (*pfnOldFrameWndProc)(hWnd, msg, mp1, mp2);%@NL@%
  8787. }%@NL@%
  8788. %@NL@%
  8789. BOOL Filter(USHORT fs, char ch, USHORT vkey) {%@NL@%
  8790.     BOOL rc = FALSE;%@NL@%
  8791. %@NL@%
  8792.     if (fs & KC_VIRTUALKEY) {%@NL@%
  8793.         switch(vkey) {%@NL@%
  8794.             case VK_HOME:%@NL@%
  8795.                 if (fs & KC_CTRL) rc = ThdPutString("\033[2J",4);%@NL@%
  8796.                 return (rc || ThdPutString("\033[H", 3));%@NL@%
  8797.             case VK_UP:%@NL@%
  8798.                 return ThdPutString("\033[A", 3);%@NL@%
  8799.             case VK_DOWN:%@NL@%
  8800.                 return ThdPutString("\033[B", 3);%@NL@%
  8801.             case VK_RIGHT:%@NL@%
  8802.                 return ThdPutString("\033[C", 3);%@NL@%
  8803.             case VK_LEFT:%@NL@%
  8804.                 return ThdPutString("\033[D", 3);%@NL@%
  8805.             default: break;%@NL@%
  8806.         }%@NL@%
  8807.     }%@NL@%
  8808. %@NL@%
  8809.     if (fs & KC_CTRL) {%@NL@%
  8810.         switch (ch) {%@NL@%
  8811.             case 'l':%@NL@%
  8812.             case 'L': AvioRedraw();%@NL@%
  8813.             case '\0': return FALSE; break;%@NL@%
  8814.             default: ch = Ctrl(ch); break;%@NL@%
  8815.         }%@NL@%
  8816.     } else {%@NL@%
  8817.         switch (ch) {%@NL@%
  8818.             case '\0': return FALSE; break;%@NL@%
  8819.             default: break;%@NL@%
  8820.         }%@NL@%
  8821.     }%@NL@%
  8822.     return(rc || ThdPutChar(ch));%@NL@%
  8823. }%@NL@%
  8824. %@NL@%
  8825. %@NL@%
  8826. %@2@%%@AH@%CPGREP.C%@AE@%%@EH@%%@NL@%
  8827. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CPGREP\CPGREP.C%@AE@%%@NL@%
  8828. %@NL@%
  8829. %@AB@%/* cpgrep - string searches%@NL@%
  8830. %@AB@% *%@NL@%
  8831. %@AB@% * Created by Microsoft Corp. 1986%@NL@%
  8832. %@AB@% *%@NL@%
  8833. %@AB@% *%@NL@%
  8834. %@AB@% */%@AE@%%@NL@%
  8835. %@NL@%
  8836. %@AI@%#include %@AE@%               <os2def.h> %@NL@%
  8837. %@AI@%#define %@AE@%INCL_DOSPROCESS %@NL@%
  8838. %@AI@%#define %@AE@%INCL_DOSSEMAPHORES %@NL@%
  8839. %@AI@%#define %@AE@%INCL_DOSQUEUES %@NL@%
  8840. %@AI@%#define %@AE@%INCL_DOSMEMMGR %@NL@%
  8841. %@AI@%#define %@AE@%INCL_DOSMISC %@NL@%
  8842. %@AI@%#include %@AE@%               <bsedos.h> %@NL@%
  8843. %@AI@%#include %@AE@%               <stdio.h> %@NL@%
  8844. %@AI@%#include %@AE@%               <fcntl.h> %@NL@%
  8845. %@AI@%#include %@AE@%               <ctype.h> %@NL@%
  8846. %@NL@%
  8847. %@AI@%#define %@AE@%       BEGLINE                0x40 %@NL@%
  8848. %@AI@%#define %@AE@%       DEBUG                0x08 %@NL@%
  8849. %@AI@%#define %@AE@%       ENDLINE                0x80 %@NL@%
  8850. %@AI@%#define %@AE@%       FILBUFLEN        (SECTORLEN*30) %@NL@%
  8851. %@AI@%#define %@AE@%       FILNAMLEN        80 %@NL@%
  8852. %@AI@%#define %@AE@%       INVERT                0x10 %@NL@%
  8853. %@AI@%#define %@AE@%       ISCOT                0x0002 %@NL@%
  8854. %@AI@%#define %@AE@%       LG2SECLEN        9 %@NL@%
  8855. %@AI@%#define %@AE@%       LINELEN                128 %@NL@%
  8856. %@AI@%#define %@AE@%       LINENOS                0x04 %@NL@%
  8857. %@AI@%#define %@AE@%       LNOLEN                8 %@NL@%
  8858. %@AI@%#define %@AE@%       MAXSTRLEN        128 %@NL@%
  8859. %@AI@%#define %@AE@%       NAMEONLY        0x02 %@NL@%
  8860. %@AI@%#define %@AE@%       OUTBUFLEN        (SECTORLEN*4) %@NL@%
  8861. %@AI@%#define %@AE@%       SECTORLEN        (1 << LG2SECLEN) %@NL@%
  8862. %@AI@%#define %@AE@%       SHOWNAME        0x01 %@NL@%
  8863. %@AI@%#define %@AE@%       STKLEN                256 %@NL@%
  8864. %@AI@%#define %@AE@%       TIMER                0x20 %@NL@%
  8865. %@AI@%#define %@AE@%       TRTABLEN        256 %@NL@%
  8866. %@AI@%#define %@AE@%       s_text(x)        (((char *)(x)) - ((x)->s_must)) %@NL@%
  8867. %@NL@%
  8868. typedef struct stringnode%@NL@%
  8869.   {%@NL@%
  8870.     struct stringnode        *s_alt;                %@AB@%/* List of alternates */%@AE@%%@NL@%
  8871.     struct stringnode        *s_suf;                %@AB@%/* List of suffixes */%@AE@%%@NL@%
  8872.     int                        s_must;                %@AB@%/* Length of portion that must match */%@AE@%%@NL@%
  8873.   }%@NL@%
  8874.                         STRINGNODE;%@NL@%
  8875. %@NL@%
  8876. char                        filbuf[(FILBUFLEN + 2)*2];%@NL@%
  8877. char                        *bufptr[] = { filbuf, filbuf + FILBUFLEN + 2 };%@NL@%
  8878. char                        outbuf[OUTBUFLEN*2];%@NL@%
  8879. char                        *obuf[] = { outbuf, outbuf + OUTBUFLEN };%@NL@%
  8880. char                        *optr[] = { outbuf, outbuf + OUTBUFLEN };%@NL@%
  8881. USHORT                        ocnt[] = { OUTBUFLEN, OUTBUFLEN };%@NL@%
  8882. int                        oi = 0;%@NL@%
  8883. char                        transtab[TRTABLEN] = { 0 };%@NL@%
  8884. STRINGNODE                *stringlist[TRTABLEN/2];%@NL@%
  8885. USHORT                        arrc;                %@AB@%/* I/O return code for DosRead */%@AE@%%@NL@%
  8886. USHORT                        awrc;                %@AB@%/* I/O return code for DosWrite */%@AE@%%@NL@%
  8887. int                        casesen = 1;        %@AB@%/* Assume case-sensitivity */%@AE@%%@NL@%
  8888. USHORT                        cbread;         %@AB@%/* Bytes read by DosRead */%@AE@%%@NL@%
  8889. USHORT                        cbwrite;        %@AB@%/* Bytes written by DosWrite */%@AE@%%@NL@%
  8890. int                        clists = 1;        %@AB@%/* One is first available index */%@AE@%%@NL@%
  8891. int                        flags;                %@AB@%/* Flags */%@AE@%%@NL@%
  8892. int                        lineno;                %@AB@%/* Current line number */%@AE@%%@NL@%
  8893. char                        pmode;                %@AB@%/* Protected mode flag */%@AE@%%@NL@%
  8894. LONG                        readdone;        %@AB@%/* Async read done semaphore */%@AE@%%@NL@%
  8895. LONG                        readpending;        %@AB@%/* Async read pending semaphore */%@AE@%%@NL@%
  8896. int                        status = 1;        %@AB@%/* Assume failure */%@AE@%%@NL@%
  8897. char                        *t2buf;                %@AB@%/* Async read buffer */%@AE@%%@NL@%
  8898. USHORT                        t2buflen;        %@AB@%/* Async read buffer length */%@AE@%%@NL@%
  8899. HFILE                        t2fd;                %@AB@%/* Async read file */%@AE@%%@NL@%
  8900. char                        *t3buf;                %@AB@%/* Async write buffer */%@AE@%%@NL@%
  8901. USHORT                        t3buflen;        %@AB@%/* Async write buffer length */%@AE@%%@NL@%
  8902. HFILE                        t3fd;                %@AB@%/* Async write file */%@AE@%%@NL@%
  8903. LONG                        writedone;        %@AB@%/* Async write done semaphore */%@AE@%%@NL@%
  8904. LONG                        writepending;        %@AB@%/* Async write pending semaphore */%@AE@%%@NL@%
  8905. char                        target[MAXSTRLEN];%@NL@%
  8906.                                         %@AB@%/* Last string added */%@AE@%%@NL@%
  8907. int                        targetlen;        %@AB@%/* Length of last string added */%@AE@%%@NL@%
  8908. %@NL@%
  8909. int                        countlines();        %@AB@%/* See CPGREPSB.ASM */%@AE@%%@NL@%
  8910. int                        countmatched();        %@AB@%/* See CPGREPSB.ASM */%@AE@%%@NL@%
  8911. char                        *findlist();        %@AB@%/* See CPGREPSB.ASM */%@AE@%%@NL@%
  8912. char                        *findone();        %@AB@%/* See CPGREPSB.ASM */%@AE@%%@NL@%
  8913. void                        flush1buf();        %@AB@%/* See below */%@AE@%%@NL@%
  8914. int                        grepbuffer();        %@AB@%/* See below */%@AE@%%@NL@%
  8915. int                        revfind();        %@AB@%/* See CPGREPSB.ASM */%@AE@%%@NL@%
  8916. void                        write1buf();        %@AB@%/* See below */%@AE@%%@NL@%
  8917. char                        *(*find)() = findlist;%@NL@%
  8918. void                        (*flush1)() = flush1buf;%@NL@%
  8919. int                        (*grep)() = grepbuffer;%@NL@%
  8920. void                        (*write1)() = write1buf;%@NL@%
  8921. %@NL@%
  8922. void                        freenode(x)%@NL@%
  8923. register STRINGNODE        *x;                %@AB@%/* Pointer to node to free */%@AE@%%@NL@%
  8924.   {%@NL@%
  8925.     register STRINGNODE        *y;                %@AB@%/* Pointer to next node in list */%@AE@%%@NL@%
  8926. %@NL@%
  8927.     while(x != NULL)                        %@AB@%/* While not at end of list */%@AE@%%@NL@%
  8928.       {%@NL@%
  8929.         if(x->s_suf != NULL) freenode(x->s_suf);%@NL@%
  8930.                                         %@AB@%/* Free suffix list */%@AE@%%@NL@%
  8931.         y = x;                                %@AB@%/* Save pointer */%@AE@%%@NL@%
  8932.         x = x->s_alt;                        %@AB@%/* Move down the list */%@AE@%%@NL@%
  8933.         free(y);                        %@AB@%/* Free the node */%@AE@%%@NL@%
  8934.       }%@NL@%
  8935.   }%@NL@%
  8936. %@NL@%
  8937. %@NL@%
  8938. STRINGNODE                *newnode(s,n)%@NL@%
  8939. char                        *s;                %@AB@%/* String */%@AE@%%@NL@%
  8940. int                        n;                %@AB@%/* Length of string */%@AE@%%@NL@%
  8941.   {%@NL@%
  8942.     register STRINGNODE        *new;                %@AB@%/* Pointer to new node */%@AE@%%@NL@%
  8943.     char                *t;                %@AB@%/* String pointer */%@AE@%%@NL@%
  8944.     char                *malloc();        %@AB@%/* Storage allocator */%@AE@%%@NL@%
  8945. %@NL@%
  8946.     if((t = malloc(sizeof(STRINGNODE) + n + (n & 1))) == NULL)%@NL@%
  8947.       {                                        %@AB@%/* If allocation fails */%@AE@%%@NL@%
  8948.         fprintf(stderr,"Out of memory\n");%@NL@%
  8949.         DosExit( EXIT_PROCESS, 2);        %@AB@%/* Print error message and die */%@AE@%%@NL@%
  8950.       }%@NL@%
  8951.     if(n & 1) ++t;                        %@AB@%/* END of string word-aligned */%@AE@%%@NL@%
  8952.     strncpy(t,s,n);                        %@AB@%/* Copy string text */%@AE@%%@NL@%
  8953.     new = (STRINGNODE *)(t + n);        %@AB@%/* Set pointer to node */%@AE@%%@NL@%
  8954.     new->s_alt = NULL;                        %@AB@%/* No alternates yet */%@AE@%%@NL@%
  8955.     new->s_suf = NULL;                        %@AB@%/* No suffixes yet */%@AE@%%@NL@%
  8956.     new->s_must = n;                        %@AB@%/* Set string length */%@AE@%%@NL@%
  8957.     return(new);                        %@AB@%/* Return pointer to new node */%@AE@%%@NL@%
  8958.   }%@NL@%
  8959. %@NL@%
  8960. %@NL@%
  8961. void                        reallocnode(node,s,n)%@NL@%
  8962. register STRINGNODE        *node;                %@AB@%/* Pointer to node */%@AE@%%@NL@%
  8963. char                        *s;                %@AB@%/* String */%@AE@%%@NL@%
  8964. register int                n;                %@AB@%/* Length of string */%@AE@%%@NL@%
  8965.   {%@NL@%
  8966.     if(n > node->s_must)                %@AB@%/* If node must grow */%@AE@%%@NL@%
  8967.       {%@NL@%
  8968.         fprintf(stderr,"Internal error\n");%@NL@%
  8969.                                         %@AB@%/* Error message */%@AE@%%@NL@%
  8970.         DosExit( EXIT_PROCESS, 2);                          %@AB@%/* Error exit */%@AE@%%@NL@%
  8971.       }%@NL@%
  8972.     node->s_must = n;                        %@AB@%/* Set new length */%@AE@%%@NL@%
  8973.     memcpy(s_text(node),s,n);                %@AB@%/* Copy new text */%@AE@%%@NL@%
  8974.   }%@NL@%
  8975. %@NL@%
  8976. %@NL@%
  8977. void                        addstring(s,n)%@NL@%
  8978. char                        *s;                %@AB@%/* String to add */%@AE@%%@NL@%
  8979. int                        n;                %@AB@%/* Length of string */%@AE@%%@NL@%
  8980.   {%@NL@%
  8981.     register STRINGNODE        *cur;                %@AB@%/* Current string */%@AE@%%@NL@%
  8982.     register STRINGNODE        **pprev;        %@AB@%/* Pointer to previous link */%@AE@%%@NL@%
  8983.     STRINGNODE                *new;                %@AB@%/* New string */%@AE@%%@NL@%
  8984.     int                        i;                %@AB@%/* Index */%@AE@%%@NL@%
  8985.     int                        j;                %@AB@%/* Count */%@AE@%%@NL@%
  8986.     int                        k;                %@AB@%/* Count */%@AE@%%@NL@%
  8987. %@NL@%
  8988.     if(n <= 0 || n > 127) return;        %@AB@%/* Should never happen */%@AE@%%@NL@%
  8989.     i = transtab[*s];                        %@AB@%/* Get current index */%@AE@%%@NL@%
  8990.     if(i == 0)                                %@AB@%/* If no existing list */%@AE@%%@NL@%
  8991.       {%@NL@%
  8992.         %@AB@%/*%@NL@%
  8993. %@AB@%         *  We have to start a new list%@NL@%
  8994. %@AB@%         */%@AE@%%@NL@%
  8995.         if((i = clists++) >= TRTABLEN/2)%@NL@%
  8996.           {                                %@AB@%/* If too many string lists */%@AE@%%@NL@%
  8997.             fprintf(stderr,"Too many string lists\n");%@NL@%
  8998.                                         %@AB@%/* Error message */%@AE@%%@NL@%
  8999.             DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9000.           }%@NL@%
  9001.         stringlist[i] = NULL;                %@AB@%/* Initialize */%@AE@%%@NL@%
  9002.         transtab[*s] = i;                %@AB@%/* Set pointer to new list */%@AE@%%@NL@%
  9003.         if(!casesen && isalpha(*s)) transtab[*s ^ '\x20'] = i;%@NL@%
  9004.                                         %@AB@%/* Set pointer for other case */%@AE@%%@NL@%
  9005.       }%@NL@%
  9006.     else if(stringlist[i] == NULL) return;%@NL@%
  9007.                                         %@AB@%/* Check for existing 1-byte string */%@AE@%%@NL@%
  9008.     if(--n == 0)                        %@AB@%/* If 1-byte string */%@AE@%%@NL@%
  9009.       {%@NL@%
  9010.         freenode(stringlist[i]);        %@AB@%/* Free any existing stuff */%@AE@%%@NL@%
  9011.         stringlist[i] = NULL;                %@AB@%/* No record here */%@AE@%%@NL@%
  9012.         return;                                %@AB@%/* Done */%@AE@%%@NL@%
  9013.       }%@NL@%
  9014.     ++s;                                %@AB@%/* Skip first char */%@AE@%%@NL@%
  9015.     pprev = stringlist + i;                %@AB@%/* Get pointer to link */%@AE@%%@NL@%
  9016.     cur = *pprev;                        %@AB@%/* Get pointer to node */%@AE@%%@NL@%
  9017.     while(cur != NULL)                        %@AB@%/* Loop to traverse match tree */%@AE@%%@NL@%
  9018.       {%@NL@%
  9019.         i = (n > cur->s_must)? cur->s_must: n;%@NL@%
  9020.                                         %@AB@%/* Find minimum of string lengths */%@AE@%%@NL@%
  9021.         matchstrings(s,s_text(cur),i,&j,&k);%@NL@%
  9022.                                         %@AB@%/* Compare the strings */%@AE@%%@NL@%
  9023.         if(j == 0)                        %@AB@%/* If complete mismatch */%@AE@%%@NL@%
  9024.           {%@NL@%
  9025.             if(k < 0) break;                %@AB@%/* Break if insertion point found */%@AE@%%@NL@%
  9026.             pprev = &(cur->s_alt);        %@AB@%/* Get pointer to alternate link */%@AE@%%@NL@%
  9027.             cur = *pprev;                %@AB@%/* Follow the link */%@AE@%%@NL@%
  9028.           }%@NL@%
  9029.         else if(i == j)                        %@AB@%/* Else if strings matched */%@AE@%%@NL@%
  9030.           {%@NL@%
  9031.             if(i == n)                        %@AB@%/* If new is prefix of current */%@AE@%%@NL@%
  9032.               {%@NL@%
  9033.                 reallocnode(cur,s_text(cur),n);%@NL@%
  9034.                                         %@AB@%/* Shorten text of node */%@AE@%%@NL@%
  9035.                 if(cur->s_suf != NULL)        %@AB@%/* If there are suffixes */%@AE@%%@NL@%
  9036.                   {%@NL@%
  9037.                     freenode(cur->s_suf);%@NL@%
  9038.                                         %@AB@%/* Suffixes no longer needed */%@AE@%%@NL@%
  9039.                     cur->s_suf = NULL;%@NL@%
  9040.                   }%@NL@%
  9041.                 return;                        %@AB@%/* All done */%@AE@%%@NL@%
  9042.               }%@NL@%
  9043.             pprev = &(cur->s_suf);        %@AB@%/* Get pointer to suffix link */%@AE@%%@NL@%
  9044.             if((cur = *pprev) == NULL) return;%@NL@%
  9045.                                         %@AB@%/* Done if current is prefix of new */%@AE@%%@NL@%
  9046.             s += i;                        %@AB@%/* Skip matched portion */%@AE@%%@NL@%
  9047.             n -= i;%@NL@%
  9048.           }%@NL@%
  9049.         else                                %@AB@%/* Else partial match */%@AE@%%@NL@%
  9050.           {%@NL@%
  9051.             %@AB@%/*%@NL@%
  9052. %@AB@%             *        We must split an existing node.%@NL@%
  9053. %@AB@%             *        This is the trickiest case.%@NL@%
  9054. %@AB@%             */%@AE@%%@NL@%
  9055.             new = newnode(s_text(cur) + j,cur->s_must - j);%@NL@%
  9056.                                         %@AB@%/* Unmatched part of current string */%@AE@%%@NL@%
  9057.             reallocnode(cur,s_text(cur),j);%@NL@%
  9058.                                         %@AB@%/* Set length to matched portion */%@AE@%%@NL@%
  9059.             new->s_suf = cur->s_suf;        %@AB@%/* Current string's suffixes */%@AE@%%@NL@%
  9060.             if(k < 0)                        %@AB@%/* If new preceded current */%@AE@%%@NL@%
  9061.               {%@NL@%
  9062.                 cur->s_suf = newnode(s + j,n - j);%@NL@%
  9063.                                         %@AB@%/* FIrst suffix is new string */%@AE@%%@NL@%
  9064.                 cur->s_suf->s_alt = new;%@AB@%/* Alternate is part of current */%@AE@%%@NL@%
  9065.               }%@NL@%
  9066.             else                        %@AB@%/* Else new followed current */%@AE@%%@NL@%
  9067.               {%@NL@%
  9068.                 new->s_alt = newnode(s + j,n - j);%@NL@%
  9069.                                         %@AB@%/* Unmatched new string is alternate */%@AE@%%@NL@%
  9070.                 cur->s_suf = new;        %@AB@%/* New suffix list */%@AE@%%@NL@%
  9071.               }%@NL@%
  9072.             return;%@NL@%
  9073.           }%@NL@%
  9074.       }%@NL@%
  9075.     *pprev = newnode(s,n);                %@AB@%/* Set pointer to new node */%@AE@%%@NL@%
  9076.     (*pprev)->s_alt = cur;                %@AB@%/* Attach alternates */%@AE@%%@NL@%
  9077.   }%@NL@%
  9078. %@NL@%
  9079. %@NL@%
  9080. int                        addfancy(buffer,buflen,seplist)%@NL@%
  9081. register char                *buffer;        %@AB@%/* Buffer */%@AE@%%@NL@%
  9082. int                        buflen;                %@AB@%/* Length of buffer */%@AE@%%@NL@%
  9083. char                        *seplist;        %@AB@%/* List of separators */%@AE@%%@NL@%
  9084.   {%@NL@%
  9085.     register char        *bufend;        %@AB@%/* Pointer to end of buffer */%@AE@%%@NL@%
  9086.     int                        strcnt = 0;        %@AB@%/* String count */%@AE@%%@NL@%
  9087.     int                        len;                %@AB@%/* String length */%@AE@%%@NL@%
  9088.     char                c;                %@AB@%/* One char buffer */%@AE@%%@NL@%
  9089. %@NL@%
  9090.     bufend = buffer + buflen;                %@AB@%/* Set end pointer */%@AE@%%@NL@%
  9091.     while(buffer < bufend)                %@AB@%/* Loop through all strings */%@AE@%%@NL@%
  9092.       {%@NL@%
  9093.         len = strncspn(buffer,seplist,bufend - buffer);%@NL@%
  9094.                                         %@AB@%/* Length of string */%@AE@%%@NL@%
  9095.         if(flags & ENDLINE)                %@AB@%/* If match must be at end of line */%@AE@%%@NL@%
  9096.           {%@NL@%
  9097.             c = buffer[len];                %@AB@%/* Save 1st character past string */%@AE@%%@NL@%
  9098.             buffer[len++] = '\r';        %@AB@%/* Carriage return marks end of line */%@AE@%%@NL@%
  9099.           }%@NL@%
  9100.         if(findlist(buffer,buffer + len) == NULL)%@NL@%
  9101.           {                                %@AB@%/* If no match within string */%@AE@%%@NL@%
  9102.             addstring(buffer,len);        %@AB@%/* Add string to list */%@AE@%%@NL@%
  9103.             if(strcnt++ == 0)                %@AB@%/* If first string */%@AE@%%@NL@%
  9104.               {%@NL@%
  9105.                 memcpy(target,buffer,len);%@NL@%
  9106.                                         %@AB@%/* Save first string in buffer */%@AE@%%@NL@%
  9107.                 targetlen = len;        %@AB@%/* Remember length */%@AE@%%@NL@%
  9108.               }%@NL@%
  9109.           }%@NL@%
  9110.         buffer += len;                        %@AB@%/* Skip over string */%@AE@%%@NL@%
  9111.         if(flags & ENDLINE) (--buffer)[0] = c;%@NL@%
  9112.                                         %@AB@%/* Restore saved character */%@AE@%%@NL@%
  9113.         buffer += strnspn(buffer,seplist,bufend - buffer);%@NL@%
  9114.                                         %@AB@%/* Skip over trailing separators */%@AE@%%@NL@%
  9115.       }%@NL@%
  9116.     return(strcnt);                        %@AB@%/* Return string count */%@AE@%%@NL@%
  9117.   }%@NL@%
  9118. %@NL@%
  9119. %@NL@%
  9120. int                        addplain(buffer,buflen,seplist)%@NL@%
  9121. register char                *buffer;        %@AB@%/* String list buffer */%@AE@%%@NL@%
  9122. int                        buflen;                %@AB@%/* Buffer length */%@AE@%%@NL@%
  9123. char                        *seplist;        %@AB@%/* List of separators */%@AE@%%@NL@%
  9124.   {%@NL@%
  9125.     int                        strcnt;                %@AB@%/* String count */%@AE@%%@NL@%
  9126.     register int        len;                %@AB@%/* String length */%@AE@%%@NL@%
  9127.     char                c;                %@AB@%/* One char buffer */%@AE@%%@NL@%
  9128. %@NL@%
  9129.     strcnt = 0;%@NL@%
  9130.     while((len = strncspn(buffer,seplist,buflen)) > 0)%@NL@%
  9131.       {                                        %@AB@%/* While not at end of input list */%@AE@%%@NL@%
  9132.         if(flags & ENDLINE)                %@AB@%/* If match must be at end of line */%@AE@%%@NL@%
  9133.           {%@NL@%
  9134.             c = buffer[len];                %@AB@%/* Save 1st character past string */%@AE@%%@NL@%
  9135.             buffer[len++] = '\r';        %@AB@%/* Carriage return marks end of line */%@AE@%%@NL@%
  9136.           }%@NL@%
  9137.         if(strcnt == 0)                        %@AB@%/* Save first string */%@AE@%%@NL@%
  9138.           {%@NL@%
  9139.             strncpy(target,buffer,len);        %@AB@%/* Save string in buffer */%@AE@%%@NL@%
  9140.             targetlen = len;                %@AB@%/* Save string length */%@AE@%%@NL@%
  9141.           }%@NL@%
  9142.         addstring(buffer,len);                %@AB@%/* Add the string to the table */%@AE@%%@NL@%
  9143.         if(flags & ENDLINE) buffer[--len] = c;%@NL@%
  9144.                                         %@AB@%/* Restore saved character */%@AE@%%@NL@%
  9145.         buffer += len;                        %@AB@%/* Skip the string */%@AE@%%@NL@%
  9146.         buflen -= len;%@NL@%
  9147.         len = strnspn(buffer,seplist,buflen);%@NL@%
  9148.                                         %@AB@%/* Skip separators */%@AE@%%@NL@%
  9149.         buffer += len;%@NL@%
  9150.         buflen -= len;%@NL@%
  9151.         ++strcnt;                        %@AB@%/* Increment string count */%@AE@%%@NL@%
  9152.       }%@NL@%
  9153.     return(strcnt);                        %@AB@%/* Return string count */%@AE@%%@NL@%
  9154.   }%@NL@%
  9155. %@NL@%
  9156. %@NL@%
  9157. void                        dumplist(node,indent)%@NL@%
  9158. register STRINGNODE        *node;                %@AB@%/* Pointer to list to dump */%@AE@%%@NL@%
  9159. int                        indent;                %@AB@%/* Current length of buffer */%@AE@%%@NL@%
  9160.   {%@NL@%
  9161.     int                        i;                %@AB@%/* Counter */%@AE@%%@NL@%
  9162. %@NL@%
  9163.     while(node != NULL)                        %@AB@%/* While not at end of list */%@AE@%%@NL@%
  9164.       {%@NL@%
  9165.         for(i = 0; i < indent; ++i) fputc(' ',stderr);%@NL@%
  9166.         fwrite(s_text(node),sizeof(char),node->s_must,stderr);%@NL@%
  9167.         fprintf(stderr,"\n");%@NL@%
  9168.         if(node->s_suf != NULL)%@NL@%
  9169.           dumplist(node->s_suf,indent + node->s_must);%@NL@%
  9170.                                         %@AB@%/* Recurse to do suffixes */%@AE@%%@NL@%
  9171.         node = node->s_alt;                %@AB@%/* Do next alternate in list */%@AE@%%@NL@%
  9172.       }%@NL@%
  9173.   }%@NL@%
  9174. %@NL@%
  9175. %@NL@%
  9176. void                        dumpstrings()%@NL@%
  9177.   {%@NL@%
  9178.     int                        i;                %@AB@%/* Index */%@AE@%%@NL@%
  9179. %@NL@%
  9180.     for(i = 0; i < TRTABLEN; ++i)        %@AB@%/* Loop through translation table */%@AE@%%@NL@%
  9181.       {%@NL@%
  9182.         if(transtab[i] == 0) continue;        %@AB@%/* Skip null entries */%@AE@%%@NL@%
  9183.         fprintf(stderr,"%c\n",i);        %@AB@%/* Print the first byte */%@AE@%%@NL@%
  9184.         dumplist(stringlist[transtab[i]],1);%@NL@%
  9185.                                         %@AB@%/* Dump the list */%@AE@%%@NL@%
  9186.       }%@NL@%
  9187.   }%@NL@%
  9188. %@NL@%
  9189. %@NL@%
  9190. HFILE                        openfile(name)%@NL@%
  9191. char                        *name;                %@AB@%/* File name */%@AE@%%@NL@%
  9192.   {%@NL@%
  9193.     HFILE                fd;                %@AB@%/* File descriptor */%@AE@%%@NL@%
  9194. %@NL@%
  9195.     if((fd = open(name,0)) == -1)        %@AB@%/* If error opening file */%@AE@%%@NL@%
  9196.       {%@NL@%
  9197.         fprintf(stderr,"Cannot open %s\r\n",name);%@NL@%
  9198.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9199.       }%@NL@%
  9200.     return(fd);                                %@AB@%/* Return file descriptor */%@AE@%%@NL@%
  9201.   }%@NL@%
  9202. %@NL@%
  9203. %@NL@%
  9204. void far                thread2()        %@AB@%/* Read thread */%@AE@%%@NL@%
  9205.   {%@NL@%
  9206.     while(DosSemRequest( &readpending, -1L) == 0)%@NL@%
  9207.       {                                        %@AB@%/* While there is work to do */%@AE@%%@NL@%
  9208.         arrc = DosRead( t2fd, t2buf, t2buflen, &cbread);%@NL@%
  9209.                                         %@AB@%/* Do the read */%@AE@%%@NL@%
  9210.         DosSemClear( &readdone);        %@AB@%/* Signal read completed */%@AE@%%@NL@%
  9211.       }%@NL@%
  9212.     fprintf(stderr,"Thread 2: DosSemRequest failed\n");%@NL@%
  9213.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9214.     DosExit( EXIT_PROCESS, 2);                %@AB@%/* Die */%@AE@%%@NL@%
  9215.   }%@NL@%
  9216. %@NL@%
  9217. %@NL@%
  9218. void far                thread3()        %@AB@%/* Write thread */%@AE@%%@NL@%
  9219.   {%@NL@%
  9220.     while(DosSemRequest((long far *) &writepending,-1L) == 0)%@NL@%
  9221.       {                                        %@AB@%/* While there is work to do */%@AE@%%@NL@%
  9222.         awrc = DosWrite(t3fd, t3buf, t3buflen, &cbwrite);%@NL@%
  9223.                                         %@AB@%/* Do the write */%@AE@%%@NL@%
  9224.         DosSemClear( &writedone);        %@AB@%/* Signal write completed */%@AE@%%@NL@%
  9225.       }%@NL@%
  9226.     fprintf(stderr,"Thread 3: DosSemRequest failed\n");%@NL@%
  9227.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9228.     DosExit( EXIT_PROCESS, 2);                %@AB@%/* Die */%@AE@%%@NL@%
  9229.   }%@NL@%
  9230. %@NL@%
  9231. %@NL@%
  9232. void                        startread(fd,buffer,buflen)%@NL@%
  9233. HFILE                        fd;                %@AB@%/* File handle */%@AE@%%@NL@%
  9234. char                        *buffer;        %@AB@%/* Buffer */%@AE@%%@NL@%
  9235. USHORT                        buflen;         %@AB@%/* Buffer length */%@AE@%%@NL@%
  9236.   {%@NL@%
  9237.     if(pmode)                                %@AB@%/* If protected mode */%@AE@%%@NL@%
  9238.       {%@NL@%
  9239.         if(DosSemRequest( &readdone, -1L) != 0)%@NL@%
  9240.           {                                %@AB@%/* If we fail to get the semaphore */%@AE@%%@NL@%
  9241.             fprintf(stderr,"DosSemRequest failed\n");%@NL@%
  9242.                                         %@AB@%/* Error message */%@AE@%%@NL@%
  9243.             DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9244.           }%@NL@%
  9245.         t2fd = fd;                        %@AB@%/* Set parameters for read */%@AE@%%@NL@%
  9246.         t2buf = buffer;%@NL@%
  9247.         t2buflen = buflen;%@NL@%
  9248.         DosSemClear( &readpending);        %@AB@%/* Wake thread 2 for read */%@AE@%%@NL@%
  9249.         DosSleep(0L);                        %@AB@%/* Yield the CPU */%@AE@%%@NL@%
  9250.       }%@NL@%
  9251.     else arrc = DosRead( fd, buffer, buflen, &cbread);%@NL@%
  9252.   }%@NL@%
  9253. %@NL@%
  9254. %@NL@%
  9255. int                        finishread()%@NL@%
  9256.   {%@NL@%
  9257.     if(pmode && DosSemWait( &readdone, -1L) != 0)%@NL@%
  9258.       {                                        %@AB@%/* If protected mode and wait fails */%@AE@%%@NL@%
  9259.         fprintf(stderr,"DosSemWait failed\n");%@NL@%
  9260.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9261.         DosExit( EXIT_PROCESS, 2);                          %@AB@%/* Die */%@AE@%%@NL@%
  9262.       }%@NL@%
  9263.     return((arrc == 0)? cbread: -1);        %@AB@%/* Return number of bytes read */%@AE@%%@NL@%
  9264.   }%@NL@%
  9265. %@NL@%
  9266. %@NL@%
  9267. void                        startwrite(fd,buffer,buflen)%@NL@%
  9268. HFILE                        fd;                %@AB@%/* File handle */%@AE@%%@NL@%
  9269. char                        *buffer;        %@AB@%/* Buffer */%@AE@%%@NL@%
  9270. USHORT                        buflen;         %@AB@%/* Buffer length */%@AE@%%@NL@%
  9271.   {%@NL@%
  9272.     if(pmode)                                %@AB@%/* If protected mode */%@AE@%%@NL@%
  9273.       {%@NL@%
  9274.         if(DosSemRequest( &writedone, -1L) != 0)%@NL@%
  9275.           {                                %@AB@%/* If we fail to get the semaphore */%@AE@%%@NL@%
  9276.             fprintf(stderr,"DosSemRequest failed\n");%@NL@%
  9277.                                         %@AB@%/* Error message */%@AE@%%@NL@%
  9278.             DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9279.           }%@NL@%
  9280.         t3fd = fd;                        %@AB@%/* Set parameters for write */%@AE@%%@NL@%
  9281.         t3buf = buffer;%@NL@%
  9282.         t3buflen = buflen;%@NL@%
  9283.         DosSemClear( &writepending);        %@AB@%/* Wake thread 3 for read */%@AE@%%@NL@%
  9284.         DosSleep(0L);                        %@AB@%/* Yield the CPU */%@AE@%%@NL@%
  9285.       }%@NL@%
  9286.     else awrc = DosWrite(fd, buffer, buflen, &cbwrite);%@NL@%
  9287.   }%@NL@%
  9288. %@NL@%
  9289. %@NL@%
  9290. int                        finishwrite()%@NL@%
  9291.   {%@NL@%
  9292.     if(pmode && DosSemWait( &writedone, -1L) != 0)%@NL@%
  9293.       {                                        %@AB@%/* If protected mode and wait fails */%@AE@%%@NL@%
  9294.         fprintf(stderr,"DosSemWait failed\n");%@NL@%
  9295.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9296.         DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9297.       }%@NL@%
  9298.     return((awrc == 0)? cbwrite: -1);        %@AB@%/* Return number of bytes written */%@AE@%%@NL@%
  9299.   }%@NL@%
  9300. %@NL@%
  9301. %@NL@%
  9302. void                        write1nobuf(buffer,buflen)%@NL@%
  9303. char                        *buffer;        %@AB@%/* Buffer */%@AE@%%@NL@%
  9304. USHORT                        buflen;         %@AB@%/* Buffer length */%@AE@%%@NL@%
  9305.   {%@NL@%
  9306.     int                        cb;                %@AB@%/* Count of bytes written */%@AE@%%@NL@%
  9307. %@NL@%
  9308.     if( DosWrite(1, buffer, buflen, &cb) != 0 || cb != buflen)%@NL@%
  9309.                                         %@AB@%/* If write fails */%@AE@%%@NL@%
  9310.       {%@NL@%
  9311.         fprintf(stderr,"write error %d\n",awrc);%@NL@%
  9312.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9313.         DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9314.       }%@NL@%
  9315.   }%@NL@%
  9316. %@NL@%
  9317. %@NL@%
  9318. void                        write1buf(buffer,buflen)%@NL@%
  9319. char                        *buffer;        %@AB@%/* Buffer */%@AE@%%@NL@%
  9320. USHORT                        buflen;         %@AB@%/* Buffer length */%@AE@%%@NL@%
  9321.   {%@NL@%
  9322.     USHORT                cb;                %@AB@%/* Byte count */%@AE@%%@NL@%
  9323. %@NL@%
  9324.     while(buflen > 0)                        %@AB@%/* While bytes remain */%@AE@%%@NL@%
  9325.       {%@NL@%
  9326.         if(awrc != 0)                        %@AB@%/* If previous write failed */%@AE@%%@NL@%
  9327.           {%@NL@%
  9328.             fprintf(stderr,"write error %d\n",awrc);%@NL@%
  9329.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9330.             DosExit( EXIT_PROCESS, 2);                          %@AB@%/* Die */%@AE@%%@NL@%
  9331.           }%@NL@%
  9332.         if((cb = ocnt[oi]) == 0)        %@AB@%/* If buffer full */%@AE@%%@NL@%
  9333.           {%@NL@%
  9334.             startwrite(1,obuf[oi],OUTBUFLEN);%@NL@%
  9335.                                         %@AB@%/* Write the buffer */%@AE@%%@NL@%
  9336.             ocnt[oi] = OUTBUFLEN;        %@AB@%/* Reset count and pointer */%@AE@%%@NL@%
  9337.             optr[oi] = obuf[oi];%@NL@%
  9338.             oi ^= 1;                        %@AB@%/* Switch buffers */%@AE@%%@NL@%
  9339.             cb = ocnt[oi];                %@AB@%/* Get space remaining */%@AE@%%@NL@%
  9340.           }%@NL@%
  9341.         if(cb > buflen) cb = buflen;        %@AB@%/* Get minimum */%@AE@%%@NL@%
  9342.         memcpy(optr[oi],buffer,cb);        %@AB@%/* Copy bytes to buffer */%@AE@%%@NL@%
  9343.         ocnt[oi] -= cb;                        %@AB@%/* Update buffer length and pointers */%@AE@%%@NL@%
  9344.         optr[oi] += cb;%@NL@%
  9345.         buflen -= cb;%@NL@%
  9346.         buffer += cb;%@NL@%
  9347.       }%@NL@%
  9348.   }%@NL@%
  9349. %@NL@%
  9350. %@NL@%
  9351. void                        flush1nobuf()%@NL@%
  9352.   {%@NL@%
  9353.   }%@NL@%
  9354. %@NL@%
  9355. %@NL@%
  9356. void                        flush1buf()%@NL@%
  9357.   {%@NL@%
  9358.     int                        cb;                %@AB@%/* Byte count */%@AE@%%@NL@%
  9359. %@NL@%
  9360.     if((cb = OUTBUFLEN - ocnt[oi]) > 0)        %@AB@%/* If buffer not empty */%@AE@%%@NL@%
  9361.       {%@NL@%
  9362.         startwrite(1,obuf[oi],cb);        %@AB@%/* Start write */%@AE@%%@NL@%
  9363.         if(finishwrite() != cb)                %@AB@%/* If write failed */%@AE@%%@NL@%
  9364.           {%@NL@%
  9365.             fprintf(stderr,"write error %d\n",awrc);%@NL@%
  9366.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9367.             DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9368.           }%@NL@%
  9369.       }%@NL@%
  9370.   }%@NL@%
  9371. %@NL@%
  9372. %@NL@%
  9373. int                        grepnull(cp,endbuf,name)%@NL@%
  9374. register char                *cp;                %@AB@%/* Buffer pointer */%@AE@%%@NL@%
  9375. char                        *endbuf;        %@AB@%/* End of buffer */%@AE@%%@NL@%
  9376. char                        *name;                %@AB@%/* File name */%@AE@%%@NL@%
  9377.   {%@NL@%
  9378.     return(0);                                %@AB@%/* Do nothing */%@AE@%%@NL@%
  9379.   }%@NL@%
  9380. %@NL@%
  9381. %@NL@%
  9382. int                        grepbuffer(startbuf,endbuf,name)%@NL@%
  9383. char                        *startbuf;        %@AB@%/* Start of buffer */%@AE@%%@NL@%
  9384. char                        *endbuf;        %@AB@%/* End of buffer */%@AE@%%@NL@%
  9385. char                        *name;                %@AB@%/* File name */%@AE@%%@NL@%
  9386.   {%@NL@%
  9387.     register char        *cp;                %@AB@%/* Buffer pointer */%@AE@%%@NL@%
  9388.     char                *lastmatch;        %@AB@%/* Last matching line */%@AE@%%@NL@%
  9389.     int                        linelen;        %@AB@%/* Line length */%@AE@%%@NL@%
  9390.     int                        namlen = 0;        %@AB@%/* Length of name */%@AE@%%@NL@%
  9391.     char                lnobuf[LNOLEN];        %@AB@%/* Line number buffer */%@AE@%%@NL@%
  9392.     char                nambuf[LINELEN];%@AB@%/* Name buffer */%@AE@%%@NL@%
  9393. %@NL@%
  9394.     cp = startbuf;                        %@AB@%/* Initialize to start of buffer */%@AE@%%@NL@%
  9395.     lastmatch = cp;                        %@AB@%/* No previous match yet */%@AE@%%@NL@%
  9396.     while((cp = (*find)(cp,endbuf)) != NULL)%@NL@%
  9397.       {                                        %@AB@%/* While matches are found */%@AE@%%@NL@%
  9398.         if((flags & BEGLINE) && cp[-1] != '\n' && cp > startbuf)%@NL@%
  9399.           {                                %@AB@%/* If begin line conditions not met */%@AE@%%@NL@%
  9400.             ++cp;                        %@AB@%/* Skip first char of match */%@AE@%%@NL@%
  9401.             continue;                        %@AB@%/* Keep looking */%@AE@%%@NL@%
  9402.           }%@NL@%
  9403.         status = 0;                        %@AB@%/* Match found */%@AE@%%@NL@%
  9404.         if(flags & NAMEONLY)                %@AB@%/* If filename only wanted */%@AE@%%@NL@%
  9405.           {%@NL@%
  9406.             (*write1)(nambuf,sprintf(nambuf,"%s\r\n",name));%@NL@%
  9407.                                         %@AB@%/* Print the name */%@AE@%%@NL@%
  9408.             return(1);                        %@AB@%/* Punt remainder of buffer */%@AE@%%@NL@%
  9409.           }%@NL@%
  9410.         cp -= revfind(cp,'\n',cp - startbuf);%@NL@%
  9411.                                         %@AB@%/* Point at last linefeed */%@AE@%%@NL@%
  9412.         if(*cp == '\n') ++cp;                %@AB@%/* Point at start of line */%@AE@%%@NL@%
  9413.         if(flags & SHOWNAME)                %@AB@%/* If name wanted */%@AE@%%@NL@%
  9414.           {%@NL@%
  9415.             if(namlen == 0) namlen = sprintf(nambuf,"%s:",name);%@NL@%
  9416.                                         %@AB@%/* Format name if not done already */%@AE@%%@NL@%
  9417.             (*write1)(nambuf,namlen);        %@AB@%/* Show name */%@AE@%%@NL@%
  9418.           }%@NL@%
  9419.         if(flags & LINENOS)                %@AB@%/* If line number wanted */%@AE@%%@NL@%
  9420.           {%@NL@%
  9421.             lineno += countlines(lastmatch,cp);%@NL@%
  9422.                                         %@AB@%/* Count lines since last match */%@AE@%%@NL@%
  9423.             (*write1)(lnobuf,sprintf(lnobuf,"%d:",lineno));%@NL@%
  9424.                                         %@AB@%/* Print line number */%@AE@%%@NL@%
  9425.             lastmatch = cp;                %@AB@%/* New last match */%@AE@%%@NL@%
  9426.           }%@NL@%
  9427.         linelen = strncspn(cp,"\n",endbuf - cp) + 1;%@NL@%
  9428.                                         %@AB@%/* Calculate line length */%@AE@%%@NL@%
  9429.         (*write1)(cp,linelen);                %@AB@%/* Print the line */%@AE@%%@NL@%
  9430.         cp += linelen;                        %@AB@%/* Skip the line */%@AE@%%@NL@%
  9431.       }%@NL@%
  9432.     if(flags & LINENOS) lineno += countlines(lastmatch,endbuf);%@NL@%
  9433.                                         %@AB@%/* Count remaining lines in buffer */%@AE@%%@NL@%
  9434.     return(0);                                %@AB@%/* Keep searching */%@AE@%%@NL@%
  9435.   }%@NL@%
  9436. %@NL@%
  9437. %@NL@%
  9438. void                        showv(name,lastmatch,thismatch)%@NL@%
  9439. char                        *name;%@NL@%
  9440. register char                *lastmatch;%@NL@%
  9441. char                        *thismatch;%@NL@%
  9442.   {%@NL@%
  9443.     register int        linelen;%@NL@%
  9444.     int                        namlen = 0;        %@AB@%/* Length of name */%@AE@%%@NL@%
  9445.     char                lnobuf[LNOLEN];        %@AB@%/* Line number buffer */%@AE@%%@NL@%
  9446.     char                nambuf[LINELEN];%@AB@%/* Name buffer */%@AE@%%@NL@%
  9447. %@NL@%
  9448.     if(flags & (SHOWNAME | LINENOS))%@NL@%
  9449.       {%@NL@%
  9450.         while(lastmatch < thismatch)%@NL@%
  9451.           {%@NL@%
  9452.             if(flags & SHOWNAME)        %@AB@%/* If name wanted */%@AE@%%@NL@%
  9453.               {%@NL@%
  9454.                 if(namlen == 0) namlen = sprintf(nambuf,"%s:",name);%@NL@%
  9455.                                         %@AB@%/* Format name if not done already */%@AE@%%@NL@%
  9456.                 (*write1)(nambuf,namlen);%@NL@%
  9457.                                         %@AB@%/* Write the name */%@AE@%%@NL@%
  9458.               }%@NL@%
  9459.             if(flags & LINENOS)%@NL@%
  9460.               {%@NL@%
  9461.                 (*write1)(lnobuf,sprintf(lnobuf,"%d:",lineno++));%@NL@%
  9462.               }%@NL@%
  9463.             linelen = strncspn(lastmatch,"\n",thismatch - lastmatch) + 1;%@NL@%
  9464.             (*write1)(lastmatch,linelen);%@NL@%
  9465.             lastmatch += linelen;%@NL@%
  9466.           }%@NL@%
  9467.       }%@NL@%
  9468.     else (*write1)(lastmatch,thismatch - lastmatch);%@NL@%
  9469.   }%@NL@%
  9470. %@NL@%
  9471. %@NL@%
  9472. int                        grepvbuffer(startbuf,endbuf,name)%@NL@%
  9473. char                        *startbuf;        %@AB@%/* Start of buffer */%@AE@%%@NL@%
  9474. char                        *endbuf;        %@AB@%/* End of buffer */%@AE@%%@NL@%
  9475. char                        *name;                %@AB@%/* File name */%@AE@%%@NL@%
  9476.   {%@NL@%
  9477.     register char        *cp;                %@AB@%/* Buffer pointer */%@AE@%%@NL@%
  9478.     register char        *lastmatch;        %@AB@%/* Pointer to line after last match */%@AE@%%@NL@%
  9479. %@NL@%
  9480.     cp = startbuf;                        %@AB@%/* Initialize to start of buffer */%@AE@%%@NL@%
  9481.     lastmatch = cp;%@NL@%
  9482.     while((cp = (*find)(cp,endbuf)) != NULL)%@NL@%
  9483.       {%@NL@%
  9484.         if((flags & BEGLINE) && cp[-1] != '\n' && cp > startbuf)%@NL@%
  9485.           {                                %@AB@%/* If begin line conditions not met */%@AE@%%@NL@%
  9486.             ++cp;                        %@AB@%/* Skip first char of match */%@AE@%%@NL@%
  9487.             continue;                        %@AB@%/* Keep looking */%@AE@%%@NL@%
  9488.           }%@NL@%
  9489.         status = 1;                        %@AB@%/* Match found */%@AE@%%@NL@%
  9490.         if(flags & NAMEONLY) return(1);        %@AB@%/* Skip rest of file if NAMEONLY */%@AE@%%@NL@%
  9491.         cp -= revfind(cp,'\n',cp - startbuf);%@NL@%
  9492.                                         %@AB@%/* Point at last linefeed */%@AE@%%@NL@%
  9493.         if(*cp == '\n') ++cp;                %@AB@%/* Point at start of line */%@AE@%%@NL@%
  9494.         showv(name,lastmatch,cp);        %@AB@%/* Show from last match to this */%@AE@%%@NL@%
  9495.         cp += strncspn(cp,"\n",endbuf - cp) + 1;%@NL@%
  9496.                                         %@AB@%/* Skip over line with match */%@AE@%%@NL@%
  9497.         lastmatch = cp;                        %@AB@%/* New "last" match */%@AE@%%@NL@%
  9498.         ++lineno;                        %@AB@%/* Increment line count */%@AE@%%@NL@%
  9499.       }%@NL@%
  9500.     if(!(flags & NAMEONLY)) showv(name,lastmatch,endbuf);%@NL@%
  9501.                                         %@AB@%/* Show buffer tail if not NAMEONLY */%@AE@%%@NL@%
  9502.     return(0);                                %@AB@%/* Keep searching file */%@AE@%%@NL@%
  9503.   }%@NL@%
  9504. %@NL@%
  9505. %@NL@%
  9506. void                        qgrep(name,fd)%@NL@%
  9507. char                        *name;                %@AB@%/* File name */%@AE@%%@NL@%
  9508. HFILE                        fd;                %@AB@%/* File descriptor */%@AE@%%@NL@%
  9509.   {%@NL@%
  9510.     register int        cb;                %@AB@%/* Byte count */%@AE@%%@NL@%
  9511.     register char        *cp;                %@AB@%/* Buffer pointer */%@AE@%%@NL@%
  9512.     char                *endbuf;        %@AB@%/* End of buffer */%@AE@%%@NL@%
  9513.     int                        taillen;        %@AB@%/* Length of buffer tail */%@AE@%%@NL@%
  9514.     int                        bufi;                %@AB@%/* Buffer index */%@AE@%%@NL@%
  9515.     char                line[LINELEN];        %@AB@%/* Line buffer */%@AE@%%@NL@%
  9516. %@NL@%
  9517.     lineno = 1;                                %@AB@%/* File starts on line 1 */%@AE@%%@NL@%
  9518.     taillen = 0;                        %@AB@%/* No buffer tail yet */%@AE@%%@NL@%
  9519.     bufi = 0;                                %@AB@%/* Initialize buffer index */%@AE@%%@NL@%
  9520.     cp = bufptr[0];                        %@AB@%/* Initialize to start of buffer */%@AE@%%@NL@%
  9521.     finishread();                        %@AB@%/* Make sure no I/O activity */%@AE@%%@NL@%
  9522.     arrc = DosRead( fd, cp, FILBUFLEN, &cbread);%@NL@%
  9523.                                         %@AB@%/* Do first read synchronously */%@AE@%%@NL@%
  9524.     while((cb = finishread()) + taillen > 0)%@NL@%
  9525.       {                                        %@AB@%/* While search incomplete */%@AE@%%@NL@%
  9526.         if(cb == 0)                        %@AB@%/* If buffer tail is all that's left */%@AE@%%@NL@%
  9527.           {%@NL@%
  9528.             taillen = 0;                %@AB@%/* Set tail length to zero */%@AE@%%@NL@%
  9529.             *cp++ = '\r';                %@AB@%/* Add end of line sequence */%@AE@%%@NL@%
  9530.             *cp++ = '\n';%@NL@%
  9531.             endbuf = cp;                %@AB@%/* Note end of buffer */%@AE@%%@NL@%
  9532.           }%@NL@%
  9533.         else                                %@AB@%/* Else start next read */%@AE@%%@NL@%
  9534.           {%@NL@%
  9535.             taillen = revfind(cp + cb - 1,'\n',cb);%@NL@%
  9536.                                         %@AB@%/* Find length of partial line */%@AE@%%@NL@%
  9537.             endbuf = cp + cb - taillen;        %@AB@%/* Get pointer to end of buffer */%@AE@%%@NL@%
  9538.             cp = bufptr[bufi ^ 1];        %@AB@%/* Pointer to other buffer */%@AE@%%@NL@%
  9539.             memcpy(cp,endbuf,taillen);        %@AB@%/* Copy tail to head of other buffer */%@AE@%%@NL@%
  9540.             cp += taillen;                %@AB@%/* Skip over tail */%@AE@%%@NL@%
  9541.             startread(fd,cp,(FILBUFLEN - taillen) & (~0 << LG2SECLEN));%@NL@%
  9542.                                         %@AB@%/* Start next read */%@AE@%%@NL@%
  9543.           }%@NL@%
  9544.         if((*grep)(bufptr[bufi],endbuf,name)) return;%@NL@%
  9545.                                         %@AB@%/* Done if NAMEONLY and match found */%@AE@%%@NL@%
  9546.         bufi ^= 1;                        %@AB@%/* Switch buffers */%@AE@%%@NL@%
  9547.       }%@NL@%
  9548.     if((flags & (NAMEONLY | INVERT)) == (NAMEONLY | INVERT))%@NL@%
  9549.       (*write1)(line,sprintf(line,"%s\r\n",name));%@NL@%
  9550.                                         %@AB@%/* Write name if -lv */%@AE@%%@NL@%
  9551.   }%@NL@%
  9552. %@NL@%
  9553. %@NL@%
  9554. void                        usage(verbose)%@NL@%
  9555. int                        verbose;        %@AB@%/* Verbose message flag */%@AE@%%@NL@%
  9556.   {%@NL@%
  9557.     static char                *opts[] =%@NL@%
  9558.       {%@NL@%
  9559.         "-? - print this message",%@NL@%
  9560.         "-B - match pattern if at beginning of line",%@NL@%
  9561.         "-E - match pattern if at end of line",%@NL@%
  9562.         "-l - print only file name if file contains match",%@NL@%
  9563.         "-n - print line number before each matching line",%@NL@%
  9564.         "-v - print only lines not containing a match",%@NL@%
  9565.         "-x - print lines that match exactly (-BE)",%@NL@%
  9566.         "-y - treat upper and lower case as equivalent",%@NL@%
  9567.         "-e - treat next argument as the search string",%@NL@%
  9568.         "-f - read search strings from file named by next argument",%@NL@%
  9569.         "-i - read file list from file named by next argument",%@NL@%
  9570.         0%@NL@%
  9571.       };%@NL@%
  9572.     register char        **opt = opts;        %@AB@%/* Option list */%@AE@%%@NL@%
  9573. %@NL@%
  9574.     fprintf(stderr,"usage: CPGREP [-?BElnvxy][-e][-f <file>][-i <file>][<strings>][<files>]\n");%@NL@%
  9575.     if(verbose)                                %@AB@%/* If verbose message wanted */%@AE@%%@NL@%
  9576.       {%@NL@%
  9577.         while(*opt != 0) fprintf(stderr,"%s\n",*opt++);%@NL@%
  9578.                                         %@AB@%/* Print option list */%@AE@%%@NL@%
  9579.       }%@NL@%
  9580.     DosExit( EXIT_PROCESS, 2);                %@AB@%/* Error exit */%@AE@%%@NL@%
  9581.   }%@NL@%
  9582. %@NL@%
  9583. %@NL@%
  9584. void                        main(argc,argv)%@NL@%
  9585. int                        argc;%@NL@%
  9586. char                        **argv;%@NL@%
  9587.   {%@NL@%
  9588.     register char        *cp;%@NL@%
  9589.     HFILE                fd;%@NL@%
  9590.     FILE                *fi;%@NL@%
  9591.     char                filnam[FILNAMLEN];%@NL@%
  9592.     USHORT                handType;%@NL@%
  9593.     USHORT                handAttrib;%@NL@%
  9594.     int                        i;%@NL@%
  9595.     char                *inpfile = NULL;%@NL@%
  9596.     int                 j;%@NL@%
  9597.     char                *seplist = " \t";%@NL@%
  9598.     int                        strcnt;%@NL@%
  9599.     char                *strfile = NULL;%@NL@%
  9600.     long                start;                %@AB@%/* Start time */%@AE@%%@NL@%
  9601.     int                        (*add)();%@NL@%
  9602.     BYTE                t2stk[2*STKLEN];  %@AB@%/* Read thread stack */%@AE@%%@NL@%
  9603.     BYTE                t3stk[2*STKLEN];  %@AB@%/* Write thread stack */%@AE@%%@NL@%
  9604.     long                time();                %@AB@%/* Time and date in seconds */%@AE@%%@NL@%
  9605. %@NL@%
  9606.     DosGetMachineMode((char far *) &pmode);%@NL@%
  9607.     flags = 0;%@NL@%
  9608.     for(i = 1; i < argc && argv[i][0] == '-'; ++i)%@NL@%
  9609.       {%@NL@%
  9610.         switch(argv[i][1])%@NL@%
  9611.           {%@NL@%
  9612.             case 'f':%@NL@%
  9613.             case 'i':%@NL@%
  9614.               if(i == argc - 1)%@NL@%
  9615.                 {%@NL@%
  9616.                   fprintf(stderr,"File name missing after -%c\n",argv[i][1]);%@NL@%
  9617.                   DosExit( EXIT_PROCESS, 2);%@NL@%
  9618.                 }%@NL@%
  9619.               if(argv[i++][1] == 'i') inpfile = argv[i];%@NL@%
  9620.               else strfile = argv[i];%@NL@%
  9621.               break;%@NL@%
  9622. %@NL@%
  9623.             case '?':%@NL@%
  9624.             case 'B':%@NL@%
  9625.             case 'E':%@NL@%
  9626.             case 'N':%@NL@%
  9627.             case 'S':%@NL@%
  9628.             case 'd':%@NL@%
  9629.             case 'l':%@NL@%
  9630.             case 'n':%@NL@%
  9631.             case 't':%@NL@%
  9632.             case 'v':%@NL@%
  9633.             case 'x':%@NL@%
  9634.             case 'y':%@NL@%
  9635.               for(cp = &argv[i][1]; *cp != '\0'; ++cp)%@NL@%
  9636.                 {%@NL@%
  9637.                   switch(*cp)%@NL@%
  9638.                     {%@NL@%
  9639.                       case '?':%@NL@%
  9640.                         usage(1);        %@AB@%/* Verbose usage message */%@AE@%%@NL@%
  9641. %@NL@%
  9642.                       case 'B':%@NL@%
  9643.                         flags |= BEGLINE;%@NL@%
  9644.                         break;%@NL@%
  9645. %@NL@%
  9646.                       case 'E':%@NL@%
  9647.                         flags |= ENDLINE;%@NL@%
  9648.                         break;%@NL@%
  9649. %@NL@%
  9650.                       case 'N':%@NL@%
  9651.                         grep = grepnull;%@NL@%
  9652.                         break;%@NL@%
  9653. %@NL@%
  9654.                       case 'S':%@NL@%
  9655.                         pmode = 0;        %@AB@%/* Force synchronous I/O */%@AE@%%@NL@%
  9656.                         break;%@NL@%
  9657. %@NL@%
  9658.                       case 'd':%@NL@%
  9659.                         flags |= DEBUG;%@NL@%
  9660.                         break;%@NL@%
  9661. %@NL@%
  9662.                       case 'l':%@NL@%
  9663.                         flags |= NAMEONLY;%@NL@%
  9664.                         break;%@NL@%
  9665. %@NL@%
  9666.                       case 'n':%@NL@%
  9667.                         flags |= LINENOS;%@NL@%
  9668.                         break;%@NL@%
  9669. %@NL@%
  9670.                       case 't':%@NL@%
  9671.                         flags |= TIMER;%@NL@%
  9672.                         break;%@NL@%
  9673. %@NL@%
  9674.                       case 'v':%@NL@%
  9675.                         status = 0;        %@AB@%/* Assume success */%@AE@%%@NL@%
  9676.                         flags |= INVERT;%@NL@%
  9677.                         grep = grepvbuffer;%@NL@%
  9678.                         break;%@NL@%
  9679. %@NL@%
  9680.                       case 'x':%@NL@%
  9681.                         flags |= BEGLINE | ENDLINE;%@NL@%
  9682.                         break;%@NL@%
  9683. %@NL@%
  9684.                       case 'y':%@NL@%
  9685.                         casesen = 0;%@NL@%
  9686.                         break;%@NL@%
  9687. %@NL@%
  9688.                       default:%@NL@%
  9689.                         fprintf(stderr,"-%c ignored\n",*cp);%@NL@%
  9690.                         break;%@NL@%
  9691.                     }%@NL@%
  9692.                 }%@NL@%
  9693.               break;%@NL@%
  9694. %@NL@%
  9695.             case 'e':%@NL@%
  9696.               if(strfile == NULL)%@NL@%
  9697.                 {%@NL@%
  9698.                   ++i;%@NL@%
  9699.                   seplist = "";                %@AB@%/* Allow anything in string */%@AE@%%@NL@%
  9700.                   goto endfor0;%@NL@%
  9701.                 }%@NL@%
  9702.               %@AB@%/* Drop through to "default" */%@AE@%%@NL@%
  9703. %@NL@%
  9704.             default:%@NL@%
  9705.               fprintf(stderr,"%s ignored\n",argv[i]);%@NL@%
  9706.               break;%@NL@%
  9707.           }%@NL@%
  9708.       }%@NL@%
  9709.     endfor0:%@NL@%
  9710. %@NL@%
  9711.     if(i == argc && strfile == NULL) usage(0);%@NL@%
  9712.                                         %@AB@%/* Simple usage message if arg error */%@AE@%%@NL@%
  9713.     if(flags & TIMER) start = time(NULL);%@NL@%
  9714.                                         %@AB@%/* Get start time if timer on */%@AE@%%@NL@%
  9715.     if(pmode)                                %@AB@%/* Initialize semaphores and threads */%@AE@%%@NL@%
  9716.       {%@NL@%
  9717.         TID threadId;%@NL@%
  9718. %@NL@%
  9719.         DosSemClear( &readdone);%@NL@%
  9720.         DosSemClear( &writedone);%@NL@%
  9721.         DosSemSet( &readpending);%@NL@%
  9722.         DosSemSet( &writepending);%@NL@%
  9723.         if(DosCreateThread(thread2, &threadId, t2stk + 2*STKLEN) != 0 ||%@NL@%
  9724.            DosCreateThread(thread3, &threadId, t3stk + 2*STKLEN) != 0)%@NL@%
  9725.           {                                %@AB@%/* If thread creation fails */%@AE@%%@NL@%
  9726.             fprintf(stderr,"Failed to create child threads\n");%@NL@%
  9727.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9728.             DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9729.           }%@NL@%
  9730.       }%@NL@%
  9731.     setmode(fileno(stdout),O_BINARY);%@NL@%
  9732.     add = addplain;                        %@AB@%/* Assume plain string adds */%@AE@%%@NL@%
  9733.     if(strfile != NULL)                        %@AB@%/* If strings from file */%@AE@%%@NL@%
  9734.       {%@NL@%
  9735.         if(!(flags & BEGLINE)) add = addfancy;%@NL@%
  9736.                                         %@AB@%/* Try to add intelligently */%@AE@%%@NL@%
  9737.         if((fd = open(strfile,0)) == -1)%@NL@%
  9738.           {                                %@AB@%/* If open fails */%@AE@%%@NL@%
  9739.             fprintf(stderr,"Cannot read strings from %s\n",strfile);%@NL@%
  9740.             DosExit( EXIT_PROCESS, 2);                          %@AB@%/* Print message and die */%@AE@%%@NL@%
  9741.           }%@NL@%
  9742.         for(cp = filbuf, j = 0; (j = read(fd,cp,FILBUFLEN*2 - j)) > 0; cp += j);%@NL@%
  9743.                                         %@AB@%/* Read strings file into buffer */%@AE@%%@NL@%
  9744.         j = cp - filbuf;                %@AB@%/* Get total length of buffer */%@AE@%%@NL@%
  9745.         close(fd);                        %@AB@%/* Close strings file */%@AE@%%@NL@%
  9746.         filbuf[j] = '\0';                %@AB@%/* Null-terminate the buffer */%@AE@%%@NL@%
  9747.         cp = filbuf;                        %@AB@%/* Set pointer to string list */%@AE@%%@NL@%
  9748.         seplist = "\r\n";                %@AB@%/* Only '\r' and '\n' are separators */%@AE@%%@NL@%
  9749.       }%@NL@%
  9750.     else                                %@AB@%/* Else strings on command line */%@AE@%%@NL@%
  9751.       {%@NL@%
  9752.         cp = argv[i++];                        %@AB@%/* Set pointer to strings */%@AE@%%@NL@%
  9753.         j = strlen(cp);                        %@AB@%/* Get length of strings */%@AE@%%@NL@%
  9754.       }%@NL@%
  9755.     if((strcnt = (*add)(cp,j,seplist)) == 0)%@NL@%
  9756.       {                                        %@AB@%/* If no strings */%@AE@%%@NL@%
  9757.         fprintf(stderr,"No search strings\n");%@NL@%
  9758.         DosExit( EXIT_PROCESS, 2);        %@AB@%/* Print error message and die */%@AE@%%@NL@%
  9759.       }%@NL@%
  9760. %@NL@%
  9761.     %@AB@%/*%@NL@%
  9762. %@AB@%     *  Check type of handle for std. out.%@NL@%
  9763. %@AB@%     */%@AE@%%@NL@%
  9764.     if(DosQHandType(fileno(stdout), &handType, &handAttrib) != 0)%@NL@%
  9765.       {                                        %@AB@%/* If error */%@AE@%%@NL@%
  9766.         fprintf(stderr,"Standard output bad handle\n");%@NL@%
  9767.                                         %@AB@%/* Print error message */%@AE@%%@NL@%
  9768.         DosExit( EXIT_PROCESS, 2);        %@AB@%/* Die */%@AE@%%@NL@%
  9769.       }%@NL@%
  9770.     if(handType != 0 && (handAttrib & ISCOT))%@NL@%
  9771.       {                                 %@AB@%/* If handle is console output */%@AE@%%@NL@%
  9772.         write1 = write1nobuf;                %@AB@%/* Use unbuffered output */%@AE@%%@NL@%
  9773.         flush1 = flush1nobuf;%@NL@%
  9774.       }%@NL@%
  9775. %@NL@%
  9776.     if(strcnt > 1)                        %@AB@%/* If more than one string */%@AE@%%@NL@%
  9777.       {%@NL@%
  9778.         if(flags & DEBUG)                %@AB@%/* Print debug info maybe */%@AE@%%@NL@%
  9779.           {%@NL@%
  9780.             fprintf(stderr,"Here are the strings:\n");%@NL@%
  9781.             dumpstrings();%@NL@%
  9782.           }%@NL@%
  9783.       }%@NL@%
  9784.     else if(casesen) find = findone;        %@AB@%/* Else use findone() */%@AE@%%@NL@%
  9785.     if(inpfile != NULL)                        %@AB@%/* If file list from file */%@AE@%%@NL@%
  9786.       {%@NL@%
  9787.         flags |= SHOWNAME;                %@AB@%/* Always show name of file */%@AE@%%@NL@%
  9788.         if((fi = fopen(inpfile,"r")) == NULL)%@NL@%
  9789.           {                                %@AB@%/* If open fails */%@AE@%%@NL@%
  9790.             fprintf(stderr,"Cannot read file list from %s\r\n",inpfile);%@NL@%
  9791.                                         %@AB@%/* Error message */%@AE@%%@NL@%
  9792.             DosExit( EXIT_PROCESS, 2);        %@AB@%/* Error exit */%@AE@%%@NL@%
  9793.           }%@NL@%
  9794.         while(fgets(filnam,FILNAMLEN,fi) != NULL)%@NL@%
  9795.           {                                %@AB@%/* While there are names */%@AE@%%@NL@%
  9796.             filnam[strcspn(filnam,"\r\n")] = '\0';%@NL@%
  9797.                                         %@AB@%/* Null-terminate the name */%@AE@%%@NL@%
  9798.             if((fd = openfile(filnam)) == -1) continue;%@NL@%
  9799.                                         %@AB@%/* Skip file if it cannot be opened */%@AE@%%@NL@%
  9800.             qgrep(filnam,fd);                %@AB@%/* Do the work */%@AE@%%@NL@%
  9801.             close(fd);                        %@AB@%/* Close the file */%@AE@%%@NL@%
  9802.           }%@NL@%
  9803.         fclose(fi);                        %@AB@%/* Close the list file */%@AE@%%@NL@%
  9804.       }%@NL@%
  9805.     else if(i == argc)%@NL@%
  9806.       {%@NL@%
  9807.         flags &= ~(NAMEONLY | SHOWNAME);%@NL@%
  9808.         setmode(fileno(stdin),O_BINARY);%@NL@%
  9809.         qgrep(NULL,fileno(stdin));%@NL@%
  9810.       }%@NL@%
  9811.     if(argc > i + 1) flags |= SHOWNAME;%@NL@%
  9812.     for(; i < argc; ++i)%@NL@%
  9813.       {%@NL@%
  9814.         if((fd = openfile(argv[i])) == -1) continue;%@NL@%
  9815.         qgrep(argv[i],fd);%@NL@%
  9816.         close(fd);%@NL@%
  9817.       }%@NL@%
  9818.     (*flush1)();%@NL@%
  9819.     if(flags & TIMER) fprintf(stderr,"%ld seconds\n",time(NULL) - start);%@NL@%
  9820.                                         %@AB@%/* Print elapsed time if timer on */%@AE@%%@NL@%
  9821.     DosExit( EXIT_PROCESS, status);%@NL@%
  9822.   }%@NL@%
  9823. %@NL@%
  9824. %@NL@%
  9825. %@2@%%@AH@%CPGREPSB.ASM%@AE@%%@EH@%%@NL@%
  9826. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CPGREP\CPGREPSB.ASM%@AE@%%@NL@%
  9827. %@NL@%
  9828. %@AB@%; Created by Microsoft Corp. 1986%@AE@%%@NL@%
  9829. name cpgrepsub%@NL@%
  9830. %@NL@%
  9831. retlen        equ        2                        %@AB@%; Size of return address on stack%@AE@%%@NL@%
  9832. %@NL@%
  9833. dgroup        group        _data%@NL@%
  9834. %@NL@%
  9835. extrn        _casesen:        word                %@AB@%; Case-sensitivity flag%@AE@%%@NL@%
  9836. extrn        _stringlist:        word                %@AB@%; Table of string lists%@AE@%%@NL@%
  9837. extrn        _target:        byte                %@AB@%; Target string%@AE@%%@NL@%
  9838. extrn        _targetlen:        word                %@AB@%; Length of target string%@AE@%%@NL@%
  9839. extrn        _transtab:        byte                %@AB@%; Translation table for _findlist%@AE@%%@NL@%
  9840. %@NL@%
  9841. %@AB@%;        This segment is puposely word-aligned.  See note%@AE@%%@NL@%
  9842. %@AB@%;        in _findlist below.%@AE@%%@NL@%
  9843. %@NL@%
  9844. _text        segment word public 'code'%@NL@%
  9845.         assume        cs:_text, ds:dgroup, es:nothing, ss:dgroup%@NL@%
  9846. %@NL@%
  9847. %@AB@%; char                        *findone(buffer,bufend)%@AE@%%@NL@%
  9848. %@AB@%; char                        *buffer                /* Buffer in which to search */%@AE@%%@NL@%
  9849. %@AB@%; char                        *bufend;        /* End of buffer */%@AE@%%@NL@%
  9850. %@AB@%;%@AE@%%@NL@%
  9851. %@AB@%; NOTE: targetlen MUST BE greater than zero%@AE@%%@NL@%
  9852. %@NL@%
  9853. buffer        equ        word ptr [bp+retlen+2]%@NL@%
  9854. bufend        equ        word ptr [bp+retlen+4]%@NL@%
  9855. %@NL@%
  9856.         EVEN%@NL@%
  9857. %@NL@%
  9858.         public        _findone%@NL@%
  9859. _findone proc        near%@NL@%
  9860.         push        bp%@NL@%
  9861.         mov        bp,sp%@NL@%
  9862.         push        di%@NL@%
  9863.         push        si%@NL@%
  9864.         push        es%@NL@%
  9865.         push        ds                        %@AB@%; ES = DS%@AE@%%@NL@%
  9866.         pop        es%@NL@%
  9867.         mov        cx,bufend                %@AB@%; CX = end of buffer%@AE@%%@NL@%
  9868.         mov        di,buffer                %@AB@%; ES:DI = buffer%@AE@%%@NL@%
  9869.         sub        cx,di                        %@AB@%; CX = length of buffer%@AE@%%@NL@%
  9870.         jbe        sfnomatch                %@AB@%;  length less than or equal to zero%@AE@%%@NL@%
  9871.         mov        dx,_targetlen                %@AB@%; DX = length of target%@AE@%%@NL@%
  9872.         dec        dx                        %@AB@%; Decrement it%@AE@%%@NL@%
  9873.         sub        cx,dx                        %@AB@%; target must fit in buffer%@AE@%%@NL@%
  9874.         jbe        sfnomatch                %@AB@%;  (no match if buffer too short)%@AE@%%@NL@%
  9875. %@NL@%
  9876. %@AB@%;        CX = buffer length%@AE@%%@NL@%
  9877. %@AB@%;        DX = target length (minus first character)%@AE@%%@NL@%
  9878. %@AB@%;        ES:DI = buffer pointer%@AE@%%@NL@%
  9879. %@NL@%
  9880. sf0:        jcxz        sfnomatch                %@AB@%; No match if count zero%@AE@%%@NL@%
  9881.         mov        si,offset dgroup:_target %@AB@%; DS:SI = target%@AE@%%@NL@%
  9882.         lodsb                                %@AB@%; AL = first byte of target%@AE@%%@NL@%
  9883.         repne scasb                        %@AB@%; Look for first character%@AE@%%@NL@%
  9884.         jne        sfnomatch                %@AB@%;  jump if not found%@AE@%%@NL@%
  9885.         mov        bx,cx                        %@AB@%; BX = buffer length%@AE@%%@NL@%
  9886.         mov        ax,di                        %@AB@%; AX = buffer pointer%@AE@%%@NL@%
  9887.         mov        cx,dx                        %@AB@%; Get count for cmpsb%@AE@%%@NL@%
  9888.         or        cx,cx                        %@AB@%; Zero? (JCXZ doesn't set flag)%@AE@%%@NL@%
  9889.         je        sf1                        %@AB@%;  yes, skip compare%@AE@%%@NL@%
  9890.         repe cmpsb                        %@AB@%; Do string compare%@AE@%%@NL@%
  9891. sf1:        mov        di,ax                        %@AB@%; DI = buffer pointer%@AE@%%@NL@%
  9892.         mov        cx,bx                        %@AB@%; CX = buffer length%@AE@%%@NL@%
  9893.         jne        sf0                        %@AB@%; Loop if no match%@AE@%%@NL@%
  9894.         dec        ax                        %@AB@%; AX = offset of start of match%@AE@%%@NL@%
  9895.         jmp        short sf4%@NL@%
  9896. %@NL@%
  9897. sfnomatch:%@NL@%
  9898.         xor        ax,ax                        %@AB@%; No match%@AE@%%@NL@%
  9899. sf4:        pop        es%@NL@%
  9900.         pop        si%@NL@%
  9901.         pop        di%@NL@%
  9902.         pop        bp%@NL@%
  9903.         ret%@NL@%
  9904. _findone endp%@NL@%
  9905. %@NL@%
  9906. %@NL@%
  9907. %@AB@%; int                        revfind(s,c,slen)%@AE@%%@NL@%
  9908. %@AB@%; char                        *s;                /* String to search */%@AE@%%@NL@%
  9909. %@AB@%; int                        c;                /* Char to search for */%@AE@%%@NL@%
  9910. %@AB@%; int                        slen;                /* Length of s */%@AE@%%@NL@%
  9911. %@NL@%
  9912. s        equ        [bp+retlen+2]%@NL@%
  9913. c        equ        [bp+retlen+4]%@NL@%
  9914. slen        equ        [bp+retlen+6]%@NL@%
  9915. %@NL@%
  9916.         EVEN%@NL@%
  9917. %@NL@%
  9918.         public        _revfind%@NL@%
  9919. _revfind proc        near%@NL@%
  9920.         push        bp%@NL@%
  9921.         mov        bp,sp%@NL@%
  9922.         push        di%@NL@%
  9923.         push        es%@NL@%
  9924.         push        ds%@NL@%
  9925.         pop        es%@NL@%
  9926.         mov        di,s%@NL@%
  9927.         mov        ax,c%@NL@%
  9928.         mov        cx,slen%@NL@%
  9929.         jcxz        rf1%@NL@%
  9930.         std%@NL@%
  9931.         repne scasb%@NL@%
  9932.         cld%@NL@%
  9933.         mov        cx,s%@NL@%
  9934.         jne        rf0%@NL@%
  9935.         inc        di%@NL@%
  9936. rf0:        sub        cx,di%@NL@%
  9937. rf1:        mov        ax,cx%@NL@%
  9938.         pop        es%@NL@%
  9939.         pop        di%@NL@%
  9940.         pop        bp%@NL@%
  9941.         ret%@NL@%
  9942. _revfind endp%@NL@%
  9943. %@NL@%
  9944. %@NL@%
  9945. %@AB@%; int                        countlines(start,finish)%@AE@%%@NL@%
  9946. %@AB@%; char                        *start;%@AE@%%@NL@%
  9947. %@AB@%; char                        *finish;%@AE@%%@NL@%
  9948. %@NL@%
  9949. start        equ        [bp+retlen+2]%@NL@%
  9950. finish        equ        [bp+retlen+4]%@NL@%
  9951. %@NL@%
  9952.         EVEN%@NL@%
  9953. %@NL@%
  9954.         public        _countlines%@NL@%
  9955. _countlines proc near%@NL@%
  9956.         push        bp%@NL@%
  9957.         mov        bp,sp%@NL@%
  9958.         push        di%@NL@%
  9959.         push        es%@NL@%
  9960.         push        ds%@NL@%
  9961.         pop        es%@NL@%
  9962.         xor        dx,dx                        %@AB@%; Accumulate count in DX%@AE@%%@NL@%
  9963.         mov        di,start                %@AB@%; ES:DI points to start%@AE@%%@NL@%
  9964.         mov        cx,finish                %@AB@%; Put length in CX%@AE@%%@NL@%
  9965.         sub        cx,di%@NL@%
  9966.         jbe        cl1                        %@AB@%;  branch if no bytes%@AE@%%@NL@%
  9967.         mov        al,0Ah                        %@AB@%; Search for linefeeds%@AE@%%@NL@%
  9968. cl0:        jcxz        cl1                        %@AB@%; Exit loop if count zero%@AE@%%@NL@%
  9969.         repne scasb                        %@AB@%; Do search%@AE@%%@NL@%
  9970.         jne        cl1                        %@AB@%;  branch if none found%@AE@%%@NL@%
  9971.         inc        dx                        %@AB@%; Increment count%@AE@%%@NL@%
  9972.         jmp        short cl0                %@AB@%; Loop%@AE@%%@NL@%
  9973. cl1:        mov        ax,dx                        %@AB@%; Return line count in AX%@AE@%%@NL@%
  9974.         pop        es%@NL@%
  9975.         pop        di%@NL@%
  9976.         pop        bp%@NL@%
  9977.         ret%@NL@%
  9978. _countlines endp%@NL@%
  9979. %@NL@%
  9980. %@NL@%
  9981. %@AB@%; char                        *findlist(buffer,bufend)%@AE@%%@NL@%
  9982. %@AB@%; char                        *buffer;        /* Buffer to search */%@AE@%%@NL@%
  9983. %@AB@%; char                        *bufend;        /* End of buffer */%@AE@%%@NL@%
  9984. %@NL@%
  9985. savesi        equ        word ptr [bp-2]%@NL@%
  9986. endbyte        equ        byte ptr [bp-4]%@NL@%
  9987. %@NL@%
  9988. stringnode struc%@NL@%
  9989.         s_alt        dw        ?                %@AB@%; List of alternate portions%@AE@%%@NL@%
  9990.         s_suf        dw        ?                %@AB@%; Pointer to suffix string list%@AE@%%@NL@%
  9991.         s_must        dw        ?                %@AB@%; Length of portion that must match%@AE@%%@NL@%
  9992. stringnode ends%@NL@%
  9993. %@NL@%
  9994.         EVEN%@NL@%
  9995. %@NL@%
  9996. flworker dw        findsubi, findsub        %@AB@%; Worker dispatch table%@AE@%%@NL@%
  9997. %@NL@%
  9998.         public        _findlist%@NL@%
  9999. _findlist proc        near%@NL@%
  10000.         ASSUME        DS:DGROUP, ES:NOTHING, SS:DGROUP%@NL@%
  10001. %@NL@%
  10002.         push        bp%@NL@%
  10003.         mov        bp,sp%@NL@%
  10004.         sub        sp,4                        %@AB@%; Make room for local vars%@AE@%%@NL@%
  10005.         push        di%@NL@%
  10006.         push        si%@NL@%
  10007.         push        ds%@NL@%
  10008.         pop        es%@NL@%
  10009.     ASSUME        ES:DGROUP%@NL@%
  10010. %@NL@%
  10011. %@AB@%;        We mark the end of our search buffer with 0FFh so that%@AE@%%@NL@%
  10012. %@AB@%;        any comparisons that might run past the end of the buffer%@AE@%%@NL@%
  10013. %@AB@%;        will fail on the 0FFh.  We choose 0FFh so that if the%@AE@%%@NL@%
  10014. %@AB@%;        comparison fails on it, it will always appear as though%@AE@%%@NL@%
  10015. %@AB@%;        the string in the buffer is greater that the string in%@AE@%%@NL@%
  10016. %@AB@%;        the search list.  This will prevent us from stopping%@AE@%%@NL@%
  10017. %@AB@%;        the search too soon.  Of course, we must restore the byte%@AE@%%@NL@%
  10018. %@AB@%;        when we're done.%@AE@%%@NL@%
  10019. %@NL@%
  10020.         mov        bx,bufend                %@AB@%; BX = end of buffer%@AE@%%@NL@%
  10021.         mov        al,0FFh                        %@AB@%; End marker%@AE@%%@NL@%
  10022.         xchg        byte ptr [bx],al        %@AB@%; AL = byte after end of buffer%@AE@%%@NL@%
  10023.         mov        endbyte,al                %@AB@%; Save the byte%@AE@%%@NL@%
  10024. %@NL@%
  10025.         mov        cx,bx                        %@AB@%; CX = end of buffer%@AE@%%@NL@%
  10026.         mov        si,buffer                %@AB@%; SI = buffer%@AE@%%@NL@%
  10027.         sub        cx,si                        %@AB@%; CX = buffer length%@AE@%%@NL@%
  10028.         jbe        fl1                        %@AB@%;  no match if empty buffer%@AE@%%@NL@%
  10029.         mov        bx,offset dgroup:_transtab %@AB@%; BX = translation table address%@AE@%%@NL@%
  10030. %@NL@%
  10031.         mov        di,_casesen                %@AB@%; Get flag%@AE@%%@NL@%
  10032.         shl        di,1                        %@AB@%; Scale to word index%@AE@%%@NL@%
  10033.         call        cs:flworker[di]                %@AB@%; Call helper%@AE@%%@NL@%
  10034.         jc        fl1                        %@AB@%;  branch if no match%@AE@%%@NL@%
  10035. %@NL@%
  10036. %@AB@%;        We have a match%@AE@%%@NL@%
  10037. %@AB@%;%@AE@%%@NL@%
  10038. %@AB@%;        SI = offset of first character past end of matched string%@AE@%%@NL@%
  10039. %@AB@%;        savesi = offset of first character past start of matched string%@AE@%%@NL@%
  10040. %@NL@%
  10041.         mov        ax,savesi                %@AB@%; AX = 1st char past start%@AE@%%@NL@%
  10042.         dec        ax                        %@AB@%; AX = start of matched string%@AE@%%@NL@%
  10043.         jmp        short fl2%@NL@%
  10044. %@NL@%
  10045. %@AB@%;        We did not find a match%@AE@%%@NL@%
  10046. %@NL@%
  10047. fl1:%@NL@%
  10048.         xor        ax,ax                        %@AB@%; Return NULL%@AE@%%@NL@%
  10049. %@NL@%
  10050. %@AB@%;        Restore end byte before leaving%@AE@%%@NL@%
  10051. %@NL@%
  10052. fl2:%@NL@%
  10053.         mov        bx,bufend                %@AB@%; BX = end of buffer%@AE@%%@NL@%
  10054.         mov        dl,endbyte                %@AB@%; DL = end byte%@AE@%%@NL@%
  10055.         mov        [bx],dl                        %@AB@%; Restore byte%@AE@%%@NL@%
  10056. %@NL@%
  10057.         pop        si%@NL@%
  10058.         pop        di%@NL@%
  10059.         mov        sp,bp%@NL@%
  10060.         pop        bp%@NL@%
  10061.         ret%@NL@%
  10062. %@NL@%
  10063. _findlist endp%@NL@%
  10064. %@NL@%
  10065. %@NL@%
  10066. %@AB@%;***        findsub - case-sensitive worker for _findlist%@AE@%%@NL@%
  10067. %@AB@%;%@AE@%%@NL@%
  10068. %@AB@%;        This function does most of the work for%@AE@%%@NL@%
  10069. %@AB@%;        case-sensitive multi-string searches.%@AE@%%@NL@%
  10070. %@AB@%;%@AE@%%@NL@%
  10071. %@AB@%;        ENTRY        BX = address of translation table%@AE@%%@NL@%
  10072. %@AB@%;                CX = number of bytes left in buffer%@AE@%%@NL@%
  10073. %@AB@%;                DS:SI = buffer pointer%@AE@%%@NL@%
  10074. %@AB@%;                SS:BP = pointer to stack frame for _findlist%@AE@%%@NL@%
  10075. %@AB@%;        EXIT        Carry set%@AE@%%@NL@%
  10076. %@AB@%;                    No match%@AE@%%@NL@%
  10077. %@AB@%;                Carry clear%@AE@%%@NL@%
  10078. %@AB@%;                    DS:SI = pointer to first character after match%@AE@%%@NL@%
  10079. %@AB@%;        USES        AX, CX, DX, DI, SI, Flags%@AE@%%@NL@%
  10080. %@NL@%
  10081.         EVEN%@NL@%
  10082. %@NL@%
  10083.         public        findsub, fs0, fs1, fs2, fs3, fs4, fs5, fs6%@NL@%
  10084. findsub        proc        near%@NL@%
  10085.         ASSUME        DS:DGROUP, ES:DGROUP, SS:DGROUP%@NL@%
  10086. %@NL@%
  10087. fs0:%@NL@%
  10088.         xor        ax,ax                        %@AB@%; AH = 0%@AE@%%@NL@%
  10089. %@NL@%
  10090. %@AB@%;        AH = 0%@AE@%%@NL@%
  10091. %@AB@%;        BX = address of translation table%@AE@%%@NL@%
  10092. %@AB@%;        CX = number of bytes left in buffer%@AE@%%@NL@%
  10093. %@AB@%;        SI = buffer pointer%@AE@%%@NL@%
  10094. %@AB@%;        DS = ES = SS = DGROUP%@AE@%%@NL@%
  10095. %@NL@%
  10096. fs1:%@NL@%
  10097.         lodsb                                %@AB@%; Character in AL%@AE@%%@NL@%
  10098.         xlat byte ptr [bx]                %@AB@%; Translate character to index%@AE@%%@NL@%
  10099.         or        al,al                        %@AB@%; Zero means invalid 1st byte%@AE@%%@NL@%
  10100.         loopz        fs1                        %@AB@%;  if so, try next character%@AE@%%@NL@%
  10101. %@NL@%
  10102. %@AB@%;        Either the zero bit is set, meaning the buffer is empty,%@AE@%%@NL@%
  10103. %@AB@%;        or the zero bit is clear, meaning we have a valid first%@AE@%%@NL@%
  10104. %@AB@%;        character.  Either way, CX has been decremented.%@AE@%%@NL@%
  10105. %@NL@%
  10106.         jz        fs6                        %@AB@%;  branch if buffer empty%@AE@%%@NL@%
  10107.         mov        savesi,si                %@AB@%; Save buffer pointer%@AE@%%@NL@%
  10108.         shl        ax,1                        %@AB@%; Scale to word index%@AE@%%@NL@%
  10109.         mov        di,ax%@NL@%
  10110.         mov        di,_stringlist[di]        %@AB@%; DI points to string record%@AE@%%@NL@%
  10111.         or        di,di                        %@AB@%; One byte match? (OR clears carry)%@AE@%%@NL@%
  10112.         jz        fs3                        %@AB@%;  yes, skip ahead%@AE@%%@NL@%
  10113. %@NL@%
  10114. %@AB@%;        Loop to search for match.%@AE@%%@NL@%
  10115. %@AB@%;        BX = address of translation table%@AE@%%@NL@%
  10116. %@AB@%;        DI = pointer to string record%@AE@%%@NL@%
  10117. %@AB@%;        SI = pointer into buffer%@AE@%%@NL@%
  10118. %@NL@%
  10119. fs2:%@NL@%
  10120.         mov        cx,[di].s_must                %@AB@%; CX = length of string%@AE@%%@NL@%
  10121.         sub        di,cx                        %@AB@%; DI = pointer to string%@AE@%%@NL@%
  10122.         mov        dx,si                        %@AB@%; Save pointer to start of suffix%@AE@%%@NL@%
  10123.         repe cmpsb                        %@AB@%; Strings match?%@AE@%%@NL@%
  10124.         ja        fs4                        %@AB@%;  no, try alternate if follows%@AE@%%@NL@%
  10125.         jb        fs5                        %@AB@%;  no, cannot be in this list%@AE@%%@NL@%
  10126.         add        di,cx                        %@AB@%; DI = pointer to string record%@AE@%%@NL@%
  10127.         mov        di,[di].s_suf                %@AB@%; Get pointer to suffix string list%@AE@%%@NL@%
  10128.         or        di,di                        %@AB@%; Is there one? (OR clears carry)%@AE@%%@NL@%
  10129.         jnz        fs2                        %@AB@%;  yes, keep looking%@AE@%%@NL@%
  10130. %@NL@%
  10131. %@AB@%;        Match found%@AE@%%@NL@%
  10132. %@NL@%
  10133. fs3:%@NL@%
  10134.         ret                                %@AB@%;  no, we have a match%@AE@%%@NL@%
  10135. %@NL@%
  10136. %@AB@%;        Try alternate suffix%@AE@%%@NL@%
  10137. %@NL@%
  10138. fs4:%@NL@%
  10139.         add        di,cx                        %@AB@%; DI = pointer to string record%@AE@%%@NL@%
  10140.         mov        di,[di].s_alt                %@AB@%; Get pointer to alternate%@AE@%%@NL@%
  10141.         mov        si,dx                        %@AB@%; Restore SI to start of suffix%@AE@%%@NL@%
  10142.         or        di,di                        %@AB@%; Is there one?%@AE@%%@NL@%
  10143.         jnz        fs2                        %@AB@%;  yes, loop%@AE@%%@NL@%
  10144. %@NL@%
  10145. %@AB@%;        Try new first character%@AE@%%@NL@%
  10146. %@NL@%
  10147. fs5:%@NL@%
  10148.         mov        cx,bufend                %@AB@%; CX = end of buffer%@AE@%%@NL@%
  10149.         mov        si,savesi                %@AB@%; Restore SI to saved value%@AE@%%@NL@%
  10150.         sub        cx,si                        %@AB@%; CX = length of buffer%@AE@%%@NL@%
  10151.         ja        short fs0                %@AB@%; Try next character in buffer%@AE@%%@NL@%
  10152. %@NL@%
  10153. %@AB@%;        No match%@AE@%%@NL@%
  10154. %@NL@%
  10155. fs6:%@NL@%
  10156.         stc                                %@AB@%; No match%@AE@%%@NL@%
  10157.         ret%@NL@%
  10158. %@NL@%
  10159. findsub        endp%@NL@%
  10160. %@NL@%
  10161. %@NL@%
  10162. %@AB@%;***        findsubi - case-insensitive worker for _findlist%@AE@%%@NL@%
  10163. %@AB@%;%@AE@%%@NL@%
  10164. %@AB@%;        This function does most of the work for%@AE@%%@NL@%
  10165. %@AB@%;        case-insensitive multi-string searches.%@AE@%%@NL@%
  10166. %@AB@%;%@AE@%%@NL@%
  10167. %@AB@%;        ENTRY        BX = address of translation table%@AE@%%@NL@%
  10168. %@AB@%;                CX = number of bytes left in buffer%@AE@%%@NL@%
  10169. %@AB@%;                DS:SI = buffer pointer%@AE@%%@NL@%
  10170. %@AB@%;                SS:BP = pointer to stack frame for _findlist%@AE@%%@NL@%
  10171. %@AB@%;        EXIT        Carry set%@AE@%%@NL@%
  10172. %@AB@%;                    No match%@AE@%%@NL@%
  10173. %@AB@%;                Carry clear%@AE@%%@NL@%
  10174. %@AB@%;                    DS:SI = pointer to first character after match%@AE@%%@NL@%
  10175. %@AB@%;        USES        AX, CX, DX, DI, SI, Flags%@AE@%%@NL@%
  10176. %@NL@%
  10177.         EVEN%@NL@%
  10178. %@NL@%
  10179.         public        findsubi%@NL@%
  10180. findsubi proc        near%@NL@%
  10181.         ASSUME        DS:DGROUP, ES:DGROUP, SS:DGROUP%@NL@%
  10182. %@NL@%
  10183. fsi0:%@NL@%
  10184.         xor        ax,ax                        %@AB@%; AH = 0%@AE@%%@NL@%
  10185. %@NL@%
  10186. %@AB@%;        AH = 0%@AE@%%@NL@%
  10187. %@AB@%;        BX = address of translation table%@AE@%%@NL@%
  10188. %@AB@%;        CX = number of bytes left in buffer%@AE@%%@NL@%
  10189. %@AB@%;        SI = buffer pointer%@AE@%%@NL@%
  10190. %@AB@%;        DS = ES = SS = DGROUP%@AE@%%@NL@%
  10191. %@NL@%
  10192. fsi1:%@NL@%
  10193.         lodsb                                %@AB@%; Character in AL%@AE@%%@NL@%
  10194.         xlat byte ptr [bx]                %@AB@%; Translate character to index%@AE@%%@NL@%
  10195.         or        al,al                        %@AB@%; Zero means invalid 1st byte%@AE@%%@NL@%
  10196.         loopz        fsi1                        %@AB@%;  if so, try next character%@AE@%%@NL@%
  10197. %@NL@%
  10198. %@AB@%;        Either the zero bit is set, meaning the buffer is empty,%@AE@%%@NL@%
  10199. %@AB@%;        or the zero bit is clear, meaning we have a valid first%@AE@%%@NL@%
  10200. %@AB@%;        character.  Either way, CX has been decremented.%@AE@%%@NL@%
  10201. %@NL@%
  10202.         jz        fsi7                        %@AB@%;  branch if buffer empty%@AE@%%@NL@%
  10203.         mov        savesi,si                %@AB@%; Save buffer pointer%@AE@%%@NL@%
  10204.         shl        ax,1                        %@AB@%; Scale to word index%@AE@%%@NL@%
  10205.         mov        di,ax%@NL@%
  10206.         mov        di,_stringlist[di]        %@AB@%; DI points to string record%@AE@%%@NL@%
  10207.         or        di,di                        %@AB@%; One byte match? (OR clears carry)%@AE@%%@NL@%
  10208.         jz        fsi4                        %@AB@%;  yes, skip ahead%@AE@%%@NL@%
  10209. %@NL@%
  10210. %@AB@%;        Loop to search for match.%@AE@%%@NL@%
  10211. %@AB@%;        BX = address of translation table%@AE@%%@NL@%
  10212. %@AB@%;        DI = pointer to string record%@AE@%%@NL@%
  10213. %@AB@%;        SI = pointer into buffer%@AE@%%@NL@%
  10214. %@NL@%
  10215. fsi2:%@NL@%
  10216.         mov        cx,[di].s_must                %@AB@%; CX = length of string%@AE@%%@NL@%
  10217.         sub        di,cx                        %@AB@%; DI = pointer to string%@AE@%%@NL@%
  10218.         mov        dx,si                        %@AB@%; Save pointer to start of suffix%@AE@%%@NL@%
  10219. fsi3:        lodsb                                %@AB@%; Byte in AL, SI = SI + 1%@AE@%%@NL@%
  10220.         mov        ah,[di]                        %@AB@%; Byte in AH, DI = DI + 1%@AE@%%@NL@%
  10221.         inc        di%@NL@%
  10222.         or        ax,2020h                %@AB@%; Fold bytes onto lower case%@AE@%%@NL@%
  10223.         cmp        al,ah                        %@AB@%; Compare bytes%@AE@%%@NL@%
  10224.         loope        fsi3                        %@AB@%; Loop while same%@AE@%%@NL@%
  10225.         ja        fsi5                        %@AB@%;  no, try alternate if follows%@AE@%%@NL@%
  10226.         jb        fsi6                        %@AB@%;  no, cannot be in this list%@AE@%%@NL@%
  10227.         add        di,cx                        %@AB@%; DI = pointer to string record%@AE@%%@NL@%
  10228.         mov        di,[di].s_suf                %@AB@%; Get pointer to suffix string list%@AE@%%@NL@%
  10229.         or        di,di                        %@AB@%; Is there one? (OR clears carry)%@AE@%%@NL@%
  10230.         jnz        fsi2                        %@AB@%;  yes, keep looking%@AE@%%@NL@%
  10231. %@NL@%
  10232. %@AB@%;        Match found%@AE@%%@NL@%
  10233. %@NL@%
  10234. fsi4:%@NL@%
  10235.         ret                                %@AB@%;  no, we have a match%@AE@%%@NL@%
  10236. %@NL@%
  10237. %@AB@%;        Try alternate suffix%@AE@%%@NL@%
  10238. %@NL@%
  10239. fsi5:%@NL@%
  10240.         add        di,cx                        %@AB@%; DI = pointer to string record%@AE@%%@NL@%
  10241.         mov        di,[di].s_alt                %@AB@%; Get pointer to alternate%@AE@%%@NL@%
  10242.         mov        si,dx                        %@AB@%; Restore SI to start of suffix%@AE@%%@NL@%
  10243.         or        di,di                        %@AB@%; Is there one?%@AE@%%@NL@%
  10244.         jnz        fsi2                        %@AB@%;  yes, loop%@AE@%%@NL@%
  10245. %@NL@%
  10246. %@AB@%;        Try new first character%@AE@%%@NL@%
  10247. %@NL@%
  10248. fsi6:%@NL@%
  10249.         mov        cx,bufend                %@AB@%; CX = end of buffer%@AE@%%@NL@%
  10250.         mov        si,savesi                %@AB@%; Restore SI to saved value%@AE@%%@NL@%
  10251.         sub        cx,si                        %@AB@%; CX = length of buffer%@AE@%%@NL@%
  10252.         ja        short fsi0                %@AB@%; Try next character in buffer%@AE@%%@NL@%
  10253. %@NL@%
  10254. %@AB@%;        No match%@AE@%%@NL@%
  10255. %@NL@%
  10256. fsi7:%@NL@%
  10257.         stc                                %@AB@%; No match%@AE@%%@NL@%
  10258.         ret%@NL@%
  10259. %@NL@%
  10260. findsubi endp%@NL@%
  10261. %@NL@%
  10262. %@NL@%
  10263. %@AB@%; int                        strnspn(s,t,n)%@AE@%%@NL@%
  10264. %@AB@%; char                        *s;                /* String to search */%@AE@%%@NL@%
  10265. %@AB@%; char                        *t;                /* Target list */%@AE@%%@NL@%
  10266. %@AB@%; int                        n;                /* Length of s */%@AE@%%@NL@%
  10267. %@NL@%
  10268. s        equ        word ptr [bp+retlen+2]%@NL@%
  10269. t        equ        word ptr [bp+retlen+4]%@NL@%
  10270. n        equ        word ptr [bp+retlen+6]%@NL@%
  10271. %@NL@%
  10272.         EVEN%@NL@%
  10273. %@NL@%
  10274.         public        _strnspn%@NL@%
  10275. _strnspn proc        near%@NL@%
  10276.         push        bp%@NL@%
  10277.         mov        bp,sp%@NL@%
  10278.         push        di%@NL@%
  10279.         push        si%@NL@%
  10280.         push        ds%@NL@%
  10281.         pop        es%@NL@%
  10282.         cld%@NL@%
  10283.         mov        bx,t                        %@AB@%; BX = t%@AE@%%@NL@%
  10284.         mov        di,bx                        %@AB@%; DI = t%@AE@%%@NL@%
  10285.         xor        al,al                        %@AB@%; Search for 0 byte%@AE@%%@NL@%
  10286.         mov        cx,0FFFFh%@NL@%
  10287.         repne scasb%@NL@%
  10288.         dec        di                        %@AB@%; Back up to 0%@AE@%%@NL@%
  10289.         sub        di,bx                        %@AB@%; DI = length of t%@AE@%%@NL@%
  10290.         jz        spn1                        %@AB@%; Done if length of t is 0%@AE@%%@NL@%
  10291.         mov        dx,di                        %@AB@%; DX = length of t%@AE@%%@NL@%
  10292.         mov        si,s                        %@AB@%; SI = s%@AE@%%@NL@%
  10293.         mov        cx,n                        %@AB@%; CX = length of s%@AE@%%@NL@%
  10294.         jcxz        spn1                        %@AB@%; Check for null string%@AE@%%@NL@%
  10295.         push        bp%@NL@%
  10296. spn0:        lodsb                                %@AB@%; AL = next char in s%@AE@%%@NL@%
  10297.         mov        bp,cx                        %@AB@%; BP = length of s%@AE@%%@NL@%
  10298.         mov        cx,dx                        %@AB@%; CX = length of t%@AE@%%@NL@%
  10299.         mov        di,bx                        %@AB@%; DI = t%@AE@%%@NL@%
  10300.         repne scasb                        %@AB@%; Scan until match found%@AE@%%@NL@%
  10301.         mov        cx,bp                        %@AB@%; CX = length of s%@AE@%%@NL@%
  10302.         loope        spn0                        %@AB@%; Loop if match found%@AE@%%@NL@%
  10303.         pop        bp%@NL@%
  10304.         je        spn1                        %@AB@%; Skip ahead if end of s reached%@AE@%%@NL@%
  10305.         dec        si                        %@AB@%; Back up one char%@AE@%%@NL@%
  10306. spn1:        sub        si,s                        %@AB@%; SI = length of prefix%@AE@%%@NL@%
  10307.         mov        ax,si                        %@AB@%; AX = length of prefix%@AE@%%@NL@%
  10308.         pop        si%@NL@%
  10309.         pop        di%@NL@%
  10310.         pop        bp%@NL@%
  10311.         ret%@NL@%
  10312. _strnspn endp%@NL@%
  10313. %@NL@%
  10314. %@NL@%
  10315. %@AB@%; int                        strncspn(s,t,n)%@AE@%%@NL@%
  10316. %@AB@%; char                        *s;                /* String to search */%@AE@%%@NL@%
  10317. %@AB@%; char                        *t;                /* Target list */%@AE@%%@NL@%
  10318. %@AB@%; int                        n;                /* Length of s */%@AE@%%@NL@%
  10319. %@NL@%
  10320.         EVEN%@NL@%
  10321. %@NL@%
  10322.         public        _strncspn%@NL@%
  10323. _strncspn proc        near%@NL@%
  10324.         push        bp%@NL@%
  10325.         mov        bp,sp%@NL@%
  10326.         push        di%@NL@%
  10327.         push        si%@NL@%
  10328.         push        ds%@NL@%
  10329.         pop        es%@NL@%
  10330.         cld%@NL@%
  10331.         mov        bx,t                        %@AB@%; BX = t%@AE@%%@NL@%
  10332.         mov        di,bx                        %@AB@%; DI = t%@AE@%%@NL@%
  10333.         xor        al,al                        %@AB@%; Search for 0 byte%@AE@%%@NL@%
  10334.         mov        cx,0FFFFh%@NL@%
  10335.         repne scasb%@NL@%
  10336.         dec        di                        %@AB@%; Back up to 0%@AE@%%@NL@%
  10337.         sub        di,bx                        %@AB@%; DI = length of t%@AE@%%@NL@%
  10338.         mov        ax,n                        %@AB@%; Assume length of t is 0%@AE@%%@NL@%
  10339.         jz        cspn2                        %@AB@%; Done if length of t is 0%@AE@%%@NL@%
  10340.         mov        dx,di                        %@AB@%; DX = length of t%@AE@%%@NL@%
  10341.         mov        si,s                        %@AB@%; SI = s%@AE@%%@NL@%
  10342.         mov        cx,ax                        %@AB@%; CX = length of s%@AE@%%@NL@%
  10343.         jcxz        cspn1                        %@AB@%; Check for null string%@AE@%%@NL@%
  10344.         push        bp%@NL@%
  10345. cspn0:        lodsb                                %@AB@%; AL = next char in s%@AE@%%@NL@%
  10346.         mov        bp,cx                        %@AB@%; BP = length of s%@AE@%%@NL@%
  10347.         mov        cx,dx                        %@AB@%; CX = length of t%@AE@%%@NL@%
  10348.         mov        di,bx                        %@AB@%; DI = t%@AE@%%@NL@%
  10349.         repne scasb                        %@AB@%; Scan until match found%@AE@%%@NL@%
  10350.         mov        cx,bp                        %@AB@%; CX = length of s%@AE@%%@NL@%
  10351.         loopne        cspn0                        %@AB@%; Loop if match not found%@AE@%%@NL@%
  10352.         pop        bp%@NL@%
  10353.         jne        cspn1                        %@AB@%; Skip ahead if end of s reached%@AE@%%@NL@%
  10354.         dec        si                        %@AB@%; Back up one char%@AE@%%@NL@%
  10355. cspn1:        sub        si,s                        %@AB@%; SI = length of prefix%@AE@%%@NL@%
  10356.         mov        ax,si                        %@AB@%; AX = length of prefix%@AE@%%@NL@%
  10357. cspn2:        pop        si%@NL@%
  10358.         pop        di%@NL@%
  10359.         pop        bp%@NL@%
  10360.         ret%@NL@%
  10361. _strncspn endp%@NL@%
  10362. %@NL@%
  10363. %@NL@%
  10364. %@AB@%;        cmpsen - case-sensitive comparison%@AE@%%@NL@%
  10365. %@AB@%;%@AE@%%@NL@%
  10366. %@AB@%;        ENTRY        DS:SI = buffer%@AE@%%@NL@%
  10367. %@AB@%;                ES:DI = string%@AE@%%@NL@%
  10368. %@AB@%;                CX = length of string%@AE@%%@NL@%
  10369. %@AB@%;        EXIT        CX = length of string unused%@AE@%%@NL@%
  10370. %@AB@%;                DI = unused portion of string%@AE@%%@NL@%
  10371. %@AB@%;                Z set%@AE@%%@NL@%
  10372. %@AB@%;                    match found%@AE@%%@NL@%
  10373. %@AB@%;                Z clear%@AE@%%@NL@%
  10374. %@AB@%;                    no match%@AE@%%@NL@%
  10375. %@AB@%;        USES        CX, DI, SI, Flags%@AE@%%@NL@%
  10376. %@NL@%
  10377.         EVEN%@NL@%
  10378. %@NL@%
  10379. cmpsen        proc        near%@NL@%
  10380.         repe cmpsb%@NL@%
  10381.         ret%@NL@%
  10382. cmpsen        endp%@NL@%
  10383. %@NL@%
  10384. %@NL@%
  10385. %@AB@%;        cmpinsen - case-insensitive comparison%@AE@%%@NL@%
  10386. %@AB@%;%@AE@%%@NL@%
  10387. %@AB@%;        ENTRY        DS:SI = buffer%@AE@%%@NL@%
  10388. %@AB@%;                ES:DI = string%@AE@%%@NL@%
  10389. %@AB@%;                CX = length of string%@AE@%%@NL@%
  10390. %@AB@%;        EXIT        CX = length of string unused%@AE@%%@NL@%
  10391. %@AB@%;                DI = unused portion of string%@AE@%%@NL@%
  10392. %@AB@%;                Z set%@AE@%%@NL@%
  10393. %@AB@%;                    match found%@AE@%%@NL@%
  10394. %@AB@%;                Z clear%@AE@%%@NL@%
  10395. %@AB@%;                    no match%@AE@%%@NL@%
  10396. %@AB@%;        USES        AX, CX, DI, SI, Flags%@AE@%%@NL@%
  10397. %@NL@%
  10398.         EVEN%@NL@%
  10399. %@NL@%
  10400. cmpinsen proc        near%@NL@%
  10401. cmpi0:        lodsb                                %@AB@%; Byte in AL, SI = SI + 1%@AE@%%@NL@%
  10402.         mov        ah,[di]                        %@AB@%; Byte in AH, DI = DI + 1%@AE@%%@NL@%
  10403.         inc        di%@NL@%
  10404.         or        ax,2020h                %@AB@%; Fold bytes onto lower case%@AE@%%@NL@%
  10405.         cmp        al,ah                        %@AB@%; Compare bytes%@AE@%%@NL@%
  10406.         loope        cmpi0                        %@AB@%; Loop while same%@AE@%%@NL@%
  10407.         ret%@NL@%
  10408. cmpinsen endp%@NL@%
  10409. %@NL@%
  10410. %@NL@%
  10411. %@AB@%; void                        matchstrings(s1,s2,len,nmatched,leg)%@AE@%%@NL@%
  10412. %@AB@%; char                        *s1;                /* First string */%@AE@%%@NL@%
  10413. %@AB@%; char                        *s2;                /* Second string */%@AE@%%@NL@%
  10414. %@AB@%; int                        len;                /* Length */%@AE@%%@NL@%
  10415. %@AB@%; int                        *nmatched;        /* Number of bytes matched */%@AE@%%@NL@%
  10416. %@AB@%; int                        *leg;                /* Less than, equal, greater than */%@AE@%%@NL@%
  10417. %@NL@%
  10418. cm_s1                equ        word ptr [bp+retlen+2]%@NL@%
  10419. cm_s2                equ        word ptr [bp+retlen+4]%@NL@%
  10420. cm_len                equ        word ptr [bp+retlen+6]%@NL@%
  10421. cm_nmatched        equ        word ptr [bp+retlen+8]%@NL@%
  10422. cm_leg                equ        word ptr [bp+retlen+10]%@NL@%
  10423. %@NL@%
  10424.         EVEN%@NL@%
  10425. %@NL@%
  10426.         public        _matchstrings%@NL@%
  10427. _matchstrings proc near%@NL@%
  10428.         ASSUME        DS:DGROUP, ES:NOTHING, SS:DGROUP%@NL@%
  10429. %@NL@%
  10430.         push        bp%@NL@%
  10431.         mov        bp,sp%@NL@%
  10432.         push        di%@NL@%
  10433.         push        si%@NL@%
  10434.         push        ds%@NL@%
  10435.         pop        es%@NL@%
  10436.     ASSUME        ES:DGROUP%@NL@%
  10437.         mov        di,cm_s2%@NL@%
  10438.         mov        si,cm_s1%@NL@%
  10439.         mov        cx,cm_len%@NL@%
  10440.         cmp        _casesen,0%@NL@%
  10441.         je        cm0%@NL@%
  10442.         call        cmpsen%@NL@%
  10443.         jmp        short cm1%@NL@%
  10444. cm0:        call        cmpinsen%@NL@%
  10445. cm1:        mov        bx,cm_leg%@NL@%
  10446.         mov        word ptr [bx],0                %@AB@%; Assume equal%@AE@%%@NL@%
  10447.         jz        cm2                        %@AB@%;  yes, skip ahead%@AE@%%@NL@%
  10448.         mov        word ptr [bx],1                %@AB@%; Assume greater than%@AE@%%@NL@%
  10449.         jg        cm1a                        %@AB@%;  yes, skip ahead%@AE@%%@NL@%
  10450.         mov        word ptr [bx],-1        %@AB@%; Less than%@AE@%%@NL@%
  10451. cm1a:        dec        si%@NL@%
  10452. cm2:        sub        si,cm_s1%@NL@%
  10453.         mov        bx,cm_nmatched%@NL@%
  10454.         mov        [bx],si%@NL@%
  10455.         pop        si%@NL@%
  10456.         pop        di%@NL@%
  10457.         pop        bp%@NL@%
  10458.         ret%@NL@%
  10459. %@NL@%
  10460. _matchstrings endp%@NL@%
  10461. %@NL@%
  10462. %@NL@%
  10463. %@AB@%; int                        strcmp(s1,s2)%@AE@%%@NL@%
  10464. %@AB@%; char                        *s1;                /* First string */%@AE@%%@NL@%
  10465. %@AB@%; char                        *s2;                /* Second string */%@AE@%%@NL@%
  10466. %@NL@%
  10467.         public        _strcmp%@NL@%
  10468. _strcmp        proc        near%@NL@%
  10469.         push        bp%@NL@%
  10470.         mov        bp,sp%@NL@%
  10471.         push        di%@NL@%
  10472.         push        si%@NL@%
  10473.         push        ds%@NL@%
  10474.         pop        es%@NL@%
  10475.         mov        si,[bp+4]                %@AB@%; DS:SI = s1%@AE@%%@NL@%
  10476.         mov        di,[bp+6]                %@AB@%; ES:DI = s2%@AE@%%@NL@%
  10477. sc0:        lodsb                                %@AB@%; AL = *s1++%@AE@%%@NL@%
  10478.         scasb                                %@AB@%; AL - *s2++%@AE@%%@NL@%
  10479.         jne        sc1                        %@AB@%;  branch if no match%@AE@%%@NL@%
  10480.         or        al,al                        %@AB@%; End of s1?%@AE@%%@NL@%
  10481.         jne        sc0                        %@AB@%;  no, loop%@AE@%%@NL@%
  10482.         cbw                                %@AB@%; AX = 0%@AE@%%@NL@%
  10483.         jmp        short sc2                %@AB@%; Exit%@AE@%%@NL@%
  10484. sc1:        mov        ax,1                        %@AB@%; Assume s1 > s2%@AE@%%@NL@%
  10485.         jg        sc2                        %@AB@%;  yes, branch%@AE@%%@NL@%
  10486.         neg        ax                        %@AB@%; s1 < s2%@AE@%%@NL@%
  10487. sc2:        pop        si%@NL@%
  10488.         pop        di%@NL@%
  10489.         pop        bp%@NL@%
  10490.         ret%@NL@%
  10491. _strcmp        endp%@NL@%
  10492. %@NL@%
  10493. %@NL@%
  10494.         public        _bpt%@NL@%
  10495. _bpt        proc        near%@NL@%
  10496.         int        3%@NL@%
  10497.         ret%@NL@%
  10498. _bpt        endp%@NL@%
  10499. %@NL@%
  10500. _text        ends%@NL@%
  10501. %@NL@%
  10502. _data        segment word public 'data'%@NL@%
  10503. _data        ends%@NL@%
  10504. %@NL@%
  10505. end%@NL@%
  10506. %@NL@%
  10507. %@NL@%
  10508. %@2@%%@AH@%DATA.C%@AE@%%@EH@%%@NL@%
  10509. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\OPENDLG\DATA.C%@AE@%%@NL@%
  10510. %@NL@%
  10511. %@AB@%/***************************************************************************\%@NL@%
  10512. %@AB@%* DATA.C -- This file contains per process global variables%@NL@%
  10513. %@AB@%* Created by Microsoft Corporation, 1989%@NL@%
  10514. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  10515. %@NL@%
  10516. %@AI@%#define %@AE@%NO_DOS %@NL@%
  10517. %@AI@%#define %@AE@%NO_GPI %@NL@%
  10518. %@AI@%#include %@AE@%"tool.h" %@NL@%
  10519. %@NL@%
  10520. %@AB@%/*%@NL@%
  10521. %@AB@%   This library uses a NON SHARED DATA selector.  This means each%@NL@%
  10522. %@AB@%   process using the library gets its own selector, and also that%@NL@%
  10523. %@AB@%   values cannot be shared and must be recreated for each process.%@NL@%
  10524. %@AB@%*/%@AE@%%@NL@%
  10525. %@NL@%
  10526. HMODULE vhModule;            %@AB@%/* Library module handle */%@AE@%%@NL@%
  10527. HHEAP  vhheap;               %@AB@%/* Library heap */%@AE@%%@NL@%
  10528. %@NL@%
  10529. PSTR   vrgsz[CSTRINGS];      %@AB@%/* Array of pointer to our strings (indexed%@NL@%
  10530. %@AB@%                                by IDS_... */%@AE@%%@NL@%
  10531. %@NL@%
  10532. %@NL@%
  10533. %@2@%%@AH@%DCALC.C%@AE@%%@EH@%%@NL@%
  10534. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CALC\DCALC\DCALC.C%@AE@%%@NL@%
  10535. %@NL@%
  10536. %@AB@%/****************************** Module Header ******************************\%@NL@%
  10537. %@AB@%* Module Name:        dcalc.c - Dialog form of the Calc application%@NL@%
  10538. %@AB@%*%@NL@%
  10539. %@AB@%* OS/2 Presentation Manager version of Calc, ported from Windows version%@NL@%
  10540. %@AB@%*%@NL@%
  10541. %@AB@%* Created by Microsoft Corporation, 1989%@NL@%
  10542. %@AB@%*%@NL@%
  10543. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  10544. %@NL@%
  10545. %@AI@%#define %@AE@%INCL_DEV %@NL@%
  10546. %@AI@%#define %@AE@%INCL_DOSPROCESS %@NL@%
  10547. %@AI@%#define %@AE@%INCL_DOSSEMAPHORES %@NL@%
  10548. %@AI@%#define %@AE@%INCL_DOSNLS %@NL@%
  10549. %@AI@%#define %@AE@%INCL_ERRORS %@NL@%
  10550. %@AI@%#define %@AE@%INCL_WINBUTTONS %@NL@%
  10551. %@AI@%#define %@AE@%INCL_WINCLIPBOARD %@NL@%
  10552. %@AI@%#define %@AE@%INCL_WINDIALOGS %@NL@%
  10553. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  10554. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  10555. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  10556. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  10557. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  10558. %@AI@%#define %@AE@%INCL_WINSWITCHLIST %@NL@%
  10559. %@AI@%#define %@AE@%INCL_WINTRACKRECT %@NL@%
  10560. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  10561. %@AI@%#include %@AE@%<os2.h> %@NL@%
  10562. %@AI@%#include %@AE@%<string.h> %@NL@%
  10563. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  10564. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  10565. %@AI@%#include %@AE@%"dcalc.h" %@NL@%
  10566. %@NL@%
  10567. %@AB@%/************* GLOBAL VARIABLES         */%@AE@%%@NL@%
  10568. %@NL@%
  10569. char chLastKey, currkey;%@NL@%
  10570. char szCalcClass[] = "Calculator";%@NL@%
  10571. char szTitle[30];%@NL@%
  10572. char szreg1[20], szreg2[20], szmem[20], szregx[20];%@NL@%
  10573. %@AB@%/* hope 20 is enough for kanji error string */%@AE@%%@NL@%
  10574. char szErrorString[20], szPlusMinus[2];%@NL@%
  10575. short charwidth, charheight;%@NL@%
  10576. int aspectx, aspecty, nchszstr;%@NL@%
  10577. extern BOOL fError  = FALSE;%@NL@%
  10578. BOOL fValueInMemory = FALSE;%@NL@%
  10579. BOOL fMDown = FALSE;%@NL@%
  10580. UCHAR mScan = 0;%@NL@%
  10581. %@NL@%
  10582. %@AI@%#define %@AE@%TOLOWER(x)   ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x)) %@NL@%
  10583. %@AI@%#define %@AE@%WIDTHCONST  28 %@NL@%
  10584. %@AI@%#define %@AE@%CXCHARS     37 %@NL@%
  10585. %@AI@%#define %@AE@%CYCHARS     13 %@NL@%
  10586. %@NL@%
  10587. HAB hab;%@NL@%
  10588. HDC hdcLocal;                            %@AB@%/* Local used for button bitmap */%@AE@%%@NL@%
  10589. HPS hpsLocal;%@NL@%
  10590. HDC hdcSqr;                            %@AB@%/* Sqr used for square-root bitmap */%@AE@%%@NL@%
  10591. HPS hpsSqr;%@NL@%
  10592. HBITMAP hbmLocal, hbmSqr;%@NL@%
  10593. HMQ  hmqCalc            = NULL;%@NL@%
  10594. %@NL@%
  10595. HWND hwndCalc            = NULL,%@NL@%
  10596.      hwndMenu            = NULL;%@NL@%
  10597. %@NL@%
  10598. HPOINTER hptrFinger = NULL,%@NL@%
  10599.          hptrIcon   = NULL;%@NL@%
  10600. %@NL@%
  10601. DEVOPENSTRUC dop =                    %@AB@%/* used by DevOpenDC */%@AE@%%@NL@%
  10602. {%@NL@%
  10603.     NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL%@NL@%
  10604. };%@NL@%
  10605. %@NL@%
  10606. static char bButtonValues[] =            %@AB@%/* Button values */%@AE@%%@NL@%
  10607. {%@NL@%
  10608.     0xBC, 0xBB, 0xBA, 0xB9,  '0',  '1',  '2',  '3',  '4',%@NL@%
  10609.      '5',  '6',  '7',  '8',  '9',  '.',  '/',  '*',  '-',%@NL@%
  10610.      '+',  'q',  '%',  'c',  '=', 0xB1, NULL%@NL@%
  10611. };%@NL@%
  10612. %@NL@%
  10613. %@AB@%/************* PROCEDURE DECLARATIONS   */%@AE@%%@NL@%
  10614. %@NL@%
  10615. MPARAM EXPENTRY AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  10616. BOOL CalcInit(VOID);%@NL@%
  10617. VOID CalcPaint( HWND, HPS);%@NL@%
  10618. MRESULT EXPENTRY fnDlgCalc(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  10619. VOID cdecl main(VOID);%@NL@%
  10620. VOID DataXCopy( VOID);%@NL@%
  10621. VOID DataXPaste( VOID);%@NL@%
  10622. VOID DrawNumbers( HPS);%@NL@%
  10623. VOID Evaluate(BYTE);%@NL@%
  10624. VOID InitCalc( VOID);%@NL@%
  10625. BOOL InterpretChar( CHAR);%@NL@%
  10626. VOID ProcessKey(HWND, WPOINT *);%@NL@%
  10627. char Translate(WPOINT *);%@NL@%
  10628. VOID UpdateDisplay( VOID);%@NL@%
  10629. %@NL@%
  10630. %@NL@%
  10631. %@NL@%
  10632. %@AB@%/********************************************************************%@NL@%
  10633. %@AB@%   Write the appropriate number or error string to the display area%@NL@%
  10634. %@AB@%   and mark memory-in-use if appropriate.%@NL@%
  10635. %@AB@% */%@AE@%%@NL@%
  10636. %@NL@%
  10637. BYTE aszDisplayBuff[20];%@NL@%
  10638. %@NL@%
  10639. VOID UpdateDisplay()%@NL@%
  10640. {%@NL@%
  10641.     strcpy(aszDisplayBuff, fError? "Error" :szreg1);%@NL@%
  10642.     strcat(aszDisplayBuff, fValueInMemory? " M" : "  ");%@NL@%
  10643. %@NL@%
  10644.     WinSetDlgItemText(hwndCalc, TXT_RESULT_DISPLAY, aszDisplayBuff);%@NL@%
  10645. }%@NL@%
  10646. %@NL@%
  10647. %@NL@%
  10648. %@AB@%/**********************************************************************%@NL@%
  10649. %@AB@%    Display helpful info%@NL@%
  10650. %@AB@% */%@AE@%%@NL@%
  10651. %@NL@%
  10652. MPARAM EXPENTRY AboutDlgProc(hwnd, msg, mp1, mp2)%@NL@%
  10653. HWND hwnd;%@NL@%
  10654. USHORT msg;%@NL@%
  10655. MPARAM mp1;%@NL@%
  10656. MPARAM mp2;%@NL@%
  10657. {%@NL@%
  10658.     if (msg == WM_COMMAND)%@NL@%
  10659.     {%@NL@%
  10660.         WinDismissDlg(hwnd, TRUE);%@NL@%
  10661.         return(MPFROMSHORT(TRUE));%@NL@%
  10662.     }%@NL@%
  10663.     else return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  10664. }%@NL@%
  10665. %@NL@%
  10666. %@NL@%
  10667. %@AB@%/**********************************************************************%@NL@%
  10668. %@AB@%    General initialization%@NL@%
  10669. %@AB@% */%@AE@%%@NL@%
  10670. %@NL@%
  10671. BOOL CalcInit()%@NL@%
  10672. {%@NL@%
  10673.     hab = WinInitialize(0);%@NL@%
  10674. %@NL@%
  10675.     hmqCalc = WinCreateMsgQueue( hab, 0);%@NL@%
  10676. %@NL@%
  10677.     return(TRUE);%@NL@%
  10678. }%@NL@%
  10679. %@NL@%
  10680. %@AB@%/**********************************************************************%@NL@%
  10681. %@AB@%    main procedure%@NL@%
  10682. %@AB@% */%@AE@%%@NL@%
  10683. %@NL@%
  10684. VOID cdecl main()%@NL@%
  10685. {%@NL@%
  10686.     QMSG qmsg;%@NL@%
  10687. %@NL@%
  10688.     if (!CalcInit()) {                            %@AB@%/* general initialization */%@AE@%%@NL@%
  10689.         WinAlarm(HWND_DESKTOP, 0xffff);%@NL@%
  10690.         goto exit;%@NL@%
  10691.     }%@NL@%
  10692. %@NL@%
  10693.     WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, fnDlgCalc, NULL, CALCDLG, NULL);%@NL@%
  10694. %@NL@%
  10695.     if (hwndCalc)%@NL@%
  10696.         while (WinGetMsg( hab, (PQMSG)&qmsg, NULL, 0, 0))%@NL@%
  10697.             WinDispatchMsg( hab, (PQMSG)&qmsg);%@NL@%
  10698. %@NL@%
  10699. exit:                                            %@AB@%/* clean up */%@AE@%%@NL@%
  10700. %@NL@%
  10701.     if (hwndMenu)      WinDestroyWindow(hwndMenu);%@NL@%
  10702. %@NL@%
  10703.     WinDestroyMsgQueue(hmqCalc);%@NL@%
  10704.     WinTerminate(hab);%@NL@%
  10705. %@NL@%
  10706.     DosExit(EXIT_PROCESS, 0);                    %@AB@%/* exit without error */%@AE@%%@NL@%
  10707. }%@NL@%
  10708. %@NL@%
  10709. %@NL@%
  10710. %@AB@%/*************************************************************************%@NL@%
  10711. %@AB@%   Calc Dialog Window Procedure%@NL@%
  10712. %@AB@% */%@AE@%%@NL@%
  10713. %@NL@%
  10714. %@NL@%
  10715. USHORT        idProcess, idThread;%@NL@%
  10716. SWCNTRL swc;%@NL@%
  10717. HSWITCH hsw;%@NL@%
  10718. USHORT        usWidthCalc, usHeightCalc;%@NL@%
  10719. %@NL@%
  10720. MRESULT EXPENTRY fnDlgCalc(hwnd, msg, mp1, mp2)%@NL@%
  10721. HWND hwnd;%@NL@%
  10722. USHORT msg;%@NL@%
  10723. MPARAM mp1;%@NL@%
  10724. MPARAM mp2;%@NL@%
  10725. {%@NL@%
  10726.     RECTL rectl;%@NL@%
  10727.     BOOL fClip;%@NL@%
  10728.     USHORT fi, idCtrl;%@NL@%
  10729.     MRESULT mresult;%@NL@%
  10730.     USHORT  afSWP;%@NL@%
  10731.     PSWP    pswp;%@NL@%
  10732. %@NL@%
  10733.     static BOOL fMinimized;%@NL@%
  10734. %@NL@%
  10735. %@NL@%
  10736.     switch (msg)%@NL@%
  10737.     {%@NL@%
  10738.     case WM_INITDLG:%@NL@%
  10739. %@NL@%
  10740. %@AB@%/* Set up the global state assumed by the dialog.%@NL@%
  10741. %@AB@% */%@AE@%%@NL@%
  10742.         hwndCalc = hwnd;%@NL@%
  10743.         hwndMenu = WinLoadMenu(hwnd, NULL, IDR_CALC);%@NL@%
  10744. %@NL@%
  10745.         fMinimized = FALSE;%@NL@%
  10746. %@NL@%
  10747.         hptrFinger = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);%@NL@%
  10748.         hptrIcon   = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_CALC);%@NL@%
  10749. %@NL@%
  10750.         WinSetWindowULong(hwndCalc, QWL_STYLE,%@NL@%
  10751.                           FS_ICON | WinQueryWindowULong(hwndCalc, QWL_STYLE)%@NL@%
  10752.                          );%@NL@%
  10753. %@NL@%
  10754.         WinSendMsg(hwndCalc, WM_SETICON,     (MPARAM) hptrIcon, 0L);%@NL@%
  10755.         WinSendMsg(hwndCalc, WM_UPDATEFRAME, (MPARAM) 0L,        0L);%@NL@%
  10756. %@NL@%
  10757.         WinQueryWindowRect(hwndCalc, &rectl);%@NL@%
  10758.          usWidthCalc= (SHORT) (rectl.xRight - rectl.xLeft);%@NL@%
  10759.         usHeightCalc= (SHORT) (rectl.yTop   - rectl.yBottom);%@NL@%
  10760. %@NL@%
  10761.         WinQueryWindowProcess(hwndCalc, &idProcess, &idThread);%@NL@%
  10762. %@NL@%
  10763.         WinLoadString(NULL, NULL, 1, 30, (PSZ)szTitle);%@NL@%
  10764.         WinLoadString(NULL, NULL, 2, 20, (PSZ)szErrorString);%@NL@%
  10765.         WinLoadString(NULL, NULL, 3, 2,  (PSZ)szPlusMinus);%@NL@%
  10766. %@NL@%
  10767.         strcpy(swc.szSwtitle, szTitle);%@NL@%
  10768.         swc.hwnd          = hwndCalc;%@NL@%
  10769.         swc.hwndIcon          = hptrIcon;%@NL@%
  10770.         swc.hprog          = (ULONG)NULL;%@NL@%
  10771.         swc.idProcess          = idProcess;%@NL@%
  10772.         swc.idSession          = (USHORT)0;%@NL@%
  10773.         swc.uchVisibility = SWL_VISIBLE;%@NL@%
  10774.         swc.fbJump          = SWL_JUMPABLE;%@NL@%
  10775.         hsw                  = WinAddSwitchEntry((PSWCNTRL)&swc);%@NL@%
  10776. %@NL@%
  10777.         InitCalc();                            %@AB@%/* arithmetic initialization */%@AE@%%@NL@%
  10778. %@NL@%
  10779.         WinSetActiveWindow(HWND_DESKTOP, hwndCalc);%@NL@%
  10780. %@NL@%
  10781.         WinSetFocus(HWND_DESKTOP, hwndCalc);%@NL@%
  10782. %@NL@%
  10783.         break;%@NL@%
  10784. %@NL@%
  10785.     case WM_MINMAXFRAME:%@NL@%
  10786. %@NL@%
  10787.         pswp= PVOIDFROMMP(mp1);%@NL@%
  10788. %@NL@%
  10789.         if (pswp->fs & SWP_MINIMIZE) fMinimized= TRUE;%@NL@%
  10790.         else%@NL@%
  10791.             if (pswp->fs & SWP_RESTORE) fMinimized= FALSE;%@NL@%
  10792. %@NL@%
  10793.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  10794. %@NL@%
  10795.         break;%@NL@%
  10796. %@NL@%
  10797.     case WM_DESTROY:%@NL@%
  10798. %@NL@%
  10799.         WinDestroyPointer(hptrIcon  );        hptrIcon  = NULL;%@NL@%
  10800.         WinDestroyPointer(hptrFinger);        hptrFinger= NULL;%@NL@%
  10801. %@NL@%
  10802.         break;%@NL@%
  10803. %@NL@%
  10804.     case WM_INITMENU:%@NL@%
  10805. %@NL@%
  10806.         fClip = FALSE;%@NL@%
  10807. %@NL@%
  10808.         if (WinOpenClipbrd(NULL))%@NL@%
  10809.         {%@NL@%
  10810.             fClip = WinQueryClipbrdFmtInfo(NULL, CF_TEXT, (USHORT FAR *)&fi);%@NL@%
  10811.             WinCloseClipbrd(NULL);%@NL@%
  10812.         }%@NL@%
  10813. %@NL@%
  10814.         WinSendMsg((HWND)mp2, MM_SETITEMATTR,%@NL@%
  10815.                    (MPARAM) MAKELONG(CMD_PASTE, TRUE),%@NL@%
  10816.                    (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED));%@NL@%
  10817.         break;%@NL@%
  10818. %@NL@%
  10819.     case WM_ADJUSTWINDOWPOS:%@NL@%
  10820. %@NL@%
  10821.         mresult= WinDefDlgProc(hwnd, msg, mp1, mp2);%@NL@%
  10822. %@NL@%
  10823.         if (fMinimized) return(mresult);%@NL@%
  10824. %@NL@%
  10825.         afSWP= (pswp= (PSWP) mp1)->fs;%@NL@%
  10826. %@NL@%
  10827.         if (         afSWP & (SWP_SIZE     | SWP_MAXIMIZE)%@NL@%
  10828.             && !(afSWP &  SWP_MINIMIZE)%@NL@%
  10829.            )%@NL@%
  10830.         {%@NL@%
  10831.             pswp->y += pswp->cy - usHeightCalc;%@NL@%
  10832.             pswp->cx =        usWidthCalc;%@NL@%
  10833.             pswp->cy = usHeightCalc;%@NL@%
  10834.         }%@NL@%
  10835. %@NL@%
  10836.         return(mresult);%@NL@%
  10837. %@NL@%
  10838. %@NL@%
  10839.     case WM_COMMAND:%@NL@%
  10840. %@NL@%
  10841.         fError = FALSE;%@NL@%
  10842. %@NL@%
  10843.         idCtrl= SHORT1FROMMP(mp1);%@NL@%
  10844. %@NL@%
  10845.         if (   SHORT1FROMMP(mp2) == BN_CLICKED%@NL@%
  10846.             && idCtrl >= BUTTON_MC%@NL@%
  10847.             && idCtrl <= BUTTON_CHANGE_SIGN%@NL@%
  10848.            )%@NL@%
  10849.         {%@NL@%
  10850.             Evaluate(bButtonValues[idCtrl-BUTTON_MC]);%@NL@%
  10851.             UpdateDisplay();%@NL@%
  10852.         }%@NL@%
  10853.         else%@NL@%
  10854.             switch(idCtrl)%@NL@%
  10855.             {%@NL@%
  10856.             case CMD_COPY:%@NL@%
  10857.                 DataXCopy();                        %@AB@%/* copy to clipboard */%@AE@%%@NL@%
  10858.                 break;%@NL@%
  10859.             case CMD_PASTE:%@NL@%
  10860.                 DataXPaste();                        %@AB@%/* paste from clipboard */%@AE@%%@NL@%
  10861.                 break;%@NL@%
  10862.             case CMD_EXIT:%@NL@%
  10863.                 WinPostMsg(hwndCalc, WM_QUIT, 0L, 0L);%@NL@%
  10864.                 break;%@NL@%
  10865.             case CMD_ABOUT:%@NL@%
  10866.                 WinDlgBox(HWND_DESKTOP, hwndCalc, (PFNWP)AboutDlgProc, NULL,%@NL@%
  10867.                           1, (PSZ)NULL);%@NL@%
  10868.                 break;%@NL@%
  10869.             }%@NL@%
  10870.         break;%@NL@%
  10871. %@NL@%
  10872.     case WM_CLOSE:%@NL@%
  10873.         WinPostMsg(hwndCalc, WM_QUIT, 0L, 0L);%@NL@%
  10874.         break;%@NL@%
  10875. %@NL@%
  10876.     case WM_CONTROLPOINTER:%@NL@%
  10877.         if (!fMinimized) return(hptrFinger);%@NL@%
  10878.         else return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  10879. %@NL@%
  10880.     case WM_MOUSEMOVE:%@NL@%
  10881.         if (!fMinimized) WinSetPointer(HWND_DESKTOP, hptrFinger);%@NL@%
  10882.         break;%@NL@%
  10883. %@NL@%
  10884.     case WM_BUTTON1DOWN:%@NL@%
  10885. %@NL@%
  10886.         return(WinDefDlgProc(hwnd, WM_TRACKFRAME, (MPARAM) TF_MOVE, mp2));%@NL@%
  10887. %@NL@%
  10888.         break;%@NL@%
  10889. %@NL@%
  10890.     case WM_CHAR:%@NL@%
  10891. %@NL@%
  10892.         fError = FALSE;%@NL@%
  10893.         if (SHORT1FROMMP(mp1) & KC_KEYUP)%@NL@%
  10894.         {%@NL@%
  10895.             if (CHAR4FROMMP(mp1) == mScan)%@NL@%
  10896.                    fMDown = FALSE;                 %@AB@%/* 'm' key went up */%@AE@%%@NL@%
  10897.         }%@NL@%
  10898.         else %@NL@%
  10899.         {%@NL@%
  10900.                 if (SHORT1FROMMP(mp1) & KC_CHAR)%@NL@%
  10901.       {%@NL@%
  10902.              if (InterpretChar((UCHAR)(ULONG)(mp2)))%@NL@%
  10903.                   {        %@NL@%
  10904.                                 UpdateDisplay();%@NL@%
  10905.                   }%@NL@%
  10906.              else %@NL@%
  10907.                   {%@NL@%
  10908.                                   if (((UCHAR)(ULONG)(mp2)== 'm') || ((UCHAR)(ULONG)(mp2)== 'M'))%@NL@%
  10909.                             {%@NL@%
  10910.                                         mScan = CHAR4FROMMP(mp1);           %@AB@%/* save 'm' key scan code  */%@AE@%%@NL@%
  10911.                                         fMDown = TRUE;                           %@AB@%/* 'm' key went down       */%@AE@%%@NL@%
  10912.                             }%@NL@%
  10913.         }%@NL@%
  10914.                 }%@NL@%
  10915.         }%@NL@%
  10916.         break;%@NL@%
  10917. %@NL@%
  10918. %@NL@%
  10919.     case WM_ERASEBACKGROUND:%@NL@%
  10920.         if (WinQueryWindowULong(hwnd, QWL_STYLE) & WS_MINIMIZED)%@NL@%
  10921.             WinValidateRect(hwnd, (PRECTL) mp2, TRUE);%@NL@%
  10922.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  10923.         break;%@NL@%
  10924. %@NL@%
  10925.     case WM_SETFOCUS:%@NL@%
  10926.         if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);%@NL@%
  10927.             fMDown = FALSE;                        %@AB@%/* since we are losing focus */%@AE@%%@NL@%
  10928. %@NL@%
  10929.     default:%@NL@%
  10930.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  10931.         break;%@NL@%
  10932.     }%@NL@%
  10933.     return(0L);%@NL@%
  10934. }%@NL@%
  10935. %@NL@%
  10936. %@NL@%
  10937. %@AB@%/*************************************************************************%@NL@%
  10938. %@AB@%    translate & interpret keys (ie. locate in logical keyboard)%@NL@%
  10939. %@AB@% */%@AE@%%@NL@%
  10940. %@NL@%
  10941. BOOL InterpretChar(ch)%@NL@%
  10942. register CHAR ch;%@NL@%
  10943. {%@NL@%
  10944.     BOOL fDone;%@NL@%
  10945.     CHAR *chstep;%@NL@%
  10946. %@NL@%
  10947.     fDone = FALSE;%@NL@%
  10948.     chstep = bButtonValues;%@NL@%
  10949.     switch (ch)%@NL@%
  10950.     {%@NL@%
  10951.     case 'n':%@NL@%
  10952.         ch = szPlusMinus[0];%@NL@%
  10953.         break;%@NL@%
  10954.     case 27:                        %@AB@%/* xlate Escape into 'c' */%@AE@%%@NL@%
  10955.         ch = 'c';%@NL@%
  10956.         break;%@NL@%
  10957.     case '\r':                      %@AB@%/* xlate Enter into '=' */%@AE@%%@NL@%
  10958.         ch = '=';%@NL@%
  10959.         break;%@NL@%
  10960.     }%@NL@%
  10961. %@NL@%
  10962.     if (fMDown)                     %@AB@%/* Do memory keys */%@AE@%%@NL@%
  10963.     {%@NL@%
  10964.         switch (ch)%@NL@%
  10965.         {%@NL@%
  10966.         case 'c':%@NL@%
  10967.         case 'C':%@NL@%
  10968.             ch = '\274';%@NL@%
  10969.             break;%@NL@%
  10970.         case 'r':%@NL@%
  10971.         case 'R':%@NL@%
  10972.             ch = '\273';%@NL@%
  10973.             break;%@NL@%
  10974.         case '+':%@NL@%
  10975.             ch = '\272';%@NL@%
  10976.             break;%@NL@%
  10977.         case '-':%@NL@%
  10978.             ch = '\271';%@NL@%
  10979.             break;%@NL@%
  10980.         }%@NL@%
  10981.     }%@NL@%
  10982. %@NL@%
  10983.     while (!fDone && *chstep)%@NL@%
  10984.     {%@NL@%
  10985.         if (*chstep++ == ch)%@NL@%
  10986.             fDone = TRUE;                %@AB@%/* char found in logical keyboard */%@AE@%%@NL@%
  10987.     }%@NL@%
  10988. %@NL@%
  10989.     if (fDone)%@NL@%
  10990.     {%@NL@%
  10991.         Evaluate(ch);%@NL@%
  10992.     }%@NL@%
  10993. %@NL@%
  10994.     return (fDone);%@NL@%
  10995. }%@NL@%
  10996. %@NL@%
  10997. %@NL@%
  10998. %@2@%%@AH@%DDEML.C%@AE@%%@EH@%%@NL@%
  10999. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DDEML.C%@AE@%%@NL@%
  11000. %@NL@%
  11001. %@AB@%/****************************** Module Header ******************************\%@NL@%
  11002. %@AB@%* Module Name: DDE.C%@NL@%
  11003. %@AB@%*%@NL@%
  11004. %@AB@%* DDE Manager main module - Contains all exported Dde functions.%@NL@%
  11005. %@AB@%*%@NL@%
  11006. %@AB@%* Created: 12/12/88 Sanford Staab%@NL@%
  11007. %@AB@%*%@NL@%
  11008. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  11009. %@AB@%* 4/5/89        sanfords        removed need for hwndFrame registration parameter%@NL@%
  11010. %@AB@%* 6/5/90        sanfords        Fixed callbacks so they are blocked during%@NL@%
  11011. %@AB@%*                               timeouts.%@NL@%
  11012. %@AB@%*                               Fixed SendDDEInit allocation bug.%@NL@%
  11013. %@AB@%*                               Added hApp to ConvInfo structure.%@NL@%
  11014. %@AB@%*                               Allowed QueryConvInfo() to work on server hConvs.%@NL@%
  11015. %@AB@%*                               Added FindFrame() to provide an hApp for Server%@NL@%
  11016. %@AB@%*                               hConvs.%@NL@%
  11017. %@AB@%* 6/14/90       sanfords        Altered hDatas so they will work when shared%@NL@%
  11018. %@AB@%*                               between threads of the same process.  Also%@NL@%
  11019. %@AB@%*                               added optimization to only have the hsz%@NL@%
  11020. %@AB@%*                               in the hData for local conversations.%@NL@%
  11021. %@AB@%* 6/21/90       sanfords        Renamed APIs to Dde....%@NL@%
  11022. %@AB@%*                               Finished DdeAppNameServer() implementation.%@NL@%
  11023. %@AB@%*                       %@NL@%
  11024. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  11025. %@NL@%
  11026. %@AI@%#include %@AE@%"ddemlp.h"  %@NL@%
  11027. %@AI@%#include %@AE@%"version.h" %@NL@%
  11028. %@NL@%
  11029. %@AB@%/****** Globals *******/%@AE@%%@NL@%
  11030. %@NL@%
  11031. HMODULE hmodDmg = 0;        %@AB@%/* initialized by LoadProc on DLL initialization */%@AE@%%@NL@%
  11032. PFNWP lpfnFrameWndProc = 0;             %@AB@%/* system Frame window procedure */%@AE@%%@NL@%
  11033. %@NL@%
  11034. HHEAP hheapDmg = 0;                     %@AB@%/* main DLL heap */%@AE@%%@NL@%
  11035. %@NL@%
  11036. PHATOMTBL aAtbls;%@NL@%
  11037. USHORT cAtbls = 0;%@NL@%
  11038. USHORT iAtblCurrent = 0;%@NL@%
  11039. USHORT   cMonitor = 0;%@NL@%
  11040. DOSFSRSEM FSRSemDmg;                    %@AB@%/* used to protect globals */%@AE@%%@NL@%
  11041. USHORT cAtoms = 0;                      %@AB@%/* for debugging! */%@AE@%%@NL@%
  11042. %@NL@%
  11043. PAPPINFO pAppInfoList = NULL;           %@AB@%/* registered thread data list */%@AE@%%@NL@%
  11044. USHORT usHugeShift;                     %@AB@%/* for huge segment support */%@AE@%%@NL@%
  11045. USHORT usHugeAdd;                       %@AB@%/* for huge segment support */%@AE@%%@NL@%
  11046. COUNTRYCODE syscc;%@NL@%
  11047. %@NL@%
  11048. BOOL fInSubset(PCQDATA pcqd, ULONG afCmd);%@NL@%
  11049. %@NL@%
  11050. %@AB@%/* PUBDOC START *\%@NL@%
  11051. %@AB@%DLL overview:%@NL@%
  11052. %@AB@%%@NL@%
  11053. %@AB@%This DLL supports standard DDE communication on behalf of its client%@NL@%
  11054. %@AB@%applications.  It is compatable with most existing DDE programs.  The%@NL@%
  11055. %@AB@%API interface features object-like abstractions that allow its implementation%@NL@%
  11056. %@AB@%on and across a variety of platforms.%@NL@%
  11057. %@AB@%%@NL@%
  11058. %@AB@%Main features:%@NL@%
  11059. %@AB@%%@NL@%
  11060. %@AB@%  * HSZ manager:    Allows more efficient handling of numerous character%@NL@%
  11061. %@AB@%                    strings without the limitations of the atom manager.%@NL@%
  11062. %@AB@%                    %@NL@%
  11063. %@AB@%  * HDATA manager:  Data container objects allow easy filling, accessing%@NL@%
  11064. %@AB@%                    and reuse of huge amounts of data and allow a%@NL@%
  11065. %@AB@%                    server to efficiently support several clients.%@NL@%
  11066. %@AB@%                    %@NL@%
  11067. %@AB@%  * Controled initiates: Supports client to multi-server initiates and%@NL@%
  11068. %@AB@%                    allows a client application to pick and choose which%@NL@%
  11069. %@AB@%                    conversations to keep.%@NL@%
  11070. %@AB@%%@NL@%
  11071. %@AB@%  * Debugging support: Allows monitoring applications to be easily written%@NL@%
  11072. %@AB@%                    and provides readable error messages.  %@NL@%
  11073. %@AB@%%@NL@%
  11074. %@AB@%  * Huge Segment support: Exports a useful huge segment copy function and%@NL@%
  11075. %@AB@%                    properly handles huge data transfers.%@NL@%
  11076. %@AB@%%@NL@%
  11077. %@AB@%  * Synchronous communication:  Clients may use a very simple form of%@NL@%
  11078. %@AB@%                    transaction processing that requires little application%@NL@%
  11079. %@AB@%                    support.%@NL@%
  11080. %@AB@%%@NL@%
  11081. %@AB@%  * Asynchronous communication:  Clients may opt to use queued transfers%@NL@%
  11082. %@AB@%                    freeing them to do other tasks in parellel with DDE.%@NL@%
  11083. %@AB@%%@NL@%
  11084. %@AB@%  * Callback control:  Applications may selectively suspend DLL callbacks%@NL@%
  11085. %@AB@%                    to themselves when in time critical sections.  Selected%@NL@%
  11086. %@AB@%                    conversations can be blocked while being serviced so%@NL@%
  11087. %@AB@%                    others can be processed by the same thread.%@NL@%
  11088. %@AB@%%@NL@%
  11089. %@AB@%  * registration notification: All applications using this DLL are notified%@NL@%
  11090. %@AB@%                    whenever any other application registers or unregisters%@NL@%
  11091. %@AB@%                    itself with this DLL.  This enables nameserver support%@NL@%
  11092. %@AB@%                    for DDE.%@NL@%
  11093. %@AB@%%@NL@%
  11094. %@AB@%  * multiple DDE entity support:  An application can register itself with%@NL@%
  11095. %@AB@%                    any number of application names and can change what%@NL@%
  11096. %@AB@%                    application names it responds to at any time.  Each%@NL@%
  11097. %@AB@%                    registered thread is a seperate DDE entity.%@NL@%
  11098. %@AB@%%@NL@%
  11099. %@AB@%  * advise loop control:  Advise loops are tracked by the DLL, however%@NL@%
  11100. %@AB@%                    server applications have complete control over%@NL@%
  11101. %@AB@%                    advise loop initiation.%@NL@%
  11102. %@AB@%%@NL@%
  11103. %@AB@%  * network agent support: Special agent applications can register with this%@NL@%
  11104. %@AB@%                    DLL to represent multiple applications on other machines%@NL@%
  11105. %@AB@%                    or platforms.%@NL@%
  11106. %@AB@%                    %@NL@%
  11107. %@AB@%API specifications:%@NL@%
  11108. %@AB@%%@NL@%
  11109. %@AB@%Callback function:%@NL@%
  11110. %@AB@%    %@NL@%
  11111. %@AB@%EXPENTRY Callback(%@NL@%
  11112. %@AB@%HCONV hConv,        // holds server conversation handle in most cases%@NL@%
  11113. %@AB@%HSZ hszTopic,       // holds topic hsz for transaction%@NL@%
  11114. %@AB@%HSZ hszItem,        // holds item or application hsz for transaction%@NL@%
  11115. %@AB@%USHORT usFormat,    // holds data format when applicable%@NL@%
  11116. %@AB@%USHORT usType,      // holds transaction type code%@NL@%
  11117. %@AB@%HDMGDATA hDmgData); // holds incomming data in most cases%@NL@%
  11118. %@AB@%%@NL@%
  11119. %@AB@%This is the definition of the data call-back function that an%@NL@%
  11120. %@AB@%application must export so that the DDE can initiate interaction%@NL@%
  11121. %@AB@%with the application when necessary.  This function is refered to in%@NL@%
  11122. %@AB@%the DdeInitialize() call.%@NL@%
  11123. %@AB@%%@NL@%
  11124. %@AB@%The application callback function is very much like a PM window %@NL@%
  11125. %@AB@%procedure for DDE.  The usType specifies the type of transaction being %@NL@%
  11126. %@AB@%done.  By ANDing this parameter with XCLASS_MASK and comparing the %@NL@%
  11127. %@AB@%result with the XCLASS_ constants, the transaction return type %@NL@%
  11128. %@AB@%expected can be classified.%@NL@%
  11129. %@AB@%%@NL@%
  11130. %@AB@%XTYP_ constants also may contain the XTYPF_NOBLOCK flag.  The presence%@NL@%
  11131. %@AB@%of this flag indicates that the CBR_BLOCK return value from the callback%@NL@%
  11132. %@AB@%will not be honored by the DDE.  (see DdeEnableCallback() for more%@NL@%
  11133. %@AB@%information on this concept.)%@NL@%
  11134. %@AB@%%@NL@%
  11135. %@AB@%The various transactions are explained below:%@NL@%
  11136. %@AB@%%@NL@%
  11137. %@AB@%%@NL@%
  11138. %@AB@%-----XCLASS_NOTIFICATION class:%@NL@%
  11139. %@AB@%    These are strictly notification messages to an application.  The return%@NL@%
  11140. %@AB@%    value is ignored except in the case of CBR_BLOCK. (if the notification%@NL@%
  11141. %@AB@%    is blockable)%@NL@%
  11142. %@AB@%%@NL@%
  11143. %@AB@%XTYP_RTNPKT%@NL@%
  11144. %@AB@%%@NL@%
  11145. %@AB@%   This transaction is sent to agent applications.  hDmgData contains a %@NL@%
  11146. %@AB@%   packet to send to the agent who's handle is in the hszItem parameter.  %@NL@%
  11147. %@AB@%%@NL@%
  11148. %@AB@%XTYP_REGISTER%@NL@%
  11149. %@AB@%%@NL@%
  11150. %@AB@%   Another server name has just been registered with the DLL application %@NL@%
  11151. %@AB@%   name server.  hszItem is set to the application name being %@NL@%
  11152. %@AB@%   registered.  If this is NULL, an application has registered itself as %@NL@%
  11153. %@AB@%   WILD.  hDmgData is set to the application handle that registered.%@NL@%
  11154. %@AB@%   This is not blockable by CBR_BLOCK because no hConv is %@NL@%
  11155. %@AB@%   associated with it.  Only if all callbacks are disabled is this %@NL@%
  11156. %@AB@%   transaction blocked.%@NL@%
  11157. %@AB@%%@NL@%
  11158. %@AB@%XTYP_UNREGISTER%@NL@%
  11159. %@AB@%%@NL@%
  11160. %@AB@%   Another server application has just unregistered a name with this %@NL@%
  11161. %@AB@%   DLL.  hszItem is set to the application name being unregistered.%@NL@%
  11162. %@AB@%   hDmgData is set to the app handle of the unregistering application.%@NL@%
  11163. %@AB@%   This is not blockable by CBR_BLOCK because no hConv is associated %@NL@%
  11164. %@AB@%   with it.  Only if all callbacks are disabled is this transaction %@NL@%
  11165. %@AB@%   blocked.%@NL@%
  11166. %@AB@%%@NL@%
  11167. %@AB@%XTYP_INIT_CONFIRM%@NL@%
  11168. %@AB@%%@NL@%
  11169. %@AB@%   Sent to let a server know that a conversation on application hszItem %@NL@%
  11170. %@AB@%   and Topic hszTopic has been established on hConv.  hConv uniquely %@NL@%
  11171. %@AB@%   identifies this conversation from the server's prospective.  This %@NL@%
  11172. %@AB@%   call cannot be blocked because it is part of the DDE initiate %@NL@%
  11173. %@AB@%   sequence.  This callback is generated by the results of XTYP_INIT and %@NL@%
  11174. %@AB@%   XTYP_WILDINIT callbacks.  %@NL@%
  11175. %@AB@%%@NL@%
  11176. %@AB@%XTYP_TERM%@NL@%
  11177. %@AB@%%@NL@%
  11178. %@AB@%   This is a notification telling a server application that a %@NL@%
  11179. %@AB@%   conversation has been terminated.  hConv is set to identify which %@NL@%
  11180. %@AB@%   conversation was terminated.  %@NL@%
  11181. %@AB@%%@NL@%
  11182. %@AB@%XTYP_ADVSTOP%@NL@%
  11183. %@AB@%%@NL@%
  11184. %@AB@%   This notifies a server that an advise loop is stopping.  hszTopic, %@NL@%
  11185. %@AB@%   hszItem, and usFormat identify the advise loop within hConv.  %@NL@%
  11186. %@AB@%%@NL@%
  11187. %@AB@%XTYP_XFERCOMPLETE%@NL@%
  11188. %@AB@%%@NL@%
  11189. %@AB@%   This notifictaion is sent to a client when an asynchronous data %@NL@%
  11190. %@AB@%   DdeClientXfer() transaction is completed.  hDmgData is the client %@NL@%
  11191. %@AB@%   queue ID of the completed transaction.  hConv is the client %@NL@%
  11192. %@AB@%   conversation handle.  %@NL@%
  11193. %@AB@%    %@NL@%
  11194. %@AB@%XTYP_MONITOR%@NL@%
  11195. %@AB@%%@NL@%
  11196. %@AB@%   This notifies an app registered as DMGCMD_MONITOR of DDE data that is %@NL@%
  11197. %@AB@%   being transmitted.  hDmgData contains a text string representing the %@NL@%
  11198. %@AB@%   transaction suitable for printing on a terminal, file, or window.  %@NL@%
  11199. %@AB@%   Note that this monitors ALL DDE communication and may be extensive.  %@NL@%
  11200. %@AB@%   This call cannot be delayed by disabled callbacks.  This transaction %@NL@%
  11201. %@AB@%   is not blockable.  %@NL@%
  11202. %@AB@%%@NL@%
  11203. %@AB@%XTYP_ACK%@NL@%
  11204. %@AB@%%@NL@%
  11205. %@AB@%   This notifies a server that it has received an acknowledge from data %@NL@%
  11206. %@AB@%   it has sent a client.  The hConv, topic, item, and format are set %@NL@%
  11207. %@AB@%   apropriately.  LOUSHORT(hDmgData) will contain the dde flags from the %@NL@%
  11208. %@AB@%   ack.  %@NL@%
  11209. %@AB@%%@NL@%
  11210. %@AB@%-----XCLASS_DATA class:%@NL@%
  11211. %@AB@%%@NL@%
  11212. %@AB@%   Transactions in this class are expected to return an HDMGDATA or 0 as %@NL@%
  11213. %@AB@%   apropriate.  %@NL@%
  11214. %@AB@%%@NL@%
  11215. %@AB@%XTYP_PKT%@NL@%
  11216. %@AB@%%@NL@%
  11217. %@AB@%   This transaction is sent to agent applications.  hDmgData contains a %@NL@%
  11218. %@AB@%   packet to send.  hszItem contains the agent handle to send the data %@NL@%
  11219. %@AB@%   to.  hConv is set to the associated conversation handle.  The return %@NL@%
  11220. %@AB@%   packet received from the partner agent should be returned.  This %@NL@%
  11221. %@AB@%   call is blockable.%@NL@%
  11222. %@AB@%%@NL@%
  11223. %@AB@%   If blocked, the conversation will be unblocked and processed by %@NL@%
  11224. %@AB@%   DdeProcessPkt() when the return packet is received.  It is a good %@NL@%
  11225. %@AB@%   idea for the agent to remember the hConv parameter in case the return %@NL@%
  11226. %@AB@%   packet does not arrive within a reasonable amount of time via %@NL@%
  11227. %@AB@%   XTYP_RTNPKT.  If an agent determines that it wishes to kill a %@NL@%
  11228. %@AB@%   conversation, it should call DdeDisconnect().  %@NL@%
  11229. %@AB@%%@NL@%
  11230. %@AB@%XTYP_REQUEST%@NL@%
  11231. %@AB@%XTYP_ADVREQ%@NL@%
  11232. %@AB@%%@NL@%
  11233. %@AB@%   Data is being requested from a server application.  The function %@NL@%
  11234. %@AB@%   should create a hDmgData using the DdePutData() function and %@NL@%
  11235. %@AB@%   return it.  XTYP_ADVREQ origonates from a DdePostAdvise() call %@NL@%
  11236. %@AB@%   while XTYP_REQUEST origonates from a client data request.  %@NL@%
  11237. %@AB@%%@NL@%
  11238. %@AB@%XTYP_WILDINIT%@NL@%
  11239. %@AB@%%@NL@%
  11240. %@AB@%   This is asking a DDE server permission to make multiple connections %@NL@%
  11241. %@AB@%   with a specific client.%@NL@%
  11242. %@AB@%%@NL@%
  11243. %@AB@%   hszItem may be the application name the client is requesting or it %@NL@%
  11244. %@AB@%   may be NULL indicating a wild application name.  hszTopic may be the %@NL@%
  11245. %@AB@%   Topic requested or NULL indicating a wild topic.  If not NULL, %@NL@%
  11246. %@AB@%   hDmgData contains a CONVCONTEXT structure.  All other parameters are %@NL@%
  11247. %@AB@%   0 or NULL.%@NL@%
  11248. %@AB@%%@NL@%
  11249. %@AB@%   For local initiates, (initiates with the server application itself) %@NL@%
  11250. %@AB@%   The server should return a 0 terminated (ie hszApp = hszTopic = 0) %@NL@%
  11251. %@AB@%   array of HSZPAIR structures using DdePutData() and %@NL@%
  11252. %@AB@%   DdeAddData().  Each hsz pair represents an app/topic the server %@NL@%
  11253. %@AB@%   wishes to support.  Each created conversation will result in an %@NL@%
  11254. %@AB@%   XTYP_INIT_CONFIRM notification.  If 0 is returned, no connections are %@NL@%
  11255. %@AB@%   made with the requesting client.  This call is made even if callbacks %@NL@%
  11256. %@AB@%   are disabled due the the synchronous nature of DDE initiates.  This %@NL@%
  11257. %@AB@%   callback cannot be blocked by returning CBR_BLOCK.  %@NL@%
  11258. %@AB@%%@NL@%
  11259. %@AB@%   Agent applications may also process this transaction as a %@NL@%
  11260. %@AB@%   representative initiate.  The agent is expected to package this %@NL@%
  11261. %@AB@%   transaction using DdeCreateInitPkt() and broadcast it to all %@NL@%
  11262. %@AB@%   apropriate agents along its communication channel.  It then must %@NL@%
  11263. %@AB@%   collect the return packets and for each packet and call %@NL@%
  11264. %@AB@%   DdeProcessPkt().  Representative initiates are synchronous in that %@NL@%
  11265. %@AB@%   the agent cannot return from this callback until all initiate return %@NL@%
  11266. %@AB@%   packets are returned.  Representative initiates do NOT result in any %@NL@%
  11267. %@AB@%   XTYP_INIT_CONFIRM notifications to the agent.  The agent is then free %@NL@%
  11268. %@AB@%   to process this transaction for local connections as described.  %@NL@%
  11269. %@AB@%%@NL@%
  11270. %@AB@%-----XCLASS_BOOL class:%@NL@%
  11271. %@AB@%%@NL@%
  11272. %@AB@%   Transactions in this class expect a BOOL return of TRUE or FALSE.  %@NL@%
  11273. %@AB@%%@NL@%
  11274. %@AB@%XTYP_INIT%@NL@%
  11275. %@AB@%%@NL@%
  11276. %@AB@%   This is a query asking a DDE server permission to connect to a %@NL@%
  11277. %@AB@%   specific client.  hszItem is set to the Application name.  hszTopic %@NL@%
  11278. %@AB@%   is set to the topic name.  hDmgData if not NULL, contains CONVCONTEXT %@NL@%
  11279. %@AB@%   data.  All other parameters are 0 or NULL.  A TRUE return value %@NL@%
  11280. %@AB@%   allows the Dde to start up a server on the app/topic specified.  %@NL@%
  11281. %@AB@%   This will result in an XTYP_INIT_CONFIRM callback.  This call is made %@NL@%
  11282. %@AB@%   even if callbacks are disabled due the the synchronous nature of DDE %@NL@%
  11283. %@AB@%   initiates.  %@NL@%
  11284. %@AB@%    %@NL@%
  11285. %@AB@%   Agent applications may process this transaction as a representative %@NL@%
  11286. %@AB@%   transaction.  The agent is expected to package this transaction using %@NL@%
  11287. %@AB@%   DdeCreateInitPkt() and broadcast it to all apropriate agents along %@NL@%
  11288. %@AB@%   its communication channel.  It then must collect the return packets %@NL@%
  11289. %@AB@%   and for each packet call DdeProcessPkt().  This will NOT result in %@NL@%
  11290. %@AB@%   any XTYP_INIT_CONFIRM notifications to the agent.  The agent is then %@NL@%
  11291. %@AB@%   free to process this transaction for local connections.  %@NL@%
  11292. %@AB@%%@NL@%
  11293. %@AB@%    A FALSE return implies no local initiate permissions are granted.%@NL@%
  11294. %@AB@%%@NL@%
  11295. %@AB@%XTYP_ADVSTART%@NL@%
  11296. %@AB@%%@NL@%
  11297. %@AB@%   This transaction requests permission to start a DDE advise loop with %@NL@%
  11298. %@AB@%   a server.  The hszTopic, hszItem, and usFormat identify the advise %@NL@%
  11299. %@AB@%   loop.  If FALSE is returned, the advise loop will not be started.  %@NL@%
  11300. %@AB@%%@NL@%
  11301. %@AB@%-----XCLASS_FLAGS Class:%@NL@%
  11302. %@AB@%%@NL@%
  11303. %@AB@%   Transactions in this class have hDmgData set.  An application should %@NL@%
  11304. %@AB@%   use the DLL Data functions to extract the data from hDmgData.  The %@NL@%
  11305. %@AB@%   return value should be the DDE fsStatus flags the app desires to %@NL@%
  11306. %@AB@%   return to the client application.  If DDE_FACK is set, DDE_FBUSY and %@NL@%
  11307. %@AB@%   DDE_FNOTPROCESSED are ignored.  %@NL@%
  11308. %@AB@%%@NL@%
  11309. %@AB@%   The only flags the Dde expects to be returned are:%@NL@%
  11310. %@AB@%        DDE_FACK%@NL@%
  11311. %@AB@%        DDE_FBUSY%@NL@%
  11312. %@AB@%        DDE_FNOTPROCESSED%@NL@%
  11313. %@AB@%        any DDE_APPSTATUS bits%@NL@%
  11314. %@AB@%        %@NL@%
  11315. %@AB@%   All other bits will be stripped out by the Dde before sending an %@NL@%
  11316. %@AB@%   ack message.  %@NL@%
  11317. %@AB@%%@NL@%
  11318. %@AB@%   A 0 return is equivalent to DDE_NOTPROCESSED.  %@NL@%
  11319. %@AB@%%@NL@%
  11320. %@AB@%XTYP_EXEC%@NL@%
  11321. %@AB@%%@NL@%
  11322. %@AB@%   hDmgData contains an execute string from a client.  hConv, hszTopic, %@NL@%
  11323. %@AB@%   hszItem are set.  If the WM_DDE_EXECUTE message received had the same %@NL@%
  11324. %@AB@%   string for the itemname as for the data, hszItem will be 0L.  This %@NL@%
  11325. %@AB@%   provides for EXCEL EXECUTE compatibility without requireing the %@NL@%
  11326. %@AB@%   creation of an HSZ for the data string.  Applications are advised to %@NL@%
  11327. %@AB@%   ignore the hszItem parameter for execute transactions since newer DDE %@NL@%
  11328. %@AB@%   specifications ignore this value.  %@NL@%
  11329. %@AB@%  %@NL@%
  11330. %@AB@%XTYP_POKE%@NL@%
  11331. %@AB@%%@NL@%
  11332. %@AB@%   Similar to XTYP_EXEC but hDmgData contains data poked to the server.  %@NL@%
  11333. %@AB@%  %@NL@%
  11334. %@AB@%XTYP_ADVDATA - advise data for a client!%@NL@%
  11335. %@AB@%%@NL@%
  11336. %@AB@%   Note that XTYP_ADVDATA is for advise loop data intended for the %@NL@%
  11337. %@AB@%   CLIENT not the server.  If the advise loop in progress is of the %@NL@%
  11338. %@AB@%   NODATA type, hDmgData will be 0.  %@NL@%
  11339. %@AB@%%@NL@%
  11340. %@AB@%-----Agent Transfers:%@NL@%
  11341. %@AB@%%@NL@%
  11342. %@AB@%   A DDE agent application is one which registers itself with the %@NL@%
  11343. %@AB@%   DMGCMD_AGENT flag.  Agent applications represent any number of other %@NL@%
  11344. %@AB@%   applications across its communications channel.  Agent applications %@NL@%
  11345. %@AB@%   are only allowed to communicate locally with other non-agent %@NL@%
  11346. %@AB@%   applications.  This prevents communication loops from forming across %@NL@%
  11347. %@AB@%   communication channels.  Any number of agents may register with the %@NL@%
  11348. %@AB@%   DLL but each agent should represent a different communication %@NL@%
  11349. %@AB@%   channel, one which is orthogonal to all other agents.  It is the %@NL@%
  11350. %@AB@%   users responsability to only start up orthogonal agents.  %@NL@%
  11351. %@AB@%%@NL@%
  11352. %@AB@%   Agents are responsible for handling and updating any DDE nameservers %@NL@%
  11353. %@AB@%   associated with their communicaton channels.  Since agent %@NL@%
  11354. %@AB@%   applications can converse directly with non-agent applications, they %@NL@%
  11355. %@AB@%   can set up advise loops on the SysTopic/Topics items of local %@NL@%
  11356. %@AB@%   applications to update the nameserver for the communication channel %@NL@%
  11357. %@AB@%   if they wish to support DDE topics.  This may be impossible with some %@NL@%
  11358. %@AB@%   DDE applications which either do not support the SysTopic/Topics item %@NL@%
  11359. %@AB@%   or which have an unenumerable set of topics they support.  For %@NL@%
  11360. %@AB@%   application name servers the DdeAppNameServer() function is %@NL@%
  11361. %@AB@%   provided to give agents a local application name server from which to %@NL@%
  11362. %@AB@%   draw on.  %@NL@%
  11363. %@AB@%%@NL@%
  11364. %@AB@%   In general, an agent administers two classes of conversations.  One %@NL@%
  11365. %@AB@%   is direct conversations with itself and local non-agent applications.  %@NL@%
  11366. %@AB@%   These transactions would be handled by the agent exactly like any %@NL@%
  11367. %@AB@%   non-agent application would handle them.  %@NL@%
  11368. %@AB@%%@NL@%
  11369. %@AB@%   The other class is representative conversations which the agent %@NL@%
  11370. %@AB@%   passes over its communication channel.  In general, representative %@NL@%
  11371. %@AB@%   conversation callbacks to the agent are only XTYP_PKT or XTYP_RTNPKT %@NL@%
  11372. %@AB@%   type transactions or specially handled initiate transactions.  %@NL@%
  11373. %@AB@%%@NL@%
  11374. %@AB@%   Agent applications are responsible for providing a unique ULONG agent %@NL@%
  11375. %@AB@%   handle for every agent it is communicating with on its communication %@NL@%
  11376. %@AB@%   channel.  The handle is provided by the agent whenever it calls %@NL@%
  11377. %@AB@%   DdeProcessPkt().  Agent handles need not be global to the channel %@NL@%
  11378. %@AB@%   since only the agent that created the handle will be expected to use %@NL@%
  11379. %@AB@%   it.  Agent handles should not change over the life of a conversation.%@NL@%
  11380. %@AB@%%@NL@%
  11381. %@AB@%   Should it be necessary to allow agents to alter or convert packet %@NL@%
  11382. %@AB@%   data, the format of the packets can be documented later.  %@NL@%
  11383. %@AB@%%@NL@%
  11384. %@AB@%   To show how an agent would handle its callback function, the %@NL@%
  11385. %@AB@%   following pseudo code is offered as a model: %@NL@%
  11386. %@AB@%%@NL@%
  11387. %@AB@%ReceivePkt(pBits, cb, hAgentFrom)    \\ gets called when a packet arrives %@NL@%
  11388. %@AB@%{%@NL@%
  11389. %@AB@%    hPkt = DdePutData(pBits, cb, 0, 0, 0, 0);%@NL@%
  11390. %@AB@%    if (hDmgData = ProcessPkt(hPkt, hAgentFrom))%@NL@%
  11391. %@AB@%        PassPkt(hDmgData, hAgentFrom);  \\ agent function to send pkt %@NL@%
  11392. %@AB@%}%@NL@%
  11393. %@AB@%    %@NL@%
  11394. %@AB@%AgentCallback(hConv, hszTopic, hszItem, usFormat, usType, hDmgData)%@NL@%
  11395. %@AB@%{%@NL@%
  11396. %@AB@%    switch (usType) {%@NL@%
  11397. %@AB@%    case XTYP_INIT:%@NL@%
  11398. %@AB@%    case XTYP_WILDINIT:%@NL@%
  11399. %@AB@%        \\%@NL@%
  11400. %@AB@%        \\ process representative initiates%@NL@%
  11401. %@AB@%        \\%@NL@%
  11402. %@AB@%        QueryInterestedAgents(hszApp, hszTopic, pAgents);%@NL@%
  11403. %@AB@%        hDmgData = DdeCreateInitPkt(hszTopic, hszItem, hDmgData);%@NL@%
  11404. %@AB@%        BroadcastPkt(hDmgData, pAgents);%@NL@%
  11405. %@AB@%        \\%@NL@%
  11406. %@AB@%        \\ agent blocks here till all are in or timeout.%@NL@%
  11407. %@AB@%        \\ Packets get sent to ReceivePkt()%@NL@%
  11408. %@AB@%        \\%@NL@%
  11409. %@AB@%        CollectRtnPkts(pAgents); %@NL@%
  11410. %@AB@%        \\  %@NL@%
  11411. %@AB@%        \\ now agent does his own processing of local inits.%@NL@%
  11412. %@AB@%        \\ retval == 0 if not interested.%@NL@%
  11413. %@AB@%        \\%@NL@%
  11414. %@AB@%        return(retval);%@NL@%
  11415. %@AB@%        break;%@NL@%
  11416. %@AB@%%@NL@%
  11417. %@AB@%    case XTYP_RTNPKT:%@NL@%
  11418. %@AB@%        RemoveFromDeadCheckQ(hConv);%@NL@%
  11419. %@AB@%        PassPkt(hDmgData, hszItem); \\ hDmgData==Pkt, hszItem==hAgentTo %@NL@%
  11420. %@AB@%        return(0);%@NL@%
  11421. %@AB@%        break;%@NL@%
  11422. %@AB@%        %@NL@%
  11423. %@AB@%    case XTYP_PKT:%@NL@%
  11424. %@AB@%        if (FindIgnoreList(hConv) { \\ was this unblocked due to no rtn pkt? %@NL@%
  11425. %@AB@%            RemoveFromIgnoreList(hConv);%@NL@%
  11426. %@AB@%            return(0);  \\ rtn pkt failure.%@NL@%
  11427. %@AB@%        }%@NL@%
  11428. %@AB@%        if (!PassPkt(hDmgData, hszItem))  \\ hDmgData==Pkt, hszItem==hAgentTo %@NL@%
  11429. %@AB@%            return(0);  \\ packet send failure. %@NL@%
  11430. %@AB@%        AddToDeadCheckQ(hConv, timenow());%@NL@%
  11431. %@AB@%        return(CBR_BLOCK);  \\ will be unblocked and handled by ProcessPkt() %@NL@%
  11432. %@AB@%        break;%@NL@%
  11433. %@AB@%%@NL@%
  11434. %@AB@%    case XTYP_REGISTER:%@NL@%
  11435. %@AB@%    case XTYP_UNREGISTER:%@NL@%
  11436. %@AB@%        \\%@NL@%
  11437. %@AB@%        \\ agent updates its communications name server.%@NL@%
  11438. %@AB@%        \\%@NL@%
  11439. %@AB@%        return(0);%@NL@%
  11440. %@AB@%        break;%@NL@%
  11441. %@AB@%%@NL@%
  11442. %@AB@%    default:%@NL@%
  11443. %@AB@%        \\%@NL@%
  11444. %@AB@%        \\ the rest would reference local conversatoins that the agent%@NL@%
  11445. %@AB@%        \\ is maintaining.%@NL@%
  11446. %@AB@%        \\%@NL@%
  11447. %@AB@%        break;%@NL@%
  11448. %@AB@%    }%@NL@%
  11449. %@AB@%}%@NL@%
  11450. %@AB@%%@NL@%
  11451. %@AB@%UnblockDeadTransaction(hConv) \\ called when no rtn pkt for hConv has been%@NL@%
  11452. %@AB@%                              \\ received for a long time. %@NL@%
  11453. %@AB@%{%@NL@%
  11454. %@AB@%    RemoveFromDeadCheckQ(hConv);%@NL@%
  11455. %@AB@%    AddToIgnoreList(hConv);%@NL@%
  11456. %@AB@%    DdeEnableCallback(CBK_ENABLE, hConv);%@NL@%
  11457. %@AB@%}%@NL@%
  11458. %@AB@%%@NL@%
  11459. %@AB@%\* PUBDOC END */%@AE@%%@NL@%
  11460. %@NL@%
  11461. %@NL@%
  11462. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  11463. %@AB@%* PUBDOC START%@NL@%
  11464. %@AB@%* USHORT EXPENTRY DdeInitialize(pfnCallback, afCmd, ulRes)%@NL@%
  11465. %@AB@%* PFNCALLBACK pfnCallback;  // address to application callback function%@NL@%
  11466. %@AB@%* ULONG afCmd;              // registration command flags%@NL@%
  11467. %@AB@%* ULONG ulRes;              // currently reserved, must be 0L.%@NL@%
  11468. %@AB@%* %@NL@%
  11469. %@AB@%*     This API is used to initialize the DDEML for an application thread.%@NL@%
  11470. %@AB@%* %@NL@%
  11471. %@AB@%*     afCmd - is a set of DMGCMD_ flags for special initialization instructions.%@NL@%
  11472. %@AB@%* %@NL@%
  11473. %@AB@%*     DMGCMD_AGENT%@NL@%
  11474. %@AB@%*         The registering application represents more than one DDE application.%@NL@%
  11475. %@AB@%*         Agents are never allowed to establish a conversation with%@NL@%
  11476. %@AB@%*         another agent.  See Agent Transactions.%@NL@%
  11477. %@AB@%* %@NL@%
  11478. %@AB@%*     DMGCMD_MONITOR%@NL@%
  11479. %@AB@%*%@NL@%
  11480. %@AB@%*         This defines the registered application as a DDE transaction %@NL@%
  11481. %@AB@%*         monitor.  This is primarily used for debugging DDE %@NL@%
  11482. %@AB@%*         applications.  A monitoring application will have its Callback %@NL@%
  11483. %@AB@%*         function called every time a DDE message is sent.%@NL@%
  11484. %@AB@%* %@NL@%
  11485. %@AB@%*         This flag is exclusive of all others.  No other flags should be%@NL@%
  11486. %@AB@%*         or'ed in with this one.%@NL@%
  11487. %@AB@%* %@NL@%
  11488. %@AB@%*    DMGCMD_CLIENTONLY%@NL@%
  11489. %@AB@%*        This should be specified when the application only intends to%@NL@%
  11490. %@AB@%*        be a DDE client.  This reduces the resource consumption of the DLL.%@NL@%
  11491. %@AB@%*        %@NL@%
  11492. %@AB@%*     Registration is on a per-thread basis.  Thus a multi-threaded application%@NL@%
  11493. %@AB@%*     could register several threads as seperate DDE entities.  %@NL@%
  11494. %@AB@%* %@NL@%
  11495. %@AB@%*     returns any applicable DMGERR_ error code or 0 on success.%@NL@%
  11496. %@AB@%*%@NL@%
  11497. %@AB@%*     Most other DLL APIs will fail if the calling thread has not called this.%@NL@%
  11498. %@AB@%* %@NL@%
  11499. %@AB@%* PUBDOC END%@NL@%
  11500. %@AB@%* %@NL@%
  11501. %@AB@%* Registration causes the following windows to be created:%@NL@%
  11502. %@AB@%* %@NL@%
  11503. %@AB@%* HWND_OBJECT%@NL@%
  11504. %@AB@%*   hwndDmg(s)%@NL@%
  11505. %@AB@%*       hwndClient(s)%@NL@%
  11506. %@AB@%*   hwndTopicServer(s)%@NL@%
  11507. %@AB@%*       hwndServer(s)%@NL@%
  11508. %@AB@%*   hwndMonitor(s)%@NL@%
  11509. %@AB@%* HWND_DESKTOP%@NL@%
  11510. %@AB@%*   hwndFrame(s)%@NL@%
  11511. %@AB@%* %@NL@%
  11512. %@AB@%*   See api.doc file for usage info.%@NL@%
  11513. %@AB@%* %@NL@%
  11514. %@AB@%* History:%@NL@%
  11515. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  11516. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  11517. USHORT EXPENTRY DdeInitialize(pfnCallback, afCmd, ulRes)%@NL@%
  11518. PFNCALLBACK pfnCallback;%@NL@%
  11519. ULONG afCmd;%@NL@%
  11520. ULONG ulRes; %@NL@%
  11521. {%@NL@%
  11522.     if (ulRes != 0L || CheckSel(SELECTOROF(pfnCallback)) == 0)%@NL@%
  11523.         return(DMGERR_INVALIDPARAMETER);%@NL@%
  11524. %@NL@%
  11525.     return(Register(pfnCallback, afCmd, ulRes, FALSE));%@NL@%
  11526. }%@NL@%
  11527. %@NL@%
  11528. %@NL@%
  11529. %@NL@%
  11530. USHORT EXPENTRY Register(pfnCallback, afCmd, ulRes, f32bit)%@NL@%
  11531. PFNCALLBACK pfnCallback;%@NL@%
  11532. ULONG afCmd;%@NL@%
  11533. ULONG ulRes;%@NL@%
  11534. BOOL f32bit;    %@AB@%/* set if calling app is a 32bit app. */%@AE@%%@NL@%
  11535. {%@NL@%
  11536.     BOOL        fInit;%@NL@%
  11537.     PAPPINFO    pai = 0L, paiT;%@NL@%
  11538.     PIDINFO     pidInfo;%@NL@%
  11539.     USHORT      usRet = DMGERR_PMWIN_ERROR;%@NL@%
  11540.     ULONG       ctlFlags;%@NL@%
  11541.     CLASSINFO   ci;%@NL@%
  11542.     USHORT      cb;%@NL@%
  11543. %@NL@%
  11544.     UNUSED ulRes;%@NL@%
  11545. %@NL@%
  11546.     SemEnter();%@NL@%
  11547.     if (fInit = (hheapDmg == 0L)) {%@NL@%
  11548.         %@AB@%/*%@NL@%
  11549. %@AB@%         * First time only%@NL@%
  11550. %@AB@%         */%@AE@%%@NL@%
  11551.         syscc.codepage = syscc.country = 0;%@NL@%
  11552.         DosGetCtryInfo(sizeof(COUNTRYCODE), &syscc, (PCOUNTRYINFO)&syscc, &cb);%@NL@%
  11553.         if (DosGetHugeShift(&usHugeShift))%@NL@%
  11554.             goto Abort;%@NL@%
  11555.         usHugeAdd = (1 << usHugeShift) - 1;%@NL@%
  11556.         if (!(hheapDmg = MyCreateHeap(0, 4096, 0, 0, 0, HEAPFLAGS)))%@NL@%
  11557.             goto Abort;%@NL@%
  11558.         if (!WinQueryClassInfo(DMGHAB, WC_FRAME, &ci))%@NL@%
  11559.             goto Abort;%@NL@%
  11560.         lpfnFrameWndProc = ci.pfnWindowProc;%@NL@%
  11561.         if (!AddAtomTable(TRUE)) %@NL@%
  11562.             goto Abort;%@NL@%
  11563.     } else {%@NL@%
  11564.         %@NL@%
  11565.         if ((pai = GetCurrentAppInfo(FALSE)) != NULL) {%@NL@%
  11566.             %@AB@%/*%@NL@%
  11567. %@AB@%             * re-registration%@NL@%
  11568. %@AB@%             */%@AE@%%@NL@%
  11569.             return(DMGERR_DLL_USAGE);%@NL@%
  11570.         }%@NL@%
  11571.         %@NL@%
  11572.         %@AB@%/*%@NL@%
  11573. %@AB@%         * share the main heap with this process.%@NL@%
  11574. %@AB@%         */%@AE@%%@NL@%
  11575.         if (DosGetSeg(SELECTOROF(hheapDmg))) {%@NL@%
  11576.             SemLeave();%@NL@%
  11577.             return(DMGERR_PMWIN_ERROR);%@NL@%
  11578.         }%@NL@%
  11579.     }%@NL@%
  11580. %@NL@%
  11581.         %@NL@%
  11582.     if (DosGetPID(&pidInfo))%@NL@%
  11583.         goto Abort;%@NL@%
  11584. %@NL@%
  11585.     if (!(pai = (PAPPINFO)FarAllocMem(hheapDmg, sizeof(APPINFO))))%@NL@%
  11586.         goto Abort;%@NL@%
  11587.         %@NL@%
  11588.     if (!(pai->hheapApp = MyCreateHeap(0, 4096, 0, 0, 0, HEAPFLAGS))) {%@NL@%
  11589.         FarFreeMem(hheapDmg, pai, sizeof(APPINFO));%@NL@%
  11590.         pai = 0L;%@NL@%
  11591.         goto Abort;%@NL@%
  11592.     }%@NL@%
  11593. %@NL@%
  11594.     pai->pAppNamePile = NULL;   %@AB@%/* responds to nothing */%@AE@%%@NL@%
  11595.     pai->pSvrTopicList = CreateLst(pai->hheapApp, sizeof(HWNDHSZLI));%@NL@%
  11596.     pai->pHDataPile = CreatePile(pai->hheapApp, sizeof(HDMGDATA), 8);%@NL@%
  11597.     pai->afCmd = (USHORT)afCmd | (f32bit ? DMGCMD_32BIT : 0);%@NL@%
  11598.     pai->hwndDmg =%@NL@%
  11599.     pai->hwndFrame =%@NL@%
  11600.     pai->hwndMonitor =%@NL@%
  11601.     pai->hwndTimer = 0;%@NL@%
  11602.     pai->pid = pidInfo.pid;%@NL@%
  11603.     pai->tid = pidInfo.tid;%@NL@%
  11604.     pai->pfnCallback = pfnCallback;%@NL@%
  11605.     pai->cInCallback = 0;%@NL@%
  11606.     pai->LastError = DMGERR_NO_ERROR;%@NL@%
  11607.     pai->fEnableCB = TRUE;%@NL@%
  11608.     pai->plstCB = CreateLst(pai->hheapApp, sizeof(CBLI));%@NL@%
  11609.     pai->plstCBExceptions = NULL;%@NL@%
  11610. %@NL@%
  11611.     %@AB@%/*%@NL@%
  11612. %@AB@%     * make nextThread link.%@NL@%
  11613. %@AB@%     */%@AE@%%@NL@%
  11614.     paiT = pAppInfoList;%@NL@%
  11615.     while (paiT && paiT->pid != pai->pid) {%@NL@%
  11616.         paiT = paiT->next;%@NL@%
  11617.     }%@NL@%
  11618.     pai->nextThread = paiT; %@AB@%/* paiT is NULL or of the same process */%@AE@%%@NL@%
  11619.     %@NL@%
  11620.     if (paiT) {%@NL@%
  11621.         while (paiT->nextThread->tid != pai->nextThread->tid) {%@NL@%
  11622.             paiT = paiT->nextThread;%@NL@%
  11623.         }%@NL@%
  11624.         paiT->nextThread = pai;%@NL@%
  11625.     } else {%@NL@%
  11626.         %@AB@%/*%@NL@%
  11627. %@AB@%         * We must reregister each class for each process that invokes this%@NL@%
  11628. %@AB@%         * DLL because we can't register public classes unless we are the%@NL@%
  11629. %@AB@%         * shell.%@NL@%
  11630. %@AB@%         * Since pai->nextThread is NULL, this is a new process.%@NL@%
  11631. %@AB@%         */%@AE@%%@NL@%
  11632.         WinRegisterClass(0, SZCLIENTCLASS, ClientWndProc, 0L, 4);%@NL@%
  11633.         WinRegisterClass(0, SZSERVERCLASS, ServerWndProc, 0L, 4);%@NL@%
  11634.         WinRegisterClass(0, SZDMGCLASS, DmgWndProc, 0L, 4);%@NL@%
  11635.         WinRegisterClass(0, SZDEFCLASS, WinDefWindowProc, 0L, 4);%@NL@%
  11636.     }%@NL@%
  11637.     %@NL@%
  11638.     pai->next = pAppInfoList;%@NL@%
  11639.     pAppInfoList = pai;%@NL@%
  11640.     %@NL@%
  11641.     if ((pai->hwndDmg = WinCreateWindow(HWND_OBJECT, SZDMGCLASS, "", 0L,%@NL@%
  11642.             0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_APPROOT, 0L, 0L)) == 0L) {%@NL@%
  11643.         goto Abort;%@NL@%
  11644.     }%@NL@%
  11645. %@NL@%
  11646.     if (pai->afCmd & DMGCMD_MONITOR) {%@NL@%
  11647.         WinRegisterClass(0, SZMONITORCLASS, MonitorWndProc, 0L, 4);%@NL@%
  11648.         if ((pai->hwndMonitor = WinCreateWindow(HWND_OBJECT, SZMONITORCLASS, NULL,%@NL@%
  11649.                 0L, 0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_MONITOR, 0L, 0L))%@NL@%
  11650.                 == 0L) {%@NL@%
  11651.             goto Abort;%@NL@%
  11652.         }%@NL@%
  11653.         if (++cMonitor) {%@NL@%
  11654.             WinSetHook(DMGHAB, NULL, HK_INPUT, (PFN)DdePostHookProc, hmodDmg);%@NL@%
  11655.             WinSetHook(DMGHAB, NULL, HK_SENDMSG, (PFN)DdeSendHookProc, hmodDmg);%@NL@%
  11656.         }%@NL@%
  11657.     }%@NL@%
  11658. %@NL@%
  11659.     %@AB@%/*%@NL@%
  11660. %@AB@%     * create an invisible top-level frame for initiates. (if server ok)%@NL@%
  11661. %@AB@%     */%@AE@%%@NL@%
  11662.     usRet = DMGERR_PMWIN_ERROR;%@NL@%
  11663.     if (!(afCmd & DMGCMD_CLIENTONLY)) {%@NL@%
  11664.         ctlFlags = 0;%@NL@%
  11665.         if ((pai->hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0L, &ctlFlags,%@NL@%
  11666.                 (PSZ)NULL, "", 0L, (HMODULE)NULL, 0, (PHWND)NULL)) == (HWND)NULL)%@NL@%
  11667.             goto Abort;%@NL@%
  11668.         WinSubclassWindow(pai->hwndFrame, subframeWndProc);%@NL@%
  11669.     }%@NL@%
  11670. %@NL@%
  11671.     DosExitList(EXLST_ADD, (PFNEXITLIST)ExlstAbort);%@NL@%
  11672. %@NL@%
  11673.     SemLeave();%@NL@%
  11674. %@NL@%
  11675.     return(DMGERR_NO_ERROR);%@NL@%
  11676. %@NL@%
  11677. Abort:%@NL@%
  11678.     SemLeave();%@NL@%
  11679. %@NL@%
  11680.     if (pai)%@NL@%
  11681.         DdeUninitialize();%@NL@%
  11682.     else if (fInit && hheapDmg)%@NL@%
  11683.         hheapDmg = MyDestroyHeap(hheapDmg);%@NL@%
  11684.     return(usRet);%@NL@%
  11685. }%@NL@%
  11686. %@NL@%
  11687. %@NL@%
  11688. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  11689. %@AB@%* PUBDOC START%@NL@%
  11690. %@AB@%* BOOL EXPENTRY DdeUninitialize(void);%@NL@%
  11691. %@AB@%*     This uninitializes an application thread from the DDEML.%@NL@%
  11692. %@AB@%*     All DLL resources associated with the application are destroyed.%@NL@%
  11693. %@AB@%*     Most other APIs will fail if called after this API by the same thread.%@NL@%
  11694. %@AB@%*%@NL@%
  11695. %@AB@%* PUBDOC END%@NL@%
  11696. %@AB@%*%@NL@%
  11697. %@AB@%* History:%@NL@%
  11698. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  11699. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  11700. BOOL EXPENTRY DdeUninitialize()%@NL@%
  11701. {%@NL@%
  11702.     PAPPINFO pai, paiT;%@NL@%
  11703.     PMYDDES pmyddes;%@NL@%
  11704.     PIDINFO pi;%@NL@%
  11705. %@NL@%
  11706.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  11707.         return(FALSE);%@NL@%
  11708. %@NL@%
  11709.     DosExitList(EXLST_REMOVE, (PFNEXITLIST)ExlstAbort);%@NL@%
  11710.     %@NL@%
  11711.     %@AB@%/*%@NL@%
  11712. %@AB@%     * get us out of the semaphore!%@NL@%
  11713. %@AB@%     * !!! NOTE: semaphore tid id -1 during exitlist processing!%@NL@%
  11714. %@AB@%     */%@AE@%%@NL@%
  11715.     DosGetPID(&pi);%@NL@%
  11716.     if (FSRSemDmg.cUsage > 0 && FSRSemDmg.pid == pi.pid &&%@NL@%
  11717.             (FSRSemDmg.tid == pi.tid || FSRSemDmg.tid == -1)) {%@NL@%
  11718.         while (FSRSemDmg.cUsage) {%@NL@%
  11719.             SemLeave();%@NL@%
  11720.         }%@NL@%
  11721.     }%@NL@%
  11722.     %@NL@%
  11723.     if (pai->hwndTimer)%@NL@%
  11724.         WinSendMsg(pai->hwndTimer, WM_TIMER, MPFROMSHORT(TID_ABORT), 0L);%@NL@%
  11725. %@NL@%
  11726.     if (pai->hwndMonitor) {%@NL@%
  11727.         DestroyWindow(pai->hwndMonitor);%@NL@%
  11728.         if (!--cMonitor) {%@NL@%
  11729.             WinReleaseHook(DMGHAB, NULL, HK_INPUT, (PFN)DdePostHookProc, hmodDmg);%@NL@%
  11730.             WinReleaseHook(DMGHAB, NULL, HK_SENDMSG, (PFN)DdeSendHookProc, hmodDmg);%@NL@%
  11731.         }%@NL@%
  11732.     }%@NL@%
  11733. %@NL@%
  11734.     %@AB@%/*%@NL@%
  11735. %@AB@%     * inform others of DeRegistration%@NL@%
  11736. %@AB@%     */%@AE@%%@NL@%
  11737.     if (pai->pAppNamePile != NULL) %@NL@%
  11738.         DdeAppNameServer(NULL, ANS_UNREGISTER);%@NL@%
  11739.         %@NL@%
  11740.     UnlinkAppInfo(pai);%@NL@%
  11741. %@NL@%
  11742.     DestroyWindow(pai->hwndDmg);%@NL@%
  11743.     DestroyWindow(pai->hwndFrame);%@NL@%
  11744.     DestroyHwndHszList(pai->pSvrTopicList);%@NL@%
  11745.     while (PopPileSubitem(pai->pHDataPile, (PBYTE)&pmyddes)) {%@NL@%
  11746.         if (CheckSel(SELECTOROF(pmyddes)) > sizeof(MYDDES) &&%@NL@%
  11747.                 pmyddes->magic == MYDDESMAGIC &&%@NL@%
  11748.                 pmyddes->pai == pai) {%@NL@%
  11749.             pmyddes->fs &= ~HDATA_APPOWNED;%@NL@%
  11750.         }%@NL@%
  11751.         FreeData(pmyddes, pai);%@NL@%
  11752.     }%@NL@%
  11753.     DestroyPile(pai->pHDataPile);%@NL@%
  11754.     if (pai->nextThread) {%@NL@%
  11755.         paiT = pai;%@NL@%
  11756.         while (paiT->nextThread != pai) {%@NL@%
  11757.             paiT = paiT->nextThread;%@NL@%
  11758.         } %@NL@%
  11759.         paiT->nextThread = pai->nextThread;%@NL@%
  11760.         if (paiT->nextThread == paiT) {%@NL@%
  11761.             paiT->nextThread = NULL;%@NL@%
  11762.         }%@NL@%
  11763.     }%@NL@%
  11764.     MyDestroyHeap(pai->hheapApp);%@NL@%
  11765.     %@NL@%
  11766.     DestroyPile(pai->pAppNamePile);%@NL@%
  11767.     FarFreeMem(hheapDmg, (PBYTE)pai, sizeof(APPINFO));%@NL@%
  11768. %@NL@%
  11769.     if (pAppInfoList == NULL) {     %@AB@%/* last guy out? - turn the lights out. */%@AE@%%@NL@%
  11770.         while (cAtbls--)%@NL@%
  11771.             WinDestroyAtomTable(aAtbls[cAtbls]);%@NL@%
  11772.         hheapDmg = MyDestroyHeap(hheapDmg);%@NL@%
  11773.     } else %@NL@%
  11774.         DosFreeSeg(SELECTOROF(hheapDmg));%@NL@%
  11775. %@NL@%
  11776.     SemCheckOut();%@NL@%
  11777. %@NL@%
  11778.     return(TRUE);%@NL@%
  11779. }%@NL@%
  11780. %@NL@%
  11781. %@NL@%
  11782. %@NL@%
  11783. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  11784. %@AB@%* PUBDOC START%@NL@%
  11785. %@AB@%* HCONVLIST EXPENTRY DdeBeginEnumServers(%@NL@%
  11786. %@AB@%* HSZ hszAppName,    // app name to connect to, NULL is wild.                   %@NL@%
  11787. %@AB@%* HSZ hszTopic,      // topic name to connect to, NULL is wild.                 %@NL@%
  11788. %@AB@%* HCONV hConvList,   // previous hConvList for reenumeration, NULL for initial. %@NL@%
  11789. %@AB@%* PCONVCONTEXT pCC,  // language info or NULL for system default.               %@NL@%
  11790. %@AB@%* HAPP hApp);        // target application handle or NULL for broadcast init.   %@NL@%
  11791. %@AB@%*%@NL@%
  11792. %@AB@%*   hszAppName - the DDE application name to connect to - may be 0 for wild.%@NL@%
  11793. %@AB@%*   hszTopic - the DDE topic name to connect to - may be 0 for wild.%@NL@%
  11794. %@AB@%*   hConvList - The conversation list handle to use for reenumeration.%@NL@%
  11795. %@AB@%*       If this is 0, a new hConvList is created.%@NL@%
  11796. %@AB@%*   pCC - pointer to CONVCONTEXT structure which provides conversation%@NL@%
  11797. %@AB@%*       information needed for international support.  All DDEFMT_TEXT%@NL@%
  11798. %@AB@%*       strings within any conversation started by this call should use%@NL@%
  11799. %@AB@%*       the codepage referenced in this structure.%@NL@%
  11800. %@AB@%*       If NULL is given, the current system values are used.%@NL@%
  11801. %@AB@%*   hApp - if not NULL, this directs initiates to only be sent to hApp.%@NL@%
  11802. %@AB@%*%@NL@%
  11803. %@AB@%*       This routine connects all available conversations on the given %@NL@%
  11804. %@AB@%*       app/topic pair.  Hsz values of 0 indicate wild names.  On reenumeration%@NL@%
  11805. %@AB@%*       old hConv's are kept and any new ones created are added to the%@NL@%
  11806. %@AB@%*       list.  Duplicate connections are avoided where possible.  A%@NL@%
  11807. %@AB@%*       duplicate connection is one which is to the same process and%@NL@%
  11808. %@AB@%*       thread on the same application/topic names.  If hApp is provided,%@NL@%
  11809. %@AB@%*       initiates are given only to that application.%@NL@%
  11810. %@AB@%*       Reenumeration is primarily intended as a response%@NL@%
  11811. %@AB@%*       to registration of a new app name to the system.  Reenumeration%@NL@%
  11812. %@AB@%*       also removes any terminated conversations from the list.%@NL@%
  11813. %@AB@%*%@NL@%
  11814. %@AB@%*   returns NULL on failure, hConvList on success.%@NL@%
  11815. %@AB@%*%@NL@%
  11816. %@AB@%* PUBDOC END%@NL@%
  11817. %@AB@%*%@NL@%
  11818. %@AB@%* History:%@NL@%
  11819. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  11820. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  11821. HCONVLIST EXPENTRY DdeBeginEnumServers(hszAppName, hszTopic, hConvList,%@NL@%
  11822.         pCC, hApp)%@NL@%
  11823. HSZ hszAppName;     %@NL@%
  11824. HSZ hszTopic;       %@NL@%
  11825. HWND hConvList;     %@NL@%
  11826. PCONVCONTEXT pCC;   %@NL@%
  11827. HAPP hApp;          %@NL@%
  11828. {%@NL@%
  11829.     PAPPINFO            pai;%@NL@%
  11830.     HCONV               hConv, hConvNext, hConvNew;%@NL@%
  11831.     HCONVLIST           hConvListNew;%@NL@%
  11832.     PCLIENTINFO         pciOld, pciNew;%@NL@%
  11833.     PID                 pidOld, pidNew;%@NL@%
  11834.     TID                 tidOld, tidNew;%@NL@%
  11835. %@NL@%
  11836.     if ((pai = GetCurrentAppInfo(TRUE)) == 0)%@NL@%
  11837.         return(0);%@NL@%
  11838. %@NL@%
  11839.     %@AB@%/*%@NL@%
  11840. %@AB@%     * destroy any dead old clients%@NL@%
  11841. %@AB@%     */%@AE@%%@NL@%
  11842.     if (hConvList) {%@NL@%
  11843.         hConv = WinQueryWindow(hConvList, QW_TOP, FALSE);%@NL@%
  11844.         while (hConv != NULL) {%@NL@%
  11845.             hConvNext = WinQueryWindow(hConv, QW_NEXT, FALSE);%@NL@%
  11846.             if (!((USHORT)WinSendMsg(hConv, UM_QUERY, MPFROMSHORT(Q_STATUS), 0L) &%@NL@%
  11847.                     ST_CONNECTED))%@NL@%
  11848.                 WinDestroyWindow(hConv);%@NL@%
  11849.             hConv = hConvNext;%@NL@%
  11850.         }%@NL@%
  11851.     }%@NL@%
  11852.     %@NL@%
  11853.     if ((hConvListNew = WinCreateWindow(pai->hwndDmg, SZDEFCLASS, "", 0L,%@NL@%
  11854.             0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_CLROOT, 0L, 0L)) == NULL) {%@NL@%
  11855.         pai->LastError = DMGERR_PMWIN_ERROR;%@NL@%
  11856.         return(0L);%@NL@%
  11857.     }%@NL@%
  11858.     %@NL@%
  11859.     hConvNew = GetDDEClientWindow(hConvListNew, (HWND)hApp, NULL, hszAppName,%@NL@%
  11860.             hszTopic, pCC);%@NL@%
  11861. %@NL@%
  11862.     %@AB@%/*%@NL@%
  11863. %@AB@%     * If no new hConvs created, quit now.%@NL@%
  11864. %@AB@%     */%@AE@%%@NL@%
  11865.     if (hConvNew == NULL) {%@NL@%
  11866.         if (hConvList && WinQueryWindow(hConvList, QW_TOP, FALSE) == NULL) {%@NL@%
  11867.             DestroyWindow(hConvList);%@NL@%
  11868.             hConvList = NULL;%@NL@%
  11869.         }%@NL@%
  11870.         if (hConvList == NULL)%@NL@%
  11871.             pai->LastError = DMGERR_NO_CONV_ESTABLISHED;%@NL@%
  11872.         return(hConvList);%@NL@%
  11873.     }%@NL@%
  11874. %@NL@%
  11875.     %@AB@%/*%@NL@%
  11876. %@AB@%     * remove any new ones that duplicate old existing ones%@NL@%
  11877. %@AB@%     */%@AE@%%@NL@%
  11878.     if (hConvList && (hConv = WinQueryWindow(hConvList, QW_TOP, FALSE))) {%@NL@%
  11879.         while (hConv) {%@NL@%
  11880.             hConvNext = WinQueryWindow(hConv, QW_NEXT, FALSE);%@NL@%
  11881.             pciOld = (PCLIENTINFO)WinQueryWindowULong(hConv, QWL_USER);%@NL@%
  11882.             if (!WinIsWindow(DMGHAB, pciOld->ci.hwndPartner)) {%@NL@%
  11883.                 WinDestroyWindow(hConv);%@NL@%
  11884.                 hConv = hConvNext;%@NL@%
  11885.                 continue;%@NL@%
  11886.             }%@NL@%
  11887.             WinQueryWindowProcess(pciOld->ci.hwndPartner, &pidOld, &tidOld);%@NL@%
  11888.             %@AB@%/*%@NL@%
  11889. %@AB@%             * destroy any new clients that are duplicates of the old ones.%@NL@%
  11890. %@AB@%             */%@AE@%%@NL@%
  11891.             hConvNew = WinQueryWindow(hConvListNew, QW_TOP, FALSE);%@NL@%
  11892.             while (hConvNew) {%@NL@%
  11893.                 hConvNext = WinQueryWindow(hConvNew, QW_NEXT, FALSE);%@NL@%
  11894.                 pciNew = (PCLIENTINFO)WinQueryWindowULong(hConvNew, QWL_USER);%@NL@%
  11895.                 WinQueryWindowProcess(pciNew->ci.hwndPartner, &pidNew, &tidNew);%@NL@%
  11896.                 if (pciOld->ci.hszServerApp == pciNew->ci.hszServerApp &&%@NL@%
  11897.                         pciOld->ci.hszTopic == pciNew->ci.hszTopic &&%@NL@%
  11898.                         pidOld == pidNew &&%@NL@%
  11899.                         tidOld == tidNew) {%@NL@%
  11900.                     %@AB@%/*%@NL@%
  11901. %@AB@%                     * assume same app, same topic, same process, same thread%@NL@%
  11902. %@AB@%                     * is a duplicate.%@NL@%
  11903. %@AB@%                     */%@AE@%%@NL@%
  11904.                     WinDestroyWindow(hConvNew);%@NL@%
  11905.                 }%@NL@%
  11906.                 hConvNew = hConvNext;%@NL@%
  11907.             }%@NL@%
  11908.             %@AB@%/*%@NL@%
  11909. %@AB@%             * move the unique old client to the new list%@NL@%
  11910. %@AB@%             */%@AE@%%@NL@%
  11911.             WinSetParent(hConv, hConvListNew, FALSE);%@NL@%
  11912.             hConv = hConvNext;%@NL@%
  11913.         }%@NL@%
  11914.         WinDestroyWindow(hConvList);%@NL@%
  11915.     }%@NL@%
  11916.     %@NL@%
  11917.     %@AB@%/*%@NL@%
  11918. %@AB@%     * If none are left, fail because no conversations were established.%@NL@%
  11919. %@AB@%     */%@AE@%%@NL@%
  11920.     if (WinQueryWindow(hConvListNew, QW_TOP, FALSE) == NULL) {%@NL@%
  11921.         DestroyWindow(hConvListNew);%@NL@%
  11922.         pai->LastError = DMGERR_NO_CONV_ESTABLISHED;%@NL@%
  11923.         return(NULL);%@NL@%
  11924.     } else {%@NL@%
  11925.         return(hConvListNew);%@NL@%
  11926.     }%@NL@%
  11927. }%@NL@%
  11928. %@NL@%
  11929. %@NL@%
  11930. %@NL@%
  11931. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  11932. %@AB@%* PUBDOC START%@NL@%
  11933. %@AB@%* HCONV EXPENTRY DdeGetNextServer(%@NL@%
  11934. %@AB@%* HCONVLIST hConvList,  // conversation list being traversed%@NL@%
  11935. %@AB@%* HCONV hConvPrev)      // previous conversation extracted or NULL for first%@NL@%
  11936. %@AB@%*%@NL@%
  11937. %@AB@%* hConvList - handle of conversation list returned by DdeBeginEnumServers().%@NL@%
  11938. %@AB@%* hConvPrev - previous hConv returned by this API or 0 to start from the top%@NL@%
  11939. %@AB@%*   of hConvList.%@NL@%
  11940. %@AB@%*%@NL@%
  11941. %@AB@%* This API returns the next conversation handle associated with hConvList.%@NL@%
  11942. %@AB@%* A 0 is returned if hConvPrev was the last conversation or if hConvList%@NL@%
  11943. %@AB@%* has no active conversations within it.%@NL@%
  11944. %@AB@%*%@NL@%
  11945. %@AB@%* PUBDOC END%@NL@%
  11946. %@AB@%*%@NL@%
  11947. %@AB@%* History:%@NL@%
  11948. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  11949. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  11950. HCONV EXPENTRY DdeGetNextServer(hConvList, hConvPrev)%@NL@%
  11951. HCONVLIST hConvList;%@NL@%
  11952. HCONV hConvPrev;%@NL@%
  11953. {%@NL@%
  11954.     if (!WinIsWindow(DMGHAB, hConvList))%@NL@%
  11955.         return(NULL);%@NL@%
  11956.     if (hConvPrev == NULL)%@NL@%
  11957.         return(WinQueryWindow(hConvList, QW_TOP, FALSE));%@NL@%
  11958.     else%@NL@%
  11959.         return(WinQueryWindow(hConvPrev, QW_NEXT, FALSE));%@NL@%
  11960. }%@NL@%
  11961. %@NL@%
  11962. %@NL@%
  11963. %@NL@%
  11964. %@NL@%
  11965. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  11966. %@AB@%* PUBDOC START%@NL@%
  11967. %@AB@%* BOOL EXPENTRY DdeEndEnumServers(hConvList)%@NL@%
  11968. %@AB@%* HCONVLIST hConvList;  // conversation list to destroy.%@NL@%
  11969. %@AB@%*%@NL@%
  11970. %@AB@%* hConvList - a conversation list handle returned by DdeBeginEnumServers().%@NL@%
  11971. %@AB@%*%@NL@%
  11972. %@AB@%* This API destroys hConvList and terminates all conversations associated%@NL@%
  11973. %@AB@%* with it.  If an application wishes to save selected conversations within%@NL@%
  11974. %@AB@%* hConvList, it should call DdeDisconnect() on all hConv's it does not%@NL@%
  11975. %@AB@%* want to use and not call this API.%@NL@%
  11976. %@AB@%*%@NL@%
  11977. %@AB@%* PUBDOC END%@NL@%
  11978. %@AB@%* History:%@NL@%
  11979. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  11980. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  11981. BOOL EXPENTRY DdeEndEnumServers(hConvList)%@NL@%
  11982. HCONVLIST hConvList;%@NL@%
  11983. {%@NL@%
  11984.     PAPPINFO pai;%@NL@%
  11985.     HCONV hConv, hConvNext;%@NL@%
  11986. %@NL@%
  11987.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  11988.         return(FALSE);%@NL@%
  11989.     if (WinIsWindow(DMGHAB, hConvList)) {%@NL@%
  11990.         hConv = WinQueryWindow(hConvList, QW_TOP, FALSE);%@NL@%
  11991.         while (hConv != NULL) {%@NL@%
  11992.             hConvNext = WinQueryWindow(hConv, QW_NEXT, FALSE);%@NL@%
  11993.             DestroyWindow(hConv);%@NL@%
  11994.             hConv = hConvNext;%@NL@%
  11995.         }%@NL@%
  11996.         DestroyWindow(hConvList);%@NL@%
  11997.     }%@NL@%
  11998.     return(TRUE);%@NL@%
  11999. }%@NL@%
  12000. %@NL@%
  12001. %@NL@%
  12002. %@NL@%
  12003. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12004. %@AB@%* PUBDOC START%@NL@%
  12005. %@AB@%* HCONV EXPENTRY DdeConnect(hszAppName, hszTopic, pCC, hApp)%@NL@%
  12006. %@AB@%* HSZ hszAppName;   // app name to connect to, NULL is wild.%@NL@%
  12007. %@AB@%* HSZ hszTopic;     // topic name to connect to, NULL is wild.%@NL@%
  12008. %@AB@%* PCONVCONTEXT pCC; // language information or NULL for sys default.%@NL@%
  12009. %@AB@%* HAPP hApp;        // target application or NULL for broadcast.%@NL@%
  12010. %@AB@%*%@NL@%
  12011. %@AB@%* hszAppName - DDE application name to connect to.%@NL@%
  12012. %@AB@%* hszTopic - DDE Topic name to connect to.%@NL@%
  12013. %@AB@%* pCC - CONVCONTEXT information pertinant to this conversation.%@NL@%
  12014. %@AB@%*       If NULL, the current system information is used.%@NL@%
  12015. %@AB@%* hApp - if not NULL, directs connection to a specific app.%@NL@%
  12016. %@AB@%*%@NL@%
  12017. %@AB@%* returns - the conversation handle of the connected conversation or 0 on error.%@NL@%
  12018. %@AB@%*%@NL@%
  12019. %@AB@%* This function allows the simpler aproach of allowing a client to%@NL@%
  12020. %@AB@%* talk to the first server it finds on a topic.  It is most efficient when%@NL@%
  12021. %@AB@%* an hApp is provided.%@NL@%
  12022. %@AB@%*%@NL@%
  12023. %@AB@%* PUBDOC END%@NL@%
  12024. %@AB@%*%@NL@%
  12025. %@AB@%* History:%@NL@%
  12026. %@AB@%*   Created     12/16/88    Sanfords%@NL@%
  12027. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12028. HCONV EXPENTRY DdeConnect(hszAppName, hszTopic, pCC, hApp)%@NL@%
  12029. HSZ hszAppName;%@NL@%
  12030. HSZ hszTopic;%@NL@%
  12031. PCONVCONTEXT pCC;%@NL@%
  12032. HAPP hApp;%@NL@%
  12033. {%@NL@%
  12034.     PAPPINFO pai;%@NL@%
  12035.     HCONV hConv;%@NL@%
  12036. %@NL@%
  12037.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  12038.         return(0);%@NL@%
  12039.         %@NL@%
  12040.     hConv = GetDDEClientWindow(pai->hwndDmg, NULL, (HWND)hApp, hszAppName,%@NL@%
  12041.             hszTopic, pCC);%@NL@%
  12042.             %@NL@%
  12043.     if (hConv == 0)%@NL@%
  12044.         pai->LastError = DMGERR_NO_CONV_ESTABLISHED;%@NL@%
  12045.         %@NL@%
  12046.     return(hConv);%@NL@%
  12047. }%@NL@%
  12048. %@NL@%
  12049. %@NL@%
  12050. %@NL@%
  12051. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12052. %@AB@%* PUBDOC START%@NL@%
  12053. %@AB@%* BOOL EXPENTRY DdeDisconnect(hConv)%@NL@%
  12054. %@AB@%* hConv; // conversation handle of conversation to terminate.%@NL@%
  12055. %@AB@%*%@NL@%
  12056. %@AB@%* This API terminates a conversation started by either DdeConnect() or%@NL@%
  12057. %@AB@%* DdeBeginEnumServers().  hConv becomes invalid after this call.%@NL@%
  12058. %@AB@%*%@NL@%
  12059. %@AB@%* If hConv is a server conversation, any transactions for that conversation%@NL@%
  12060. %@AB@%* found on the server callback queue will be deleted prior to terminating%@NL@%
  12061. %@AB@%* the conversation.%@NL@%
  12062. %@AB@%*%@NL@%
  12063. %@AB@%* If hConv is a client conversation, any transactions on the Client Queue%@NL@%
  12064. %@AB@%* are purged before termination.%@NL@%
  12065. %@AB@%*%@NL@%
  12066. %@AB@%* Note that client conversations that are terminated from the server end%@NL@%
  12067. %@AB@%* go into a dormant state but are still available so that DdeQueryConvInfo()%@NL@%
  12068. %@AB@%* can be used to determine why a conversation is not working.%@NL@%
  12069. %@AB@%* Server conversations will destroy themselves if terminated from a client.%@NL@%
  12070. %@AB@%*%@NL@%
  12071. %@AB@%* returns fSuccess%@NL@%
  12072. %@AB@%*%@NL@%
  12073. %@AB@%* PUBDOC END%@NL@%
  12074. %@AB@%* History:%@NL@%
  12075. %@AB@%*   Created     12/16/88    Sanfords%@NL@%
  12076. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12077. BOOL EXPENTRY DdeDisconnect(hConv)%@NL@%
  12078. HCONV hConv;%@NL@%
  12079. {%@NL@%
  12080.     PAPPINFO pai;%@NL@%
  12081. %@NL@%
  12082.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  12083.         return(FALSE);%@NL@%
  12084.         %@NL@%
  12085.     if (!WinIsWindow(DMGHAB, hConv)) {%@NL@%
  12086.         pai->LastError = DMGERR_NO_CONV_ESTABLISHED;%@NL@%
  12087.         return(FALSE);%@NL@%
  12088.     }%@NL@%
  12089.     SemCheckOut();%@NL@%
  12090.     return((BOOL)WinSendMsg(hConv, UMCL_TERMINATE, 0L, 0L));%@NL@%
  12091. }%@NL@%
  12092. %@NL@%
  12093. %@NL@%
  12094. %@NL@%
  12095. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12096. %@AB@%* PUBDOC START%@NL@%
  12097. %@AB@%* BOOL EXPENTRY DdeQueryConvInfo(hConv, pConvInfo, idXfer)%@NL@%
  12098. %@AB@%* HCONV hConv;          // conversation hand to get info on.%@NL@%
  12099. %@AB@%* PCONVINFO pConvInfo;  // structure to hold info.%@NL@%
  12100. %@AB@%* ULONG idXfer;         // transaction ID if async, QID_SYNC if not.%@NL@%
  12101. %@AB@%*%@NL@%
  12102. %@AB@%* hConv - conversation handle of a conversation to query.%@NL@%
  12103. %@AB@%* pConvInfo - pointer to CONVINFO structure.%@NL@%
  12104. %@AB@%* idXfer - Should be a QID_ constant or an ID returned from DdeCheckQueue().%@NL@%
  12105. %@AB@%*       if id is QID_SYNC, then the synchronous conversation state is returned.%@NL@%
  12106. %@AB@%*%@NL@%
  12107. %@AB@%* returns - fSuccess.  The CONVINFO structure is filled in with the%@NL@%
  12108. %@AB@%*     conversation's status on success.%@NL@%
  12109. %@AB@%*%@NL@%
  12110. %@AB@%* Note that a client conversation may have several transactions in progress%@NL@%
  12111. %@AB@%* at the same time.  idXfer is used to choose which transaction to refer to.%@NL@%
  12112. %@AB@%*%@NL@%
  12113. %@AB@%* hConv may be a client or server conversation handle.  Server conversation%@NL@%
  12114. %@AB@%* handles ignore idXfer.%@NL@%
  12115. %@AB@%*%@NL@%
  12116. %@AB@%* PUBDOC END%@NL@%
  12117. %@AB@%*%@NL@%
  12118. %@AB@%* History:%@NL@%
  12119. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  12120. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12121. BOOL EXPENTRY DdeQueryConvInfo(hConv, pConvInfo, idXfer)%@NL@%
  12122. HCONV hConv;%@NL@%
  12123. PCONVINFO pConvInfo;%@NL@%
  12124. ULONG idXfer;%@NL@%
  12125. {%@NL@%
  12126.     PCLIENTINFO pci;%@NL@%
  12127.     PAPPINFO pai;%@NL@%
  12128.     PXADATA pxad;%@NL@%
  12129.     PCQDATA pqd;%@NL@%
  12130.     BOOL fClient;%@NL@%
  12131. %@NL@%
  12132.     if ((pai = GetCurrentAppInfo(FALSE)) == 0)%@NL@%
  12133.         return(FALSE);%@NL@%
  12134. %@NL@%
  12135.     SemCheckOut();%@NL@%
  12136. %@NL@%
  12137.     %@AB@%/*%@NL@%
  12138. %@AB@%     * note that pci may actually be a psi if fClient is false.  Since%@NL@%
  12139. %@AB@%     * the common info portions are identical, we don't care except%@NL@%
  12140. %@AB@%     * where data is extracted from non-common portions.%@NL@%
  12141. %@AB@%     */%@AE@%%@NL@%
  12142.     if (!WinIsWindow(DMGHAB, hConv) ||%@NL@%
  12143.             !(pci = (PCLIENTINFO)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_ALL, 0L)) ||%@NL@%
  12144.             !WinIsWindow(DMGHAB, pci->ci.hwndPartner)) {%@NL@%
  12145.         pai->LastError = DMGERR_NO_CONV_ESTABLISHED;%@NL@%
  12146.         return(FALSE);%@NL@%
  12147.     }%@NL@%
  12148.     %@NL@%
  12149.     fClient = (BOOL)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_CLIENT, 0L);%@NL@%
  12150.     %@NL@%
  12151.     if (idXfer == QID_SYNC || !fClient) {%@NL@%
  12152.         pxad = &pci->ci.xad;%@NL@%
  12153.     } else {%@NL@%
  12154.         if (pci->pQ != NULL &&%@NL@%
  12155.                 (pqd = (PCQDATA)Findqi(pci->pQ, idXfer))) {%@NL@%
  12156.             pxad = &pqd->xad;%@NL@%
  12157.         } else {%@NL@%
  12158.             pai->LastError = DMGERR_UNFOUND_QUEUE_ID;%@NL@%
  12159.             return(FALSE);%@NL@%
  12160.         }%@NL@%
  12161.     }%@NL@%
  12162.     SemEnter();%@NL@%
  12163.     pConvInfo->cb = sizeof(CONVINFO);%@NL@%
  12164.     pConvInfo->hConvPartner = IsDdeWindow(pci->ci.hwndPartner);%@NL@%
  12165.     pConvInfo->hszAppName = pci->ci.hszServerApp;%@NL@%
  12166.     pConvInfo->hszAppPartner = fClient ? pci->ci.hszServerApp : 0;%@NL@%
  12167.     pConvInfo->hszTopic = pci->ci.hszTopic;%@NL@%
  12168.     pConvInfo->hAgent = pci->ci.hAgent;%@NL@%
  12169.     pConvInfo->hApp = pci->ci.hwndFrame;%@NL@%
  12170.     if (fClient) {%@NL@%
  12171.         pConvInfo->hszItem = pxad->pXferInfo->hszItem;%@NL@%
  12172.         pConvInfo->usFmt = pxad->pXferInfo->usFmt;%@NL@%
  12173.         pConvInfo->usType = pxad->pXferInfo->usType;%@NL@%
  12174.         pConvInfo->usConvst = pxad->state;%@NL@%
  12175.         pConvInfo->LastError = pxad->LastError;%@NL@%
  12176.     } else {%@NL@%
  12177.         pConvInfo->hszItem = NULL;%@NL@%
  12178.         pConvInfo->usFmt = 0;%@NL@%
  12179.         pConvInfo->usType = 0;%@NL@%
  12180.         pConvInfo->usConvst = pci->ci.xad.state;%@NL@%
  12181.         pConvInfo->LastError = pci->ci.pai->LastError;%@NL@%
  12182.     }%@NL@%
  12183.     pConvInfo->usStatus = pci->ci.fs;%@NL@%
  12184.     pConvInfo->fsContext = pci->ci.cc.fsContext;%@NL@%
  12185.     pConvInfo->idCountry = pci->ci.cc.idCountry;%@NL@%
  12186.     pConvInfo->usCodepage = pci->ci.cc.usCodepage;%@NL@%
  12187.     SemLeave();%@NL@%
  12188.     return(TRUE);%@NL@%
  12189. }%@NL@%
  12190. %@NL@%
  12191. %@NL@%
  12192. %@NL@%
  12193. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12194. %@AB@%* PUBDOC START%@NL@%
  12195. %@AB@%* BOOL EXPENTRY DdePostAdvise(hszTopic, hszItem)%@NL@%
  12196. %@AB@%* HSZ hszTopic;     // topic of changed data, NULL is all topics%@NL@%
  12197. %@AB@%* HSZ hszItem;      // item of changed data, NULL is all items%@NL@%
  12198. %@AB@%*%@NL@%
  12199. %@AB@%* Causes any clients who have advise loops running on the topic/item name%@NL@%
  12200. %@AB@%* specified to receive the apropriate data messages they require.%@NL@%
  12201. %@AB@%*%@NL@%
  12202. %@AB@%* This should be called by a server application anytime data associated with%@NL@%
  12203. %@AB@%* a particular topic/item changes.  This call results in XTYP_ADVREQ%@NL@%
  12204. %@AB@%* callbacks being generated.%@NL@%
  12205. %@AB@%*%@NL@%
  12206. %@AB@%* hszTopic and/or hszItem may be NULL if all topics or items are to be updated.%@NL@%
  12207. %@AB@%* This will result in callbacks for all active advise loops that fit the%@NL@%
  12208. %@AB@%* hszTopic/hszItem pair.%@NL@%
  12209. %@AB@%* %@NL@%
  12210. %@AB@%* The API is intended for SERVERS only!%@NL@%
  12211. %@AB@%*%@NL@%
  12212. %@AB@%* PUBDOC END%@NL@%
  12213. %@AB@%* History:%@NL@%
  12214. %@AB@%*   Created     12/16/88    Sanfords%@NL@%
  12215. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12216. BOOL EXPENTRY DdePostAdvise(hszTopic, hszItem)%@NL@%
  12217. HSZ hszTopic;%@NL@%
  12218. HSZ hszItem;%@NL@%
  12219. {%@NL@%
  12220.     PAPPINFO pai;%@NL@%
  12221.     HWND hwndTopic;%@NL@%
  12222.     HWND hwndSvr;%@NL@%
  12223. %@NL@%
  12224.     // LATER - add wild hsz support%@NL@%
  12225.     %@NL@%
  12226.     if (((pai = GetCurrentAppInfo(TRUE)) == 0))%@NL@%
  12227.         return(FALSE);%@NL@%
  12228.         %@NL@%
  12229.     if (pai->afCmd & DMGCMD_CLIENTONLY) {%@NL@%
  12230.         pai->LastError = DMGERR_DLL_USAGE;%@NL@%
  12231.         return(FALSE);%@NL@%
  12232.     }%@NL@%
  12233.         %@NL@%
  12234.     if ((hwndTopic = HwndFromHsz((HSZ)hszTopic, pai->pSvrTopicList)) == 0)%@NL@%
  12235.         return(TRUE);%@NL@%
  12236. %@NL@%
  12237.     hwndSvr = WinQueryWindow(hwndTopic, QW_TOP, FALSE);%@NL@%
  12238.     while (hwndSvr) {%@NL@%
  12239.         WinPostMsg(hwndSvr, UMSR_POSTADVISE, MPFROMSHORT(hszItem), 0L);%@NL@%
  12240.         hwndSvr = WinQueryWindow(hwndSvr, QW_NEXT, FALSE);%@NL@%
  12241.     }%@NL@%
  12242. %@NL@%
  12243.     return(TRUE);%@NL@%
  12244. }%@NL@%
  12245. %@NL@%
  12246. %@NL@%
  12247. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12248. %@AB@%* PUBDOC START%@NL@%
  12249. %@AB@%* HDMGDATA EXPENTRY DdeClientXfer(pSrc, cb, hConv, hszItem, usFmt,%@NL@%
  12250. %@AB@%*         usType, ulTimeout, pidXfer)%@NL@%
  12251. %@AB@%* PBYTE pSrc;       // data source, or NULL for non-data cases.%@NL@%
  12252. %@AB@%* ULONG cb;         // data size or 0 for non-data cases.%@NL@%
  12253. %@AB@%* HCONV hConv;      // associated conversation handle%@NL@%
  12254. %@AB@%* HSZ hszItem;      // item of transaction%@NL@%
  12255. %@AB@%* USHORT usFmt;     // format for transaction%@NL@%
  12256. %@AB@%* USHORT usType;    // transaction type code%@NL@%
  12257. %@AB@%* ULONG ulTimeout;  // timeout for synchronous, TIMEOUT_ASSYNC otherwise.%@NL@%
  12258. %@AB@%* PULONG pidXfer;   // OUTPUT: assync transfer id, NULL for no output.%@NL@%
  12259. %@AB@%*%@NL@%
  12260. %@AB@%* This API initiates a transaction from a client to the server connected%@NL@%
  12261. %@AB@%* via the conversation specified by hConv.%@NL@%
  12262. %@AB@%* %@NL@%
  12263. %@AB@%* Currently usType may be:%@NL@%
  12264. %@AB@%*     XTYP_REQUEST%@NL@%
  12265. %@AB@%*     XTYP_POKE%@NL@%
  12266. %@AB@%*     XTYP_EXEC%@NL@%
  12267. %@AB@%*     XTYP_ADVSTART%@NL@%
  12268. %@AB@%*     XTYP_ADVSTART | XTYPF_NODATA%@NL@%
  12269. %@AB@%*     XTYP_ADVSTART | XTYPF_ACKREQ%@NL@%
  12270. %@AB@%*     XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ%@NL@%
  12271. %@AB@%*     XTYP_ADVSTOP%@NL@%
  12272. %@AB@%*%@NL@%
  12273. %@AB@%* ulTimeout specifies the maximum time to wait for a response in miliseconds%@NL@%
  12274. %@AB@%* and applies to synchronous transactions only.%@NL@%
  12275. %@AB@%* if ulTimeout is TIMEOUT_ASSYNC, then the transfer is asynchronous and%@NL@%
  12276. %@AB@%* pidXfer may point to where to place the client transaction queue item%@NL@%
  12277. %@AB@%* ID created by this request.%@NL@%
  12278. %@AB@%* pidXfer may be NULL if no ID is desired.%@NL@%
  12279. %@AB@%* %@NL@%
  12280. %@AB@%* If usType is XTYP_REQUEST, synchronous transfers return a valid hDmgData%@NL@%
  12281. %@AB@%* on success which holds the data received from the request.%@NL@%
  12282. %@AB@%*%@NL@%
  12283. %@AB@%* if usType is XTYP_EXEC and hszItem==NULL (wild) and usFmt==DDEFMT_TEXT,%@NL@%
  12284. %@AB@%* the item name will be changed to the same as the text data.%@NL@%
  12285. %@AB@%* This allows for EXCEL and porthole WINDOWS compatability%@NL@%
  12286. %@AB@%* for XTYP_EXEC transactions.  It is suggested that applications always set%@NL@%
  12287. %@AB@%* hszItem to NULL for XTYP_EXEC transactions and that servers ignore the%@NL@%
  12288. %@AB@%* hszItem perameter in their callback for execute transactions.%@NL@%
  12289. %@AB@%*%@NL@%
  12290. %@AB@%* returns hDmgData or ACK DDE flags on Success, 0 on failure.%@NL@%
  12291. %@AB@%*%@NL@%
  12292. %@AB@%* Note: the hDmgData passed in by this call is only valid for the duration%@NL@%
  12293. %@AB@%* of the callback.%@NL@%
  12294. %@AB@%* %@NL@%
  12295. %@AB@%* PUBDOC END%@NL@%
  12296. %@AB@%*%@NL@%
  12297. %@AB@%* History:%@NL@%
  12298. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  12299. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12300. HDMGDATA EXPENTRY DdeClientXfer(pSrc, cb, hConv, hszItem, usFmt,%@NL@%
  12301.         usType, ulTimeout, pidXfer)%@NL@%
  12302. PBYTE pSrc;%@NL@%
  12303. ULONG cb;%@NL@%
  12304. HCONV hConv;%@NL@%
  12305. HSZ hszItem;%@NL@%
  12306. USHORT usFmt;%@NL@%
  12307. USHORT usType;%@NL@%
  12308. ULONG ulTimeout;%@NL@%
  12309. PULONG pidXfer;%@NL@%
  12310. {%@NL@%
  12311.     PAPPINFO pai;%@NL@%
  12312.     XFERINFO xi;%@NL@%
  12313.     HDMGDATA hDmgData;%@NL@%
  12314. %@NL@%
  12315.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  12316.         return(0);%@NL@%
  12317. %@NL@%
  12318.     if (!WinIsWindow(DMGHAB, hConv)) {%@NL@%
  12319.         pai->LastError = DMGERR_NO_CONV_ESTABLISHED;%@NL@%
  12320.         return(0);%@NL@%
  12321.     }%@NL@%
  12322.     %@NL@%
  12323.     SemCheckOut();%@NL@%
  12324.     %@NL@%
  12325.     switch (usType) {%@NL@%
  12326.     case XTYP_REQUEST:%@NL@%
  12327.     case XTYP_POKE:%@NL@%
  12328.     case XTYP_EXEC:%@NL@%
  12329.     case XTYP_ADVSTART:%@NL@%
  12330.     case XTYP_ADVSTART | XTYPF_NODATA:%@NL@%
  12331.     case XTYP_ADVSTART | XTYPF_ACKREQ:%@NL@%
  12332.     case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:%@NL@%
  12333.     case XTYP_ADVSTOP:%@NL@%
  12334.         xi.pidXfer = pidXfer;%@NL@%
  12335.         xi.ulTimeout = ulTimeout;%@NL@%
  12336.         xi.usType = usType;%@NL@%
  12337.         xi.usFmt = usFmt;%@NL@%
  12338.         xi.hszItem = hszItem;%@NL@%
  12339.         xi.hConv = hConv;%@NL@%
  12340.         xi.cb = cb;%@NL@%
  12341.         xi.pData = pSrc;        %@NL@%
  12342.         hDmgData = (HDMGDATA)WinSendMsg(hConv, UMCL_XFER, (MPARAM)&xi, 0L);%@NL@%
  12343.         if (ulTimeout == TIMEOUT_ASYNC) {%@NL@%
  12344.             %@AB@%/*%@NL@%
  12345. %@AB@%             * Increment the count of hszItem incase the app frees it on%@NL@%
  12346. %@AB@%             * return.  This will be decremented when the client Queue%@NL@%
  12347. %@AB@%             * entry is removed.%@NL@%
  12348. %@AB@%             */%@AE@%%@NL@%
  12349.             IncHszCount(hszItem);%@NL@%
  12350.         }%@NL@%
  12351.         %@NL@%
  12352.         %@AB@%/*%@NL@%
  12353. %@AB@%         * add the hDmgData to the client's list of handles he needs%@NL@%
  12354. %@AB@%         * to eventually free.%@NL@%
  12355. %@AB@%         */%@AE@%%@NL@%
  12356.         if ((usType & XCLASS_DATA) && (CheckSel(SELECTOROF(hDmgData)))) {%@NL@%
  12357.             AddPileItem(pai->pHDataPile, (PBYTE)&hDmgData, CmpULONG);%@NL@%
  12358.             if (((PMYDDES)hDmgData)->magic == MYDDESMAGIC) {%@NL@%
  12359.                 ((PMYDDES)hDmgData)->fs |= HDATA_READONLY;%@NL@%
  12360.             }%@NL@%
  12361.         }%@NL@%
  12362.         %@NL@%
  12363.         return(hDmgData);%@NL@%
  12364.     }%@NL@%
  12365.     pai->LastError = DMGERR_INVALIDPARAMETER;%@NL@%
  12366.     return(0);%@NL@%
  12367. }%@NL@%
  12368. %@NL@%
  12369. %@NL@%
  12370. %@NL@%
  12371. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12372. %@AB@%* PUBDOC START%@NL@%
  12373. %@AB@%* USHORT EXPENTRY DdeGetLastError(void)%@NL@%
  12374. %@AB@%*%@NL@%
  12375. %@AB@%* This API returns the most recent error registered by the DDE manager for%@NL@%
  12376. %@AB@%* the current thread.  This should be called anytime a DDE manager API%@NL@%
  12377. %@AB@%* returns in a failed state.%@NL@%
  12378. %@AB@%*%@NL@%
  12379. %@AB@%* returns an error code which corresponds to a DMGERR_ constant found in%@NL@%
  12380. %@AB@%* ddeml.h.  This error code may be passed on to DdePostError() to%@NL@%
  12381. %@AB@%* show the user the reason for the error or to DdeGetErrorString() to convert%@NL@%
  12382. %@AB@%* the error code into an apropriate string.%@NL@%
  12383. %@AB@%*%@NL@%
  12384. %@AB@%* PUBDOC END%@NL@%
  12385. %@AB@%*%@NL@%
  12386. %@AB@%* History:%@NL@%
  12387. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  12388. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12389. USHORT EXPENTRY DdeGetLastError(void)%@NL@%
  12390. {%@NL@%
  12391.     PAPPINFO pai;%@NL@%
  12392.     SHORT err = DMGERR_DLL_NOT_INITIALIZED;%@NL@%
  12393. %@NL@%
  12394.     pai = GetCurrentAppInfo(FALSE);%@NL@%
  12395. %@NL@%
  12396.     if (pai) {%@NL@%
  12397.         err = pai->LastError;%@NL@%
  12398.         pai->LastError = DMGERR_NO_ERROR;%@NL@%
  12399.     }%@NL@%
  12400.     return(err);%@NL@%
  12401. }%@NL@%
  12402. %@NL@%
  12403. %@NL@%
  12404. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12405. %@AB@%* PUBDOC START%@NL@%
  12406. %@AB@%* void EXPENTRY DdePostError(err)%@NL@%
  12407. %@AB@%* ULONG err;    // error code to post.%@NL@%
  12408. %@AB@%*%@NL@%
  12409. %@AB@%* This API puts up a message box describing the error who's code was%@NL@%
  12410. %@AB@%* passed in.%@NL@%
  12411. %@AB@%*%@NL@%
  12412. %@AB@%* PUBDOC END%@NL@%
  12413. %@AB@%*%@NL@%
  12414. %@AB@%* History:%@NL@%
  12415. %@AB@%*   Created     12/20/88    sanfords%@NL@%
  12416. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12417. void EXPENTRY DdePostError(err)%@NL@%
  12418. USHORT err;%@NL@%
  12419. {%@NL@%
  12420.     char szError[MAX_ERRSTR + 1];%@NL@%
  12421. %@NL@%
  12422.     if (err < DMGERR_FIRST || err > DMGERR_LAST)%@NL@%
  12423.         return;%@NL@%
  12424.     WinLoadString(DMGHAB, hmodDmg, err, MAX_ERRSTR + 1, szError);%@NL@%
  12425.     WinMessageBox(HWND_DESKTOP, NULL, szError, SZERRCAPTION, 0,%@NL@%
  12426.             MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);%@NL@%
  12427. }%@NL@%
  12428. %@NL@%
  12429. %@NL@%
  12430. %@NL@%
  12431. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12432. %@AB@%* PUBDOC START%@NL@%
  12433. %@AB@%* USHORT EXPENTRY DdeGetErrorString(err, cbMax, psz)%@NL@%
  12434. %@AB@%* USHORT err;       // error code to convert%@NL@%
  12435. %@AB@%* USHORT cbMax;     // size of string buffer provided by caller%@NL@%
  12436. %@AB@%* PSZ psz;          // string buffer address.%@NL@%
  12437. %@AB@%*%@NL@%
  12438. %@AB@%* This function fills psz with the error string referenced by err of up%@NL@%
  12439. %@AB@%* to cbMax characters.  All error strings are <= MAX_ERRSTR in length.%@NL@%
  12440. %@AB@%* (not counting the NULL terminator.)%@NL@%
  12441. %@AB@%*%@NL@%
  12442. %@AB@%* returns length of copied string without NULL terminator or 0 on failure.%@NL@%
  12443. %@AB@%*%@NL@%
  12444. %@AB@%* PUBDOC END%@NL@%
  12445. %@AB@%*%@NL@%
  12446. %@AB@%* History:%@NL@%
  12447. %@AB@%*   Created     12/20/88    sanfords%@NL@%
  12448. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12449. USHORT EXPENTRY DdeGetErrorString(err, cbMax, psz)%@NL@%
  12450. USHORT err;%@NL@%
  12451. USHORT cbMax;%@NL@%
  12452. PSZ psz;%@NL@%
  12453. {%@NL@%
  12454.     if (err < DMGERR_FIRST || err > DMGERR_LAST)%@NL@%
  12455.         return(0);%@NL@%
  12456.     return(WinLoadString(DMGHAB, hmodDmg, err, cbMax, psz));%@NL@%
  12457. }%@NL@%
  12458. %@NL@%
  12459. %@NL@%
  12460. %@NL@%
  12461. %@AB@%/*\%@NL@%
  12462. %@AB@%* HDATA stuff:%@NL@%
  12463. %@AB@%* %@NL@%
  12464. %@AB@%* Each thread has an hData list that contains all the hData's it has%@NL@%
  12465. %@AB@%* been given by the DLL.   This list indicates what hData's an app can%@NL@%
  12466. %@AB@%* and must eventually free.%@NL@%
  12467. %@AB@%* %@NL@%
  12468. %@AB@%* If an app has multiple threads registered, each threads pai's are linked%@NL@%
  12469. %@AB@%* via the nextThread pointer.  The links are circular so the TID%@NL@%
  12470. %@AB@%* should be used to know when all the lists are traversed.%@NL@%
  12471. %@AB@%* %@NL@%
  12472. %@AB@%* Each hData contains the following flags:%@NL@%
  12473. %@AB@%* %@NL@%
  12474. %@AB@%* HDATA_READONLY - set on any hData given to the DLL or created by the DLL.%@NL@%
  12475. %@AB@%*         This prevents AddData from working.%@NL@%
  12476. %@AB@%*         %@NL@%
  12477. %@AB@%* HDATA_APPOWNED - set at creation time by app so app will keep access%@NL@%
  12478. %@AB@%*         until it frees it or unregistration happens.%@NL@%
  12479. %@AB@%*         This prevents the DLL from freeing the hData before an app is%@NL@%
  12480. %@AB@%*         through with it.%@NL@%
  12481. %@AB@%* %@NL@%
  12482. %@AB@%* HDATA_APPFREEABLE - set at creation time if logged into thread list.%@NL@%
  12483. %@AB@%* %@NL@%
  12484. %@AB@%* Each hData also contains the pai of the thread that created the hData.%@NL@%
  12485. %@AB@%*         (set by PutData)  If APPOWNED is set, this identifies the%@NL@%
  12486. %@AB@%*         owner thread as well.%@NL@%
  12487. %@AB@%* %@NL@%
  12488. %@AB@%* %@NL@%
  12489. %@AB@%* General rules for apps:%@NL@%
  12490. %@AB@%* %@NL@%
  12491. %@AB@%*         hDatas from DLL calls are the apps responsibility to free and are%@NL@%
  12492. %@AB@%*                 only valid till passed back into the DLL or freed.%@NL@%
  12493. %@AB@%*         hDatas from callback calls are only valid during the callback.%@NL@%
  12494. %@AB@%*         hDatas created by an app but not APPOWNED are only valid till%@NL@%
  12495. %@AB@%*                 passed into the DLL.%@NL@%
  12496. %@AB@%*         hDatas created by an app that are APPOWNED are valid until%@NL@%
  12497. %@AB@%*                 the creating thread frees it or till that thread unregisters%@NL@%
  12498. %@AB@%*                 itself.%@NL@%
  12499. %@AB@%*         A process will not loose access to an hData untill all threads that%@NL@%
  12500. %@AB@%*                 have received the hData have freed it or passed it back to%@NL@%
  12501. %@AB@%*                 the DLL (via callback)%@NL@%
  12502. %@AB@%* %@NL@%
  12503. %@AB@%*         %@NL@%
  12504. %@AB@%* Register:                                                       DONE%@NL@%
  12505. %@AB@%*         creates hDataList for app/thread.%@NL@%
  12506. %@AB@%*         creates nextThread links if applicable.%@NL@%
  12507. %@AB@%* %@NL@%
  12508. %@AB@%* DdePutData:                                                  DONE%@NL@%
  12509. %@AB@%*         Only allows HDATA_APPOWNED flag%@NL@%
  12510. %@AB@%*         sets HDATA_APPFREEABLE flag%@NL@%
  12511. %@AB@%*         ...Falls into....%@NL@%
  12512. %@AB@%* PutData:                                                        DONE%@NL@%
  12513. %@AB@%*         Allocates selector%@NL@%
  12514. %@AB@%*         sets creator pai%@NL@%
  12515. %@AB@%*         sets HDATA_ flags specified%@NL@%
  12516. %@AB@%*         if (HDATA_APPFREEABLE)%@NL@%
  12517. %@AB@%*             adds to hDataList. %@NL@%
  12518. %@AB@%* %@NL@%
  12519. %@AB@%* DdeAddData:                                                  DONE%@NL@%
  12520. %@AB@%*         fails if HDATA_READONLY or a non-dll type selector%@NL@%
  12521. %@AB@%* %@NL@%
  12522. %@AB@%* Callback:                                                       DONE%@NL@%
  12523. %@AB@%*         Entry:%@NL@%
  12524. %@AB@%*             for hData to callback:%@NL@%
  12525. %@AB@%*                 Sets HDATA_READONLY if hData valid DLL type selector.%@NL@%
  12526. %@AB@%*                 (does NOT add hData to thread list so he can't free it during%@NL@%
  12527. %@AB@%*                  the callback)%@NL@%
  12528. %@AB@%*                  %@NL@%
  12529. %@AB@%*         Exit:%@NL@%
  12530. %@AB@%*             for hData to callback:%@NL@%
  12531. %@AB@%*                 nothing.%@NL@%
  12532. %@AB@%*             for hData from callback:%@NL@%
  12533. %@AB@%*                 verifies creator == current%@NL@%
  12534. %@AB@%* %@NL@%
  12535. %@AB@%* DdeCreateInitPkt:                                            DONE%@NL@%
  12536. %@AB@%* DdeAppNameServer:                                            NOT COMPLETE%@NL@%
  12537. %@AB@%* DdeClientXfer:                                               DONE%@NL@%
  12538. %@AB@%* DdeCheckQ:                                                   DONE%@NL@%
  12539. %@AB@%*         if (valid selector)%@NL@%
  12540. %@AB@%*             add to thread list%@NL@%
  12541. %@AB@%*             if (valid DLL type selector)%@NL@%
  12542. %@AB@%*                 Set READONLY flag.%@NL@%
  12543. %@AB@%* %@NL@%
  12544. %@AB@%* ProcessPkt:                                                     NOT IMP.%@NL@%
  12545. %@AB@%*         for hData in:%@NL@%
  12546. %@AB@%*              After used, calls FreeData()%@NL@%
  12547. %@AB@%*         for hData out:%@NL@%
  12548. %@AB@%*              before return, adds hData to thread list%@NL@%
  12549. %@AB@%*         %@NL@%
  12550. %@AB@%* MyPostMsg:                                                      DONE%@NL@%
  12551. %@AB@%*         gives if target process != current%@NL@%
  12552. %@AB@%*         if target process is not a DLL process/thread, expand hszItem.%@NL@%
  12553. %@AB@%*         calls FreeData() on current process if MDPM_FREEHDATA is set.%@NL@%
  12554. %@AB@%*         %@NL@%
  12555. %@AB@%* %@NL@%
  12556. %@AB@%* DdeFreeData:                                                 DONE%@NL@%
  12557. %@AB@%*         if in thread list.%@NL@%
  12558. %@AB@%*             remove hData from list%@NL@%
  12559. %@AB@%*             if not in any thread lists for this process%@NL@%
  12560. %@AB@%*                 free data%@NL@%
  12561. %@AB@%*             return pass%@NL@%
  12562. %@AB@%*         else %@NL@%
  12563. %@AB@%*             return fail%@NL@%
  12564. %@AB@%* %@NL@%
  12565. %@AB@%* FreeData:                                                       DONE%@NL@%
  12566. %@AB@%*         if (DLL type selector && HDATA_APPOWNED && creator == current)%@NL@%
  12567. %@AB@%*             exit%@NL@%
  12568. %@AB@%*         remove hData from thread list if found%@NL@%
  12569. %@AB@%*         if not in any thread lists for this process%@NL@%
  12570. %@AB@%*             free data%@NL@%
  12571. %@AB@%*         %@NL@%
  12572. %@AB@%* UnRegister:                                                     DONE%@NL@%
  12573. %@AB@%*         for each item in the hDataList:%@NL@%
  12574. %@AB@%*             clear HDATA_APPOWNED flag if dll type selector and owned by this%@NL@%
  12575. %@AB@%*                 thread.%@NL@%
  12576. %@AB@%*             FreeData()%@NL@%
  12577. %@AB@%*         destroy list%@NL@%
  12578. %@AB@%*         unlink from other thread lists%@NL@%
  12579. %@AB@%*         %@NL@%
  12580. %@AB@%\*/%@AE@%%@NL@%
  12581. %@NL@%
  12582. %@NL@%
  12583. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12584. %@AB@%* PUBDOC START%@NL@%
  12585. %@AB@%* HDMGDATA EXPENTRY DdePutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd)%@NL@%
  12586. %@AB@%* PBYTE pSrc;   // address of data to place into data handle or NULL%@NL@%
  12587. %@AB@%* ULONG cb;     // amount of data to copy if pSrc is not NULL.%@NL@%
  12588. %@AB@%* ULONG cbOff;  // offset into data handle region to place pSrc data%@NL@%
  12589. %@AB@%* HSZ hszItem;  // item associated with this data%@NL@%
  12590. %@AB@%* USHORT usFmt; // format associated with this data%@NL@%
  12591. %@AB@%* USHORT afCmd; // HDATA_ flags.%@NL@%
  12592. %@AB@%* %@NL@%
  12593. %@AB@%* This api allows an application to create a hDmgData apropriate%@NL@%
  12594. %@AB@%* for return from its call-back function.%@NL@%
  12595. %@AB@%* The passed in data is stored into the hDmgData which is%@NL@%
  12596. %@AB@%* returned on success.  Any portions of the data handle not filled are%@NL@%
  12597. %@AB@%* undefined.  afCmd contains any of the HDATA_ constants described below:%@NL@%
  12598. %@AB@%*%@NL@%
  12599. %@AB@%* HDATA_APPOWNED%@NL@%
  12600. %@AB@%*   This declares the created data handle to be the responsability of%@NL@%
  12601. %@AB@%*   the application to free it.  Application owned data handles may%@NL@%
  12602. %@AB@%*   be given to the DLL multiple times.  This allows a server app to be%@NL@%
  12603. %@AB@%*   able to support many clients without having to recopy the data for%@NL@%
  12604. %@AB@%*   each request.  If this flag is not specified, the data handle becomes%@NL@%
  12605. %@AB@%*   invalid once passed to the DLL via any API or the callback function.%@NL@%
  12606. %@AB@%*%@NL@%
  12607. %@AB@%* NOTES:%@NL@%
  12608. %@AB@%*   If an application expects this data handle to hold >64K of data via%@NL@%
  12609. %@AB@%*   DdeAddData(), it should specify a cb + cbOff to be as large as%@NL@%
  12610. %@AB@%*   the object is expected to get via DdeAddData() calls to avoid%@NL@%
  12611. %@AB@%*   unnecessary data copying or reallocation by the DLL.%@NL@%
  12612. %@AB@%*%@NL@%
  12613. %@AB@%*   if psrc==NULL or cb == 0, no actual data copying takes place.%@NL@%
  12614. %@AB@%* %@NL@%
  12615. %@AB@%*   Data handles given to an application via the DdeClientXfer() or%@NL@%
  12616. %@AB@%*   DdeCheckQueue() functions are the responsability of the client%@NL@%
  12617. %@AB@%*   application to free and MUST NOT be returned from the callback%@NL@%
  12618. %@AB@%*   function as server data!  The DLL will only accept data handles%@NL@%
  12619. %@AB@%*   returned from the callback function that were created by the%@NL@%
  12620. %@AB@%*   called application.%@NL@%
  12621. %@AB@%*%@NL@%
  12622. %@AB@%* PUBDOC END%@NL@%
  12623. %@AB@%*%@NL@%
  12624. %@AB@%* History:%@NL@%
  12625. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  12626. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12627. HDMGDATA EXPENTRY DdePutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd)%@NL@%
  12628. PBYTE pSrc;%@NL@%
  12629. ULONG cb;%@NL@%
  12630. ULONG cbOff;%@NL@%
  12631. HSZ hszItem;%@NL@%
  12632. USHORT usFmt;%@NL@%
  12633. USHORT afCmd;%@NL@%
  12634. {%@NL@%
  12635.     PAPPINFO pai;%@NL@%
  12636. %@NL@%
  12637.     if (!(pai = GetCurrentAppInfo(FALSE)))%@NL@%
  12638.         return(0L);;%@NL@%
  12639. %@NL@%
  12640.     if (afCmd & ~(HDATA_APPOWNED)) {%@NL@%
  12641.         pai->LastError = DMGERR_INVALIDPARAMETER;%@NL@%
  12642.         return(0L);%@NL@%
  12643.     }%@NL@%
  12644. %@NL@%
  12645.     return(PutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd | HDATA_APPFREEABLE, pai));%@NL@%
  12646. }%@NL@%
  12647. %@NL@%
  12648. %@NL@%
  12649. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12650. %@AB@%* PUBDOC START%@NL@%
  12651. %@AB@%* HDMGDATA EXPENTRY DdeAddData(hDmgData, pSrc, cb, cbOff)%@NL@%
  12652. %@AB@%* HDMGDATA hDmgData;    // data handle to add data to%@NL@%
  12653. %@AB@%* PBYTE pSrc;           // pointer to data to add (if NULL, no data copying)%@NL@%
  12654. %@AB@%* ULONG cb;             // size of data to add%@NL@%
  12655. %@AB@%* ULONG cbOff;          // offset within hData to place data%@NL@%
  12656. %@AB@%*%@NL@%
  12657. %@AB@%* This routine allows an application to add data to a hDmgData it had%@NL@%
  12658. %@AB@%* previously created using DdePutData().  The handle will be%@NL@%
  12659. %@AB@%* grown as necessary to support the data addition.  Data may be added%@NL@%
  12660. %@AB@%* to a data handle multiple times and in any order of data locations.%@NL@%
  12661. %@AB@%*%@NL@%
  12662. %@AB@%* Once a data handle is given to the DLL via return from the callback%@NL@%
  12663. %@AB@%* function or via a DLL API, it becomes readonly.  Further attempts to%@NL@%
  12664. %@AB@%* add data to the hData by any process will fail.%@NL@%
  12665. %@AB@%*%@NL@%
  12666. %@AB@%* This call will return 0 if it failed to allocate enough memory or if%@NL@%
  12667. %@AB@%* the data handle is readonly.  On success, the returned hDmgData should %@NL@%
  12668. %@AB@%* replace the given hDmgData.  On failure, the hDmgData given is left%@NL@%
  12669. %@AB@%* in the state it was initially.%@NL@%
  12670. %@AB@%*%@NL@%
  12671. %@AB@%* NOTE: For huge segments, or segments expected to grow to greater than %@NL@%
  12672. %@AB@%*    64K, it is best if DdePutData() be called with a cbOff + cb as %@NL@%
  12673. %@AB@%*    large as maximally expected so as not to force reallocation from a %@NL@%
  12674. %@AB@%*    normal to a huge segment in 16bit applications.  This also avoids %@NL@%
  12675. %@AB@%*    the need of replaceing the hDmgData with the output each time%@NL@%
  12676. %@AB@%*    incase a new selector was needed to be allocated and copied to.  %@NL@%
  12677. %@AB@%* %@NL@%
  12678. %@AB@%* PUBDOC END%@NL@%
  12679. %@AB@%*%@NL@%
  12680. %@AB@%* History:%@NL@%
  12681. %@AB@%*   Created     9/17/89    Sanfords%@NL@%
  12682. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12683. HDMGDATA EXPENTRY DdeAddData(hDmgData, pSrc, cb, cbOff)%@NL@%
  12684. HDMGDATA hDmgData;%@NL@%
  12685. PBYTE pSrc;%@NL@%
  12686. ULONG cb;%@NL@%
  12687. ULONG cbOff;%@NL@%
  12688. {%@NL@%
  12689. %@AI@%#define %@AE@%pmyddes ((PMYDDES)hDmgData) %@NL@%
  12690. %@AI@%#define %@AE@%selIn (SELECTOROF(hDmgData)) %@NL@%
  12691.     %@NL@%
  12692.     PAPPINFO pai;%@NL@%
  12693.     SEL sel;%@NL@%
  12694.     ULONG cbOffAbs;%@NL@%
  12695. %@NL@%
  12696.     if (!(pai = GetCurrentAppInfo(FALSE)))%@NL@%
  12697.         return(0L);;%@NL@%
  12698. %@NL@%
  12699.     if (!CheckSel(selIn) ||%@NL@%
  12700.             pmyddes->offszItemName != sizeof(MYDDES) ||%@NL@%
  12701.             pmyddes->magic != MYDDESMAGIC ||%@NL@%
  12702.             pmyddes->fs & HDATA_READONLY) {%@NL@%
  12703.         pai->LastError = DMGERR_INVALID_HDMGDATA;%@NL@%
  12704.         return(0L);%@NL@%
  12705.     }%@NL@%
  12706.     %@NL@%
  12707.     cbOffAbs = pmyddes->offabData + cbOff;%@NL@%
  12708.     if (pmyddes->cbData + pmyddes->offabData < cb + cbOffAbs) {%@NL@%
  12709.         %@AB@%/*%@NL@%
  12710. %@AB@%         * need to grow...%@NL@%
  12711. %@AB@%         */%@AE@%%@NL@%
  12712.         if (cbOffAbs + cb > 0xFFFFL) {%@NL@%
  12713.             %@AB@%/*%@NL@%
  12714. %@AB@%             * going to be huge...%@NL@%
  12715. %@AB@%             */%@AE@%%@NL@%
  12716.             if ((pmyddes->offabData + pmyddes->cbData < 0xFFFFL) ||%@NL@%
  12717.                     DosReallocHuge(HIUSHORT(cb + cbOffAbs),%@NL@%
  12718.                     LOUSHORT(cb + cbOffAbs), selIn)) {%@NL@%
  12719.                 %@AB@%/*%@NL@%
  12720. %@AB@%                 * Either we can't grow a huge seg or we need to make one.%@NL@%
  12721. %@AB@%                 */%@AE@%%@NL@%
  12722.                 if (DosAllocHuge(HIUSHORT(cb + cbOffAbs),%@NL@%
  12723.                         LOUSHORT(cb + cbOffAbs), &sel, 0, SEG_GIVEABLE)) {%@NL@%
  12724.                     pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  12725.                     return(0);%@NL@%
  12726.                 }%@NL@%
  12727.                 CopyHugeBlock(hDmgData, MAKEP(sel, 0), pmyddes->cbData +%@NL@%
  12728.                         sizeof(MYDDES) + 1);%@NL@%
  12729.                 FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDmgData,%@NL@%
  12730.                         FPI_DELETE);%@NL@%
  12731.                 DosFreeSeg(selIn);%@NL@%
  12732.                 hDmgData = MAKEP(sel, 0);%@NL@%
  12733.                 AddPileItem(pai->pHDataPile, (PBYTE)&hDmgData, NULL);%@NL@%
  12734.             }%@NL@%
  12735.         } else {%@NL@%
  12736.             %@AB@%/*%@NL@%
  12737. %@AB@%             * not going to be huge%@NL@%
  12738. %@AB@%             */%@AE@%%@NL@%
  12739.             if (DosReallocSeg((USHORT)(cb + cbOffAbs), selIn)) { %@NL@%
  12740.                 pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  12741.                 return(0L);%@NL@%
  12742.             }%@NL@%
  12743.         }%@NL@%
  12744.         pmyddes->cbData = cbOff + cb;%@NL@%
  12745.     }%@NL@%
  12746.     if (pSrc)%@NL@%
  12747.         CopyHugeBlock(pSrc, HugeOffset((PBYTE)hDmgData, cbOffAbs), cb);%@NL@%
  12748.     return(hDmgData);%@NL@%
  12749. %@AI@%#undef %@AE@%selIn     %@NL@%
  12750. %@AI@%#undef %@AE@%pmyddes     %@NL@%
  12751. }%@NL@%
  12752. %@NL@%
  12753. %@NL@%
  12754. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12755. %@AB@%* PUBDOC START%@NL@%
  12756. %@AB@%* ULONG EXPENTRY DdeGetData(hDmgData, pDst, cbMax, cbOff)%@NL@%
  12757. %@AB@%* HDMGDATA hDmgData;    // data handle to extract data from%@NL@%
  12758. %@AB@%* PBYTE pDst;           // destination for extracted data%@NL@%
  12759. %@AB@%* ULONG cbMax;          // destination buffer size%@NL@%
  12760. %@AB@%* ULONG cbOff;          // offset into data to start extraction%@NL@%
  12761. %@AB@%*%@NL@%
  12762. %@AB@%* This copies up to cbMax bytes of data contained in the hDmgData data handle%@NL@%
  12763. %@AB@%* at offset cbOff into application memory pointed to by pDst.%@NL@%
  12764. %@AB@%* If pDst == NULL, no copying is performed.%@NL@%
  12765. %@AB@%*%@NL@%
  12766. %@AB@%* returns the size of the data contained in the data handle remaining after%@NL@%
  12767. %@AB@%* cbOff or 0 if hDmgData is invalid or cbOff is too large.%@NL@%
  12768. %@AB@%*%@NL@%
  12769. %@AB@%* This API supports HUGE segments in 16 bit applications.%@NL@%
  12770. %@AB@%*%@NL@%
  12771. %@AB@%* PUBDOC END%@NL@%
  12772. %@AB@%*%@NL@%
  12773. %@AB@%* History:%@NL@%
  12774. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  12775. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12776. ULONG EXPENTRY DdeGetData(hDmgData, pDst, cbMax, cbOff)%@NL@%
  12777. HDMGDATA hDmgData;%@NL@%
  12778. PBYTE pDst;%@NL@%
  12779. ULONG cbMax;%@NL@%
  12780. ULONG cbOff;%@NL@%
  12781. {%@NL@%
  12782.     PAPPINFO pai;%@NL@%
  12783. %@NL@%
  12784.     if ((pai = GetCurrentAppInfo(FALSE)) == NULL)%@NL@%
  12785.         return(0L);%@NL@%
  12786. %@NL@%
  12787.     if (!CheckSel(SELECTOROF(hDmgData))) {%@NL@%
  12788.         pai->LastError = DMGERR_INVALID_HDMGDATA;%@NL@%
  12789.         return(0L);%@NL@%
  12790.     }%@NL@%
  12791.     if (cbOff >= ((PMYDDES)hDmgData)->cbData) {%@NL@%
  12792.         pai->LastError = DMGERR_INVALIDPARAMETER;%@NL@%
  12793.         return(0L);%@NL@%
  12794.     }%@NL@%
  12795.     cbMax = min(cbMax, ((PMYDDES)hDmgData)->cbData - cbOff);%@NL@%
  12796.     if (pDst == NULL) %@NL@%
  12797.         return(((PMYDDES)hDmgData)->cbData - cbOff); %@NL@%
  12798.     CopyHugeBlock(HugeOffset(DDES_PABDATA(hDmgData), cbOff), pDst, cbMax);%@NL@%
  12799.     return(cbMax);%@NL@%
  12800. }%@NL@%
  12801. %@NL@%
  12802. %@NL@%
  12803. %@NL@%
  12804. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12805. %@AB@%* PUBDOC START%@NL@%
  12806. %@AB@%* PBYTE EXPENTRY DdeAccessData(hDmgData)%@NL@%
  12807. %@AB@%* HDMGDATA hDmgData;    // data handle to access%@NL@%
  12808. %@AB@%*%@NL@%
  12809. %@AB@%* This API returns a pointer to the data referenced by the data handle.%@NL@%
  12810. %@AB@%* The pointer returned becomes invalid once the data handle is freed%@NL@%
  12811. %@AB@%* or given to the DLL via callback return or API call.%@NL@%
  12812. %@AB@%*%@NL@%
  12813. %@AB@%* NOTE: applications MUST take care not to access beyond the limits of%@NL@%
  12814. %@AB@%* the data handle.  Only hDmgData's created by the application via%@NL@%
  12815. %@AB@%* a DdePutData() call may write to this memory prior to passing on%@NL@%
  12816. %@AB@%* to any DLL API or returning from the callback function.  Any hDmgData%@NL@%
  12817. %@AB@%* received from the DLL should be considered shared-readonly data and%@NL@%
  12818. %@AB@%* should be treated as such.  This applies whether the application owns%@NL@%
  12819. %@AB@%* the data handle or not.%@NL@%
  12820. %@AB@%*%@NL@%
  12821. %@AB@%* 0L is returned on error.%@NL@%
  12822. %@AB@%*%@NL@%
  12823. %@AB@%* PUBDOC END%@NL@%
  12824. %@AB@%*%@NL@%
  12825. %@AB@%* History:%@NL@%
  12826. %@AB@%*   Created     8/24/88    Sanfords%@NL@%
  12827. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12828. PBYTE EXPENTRY DdeAccessData(hDmgData)%@NL@%
  12829. HDMGDATA hDmgData;%@NL@%
  12830. {%@NL@%
  12831.     PAPPINFO pai;%@NL@%
  12832.     %@NL@%
  12833.     if ((pai = GetCurrentAppInfo(FALSE)) == NULL)%@NL@%
  12834.         return(0L);%@NL@%
  12835.     if (CheckSel(SELECTOROF(hDmgData))) {%@NL@%
  12836.         return(DDES_PABDATA(hDmgData));%@NL@%
  12837.     }%@NL@%
  12838.     pai->LastError = DMGERR_ACCESS_DENIED;%@NL@%
  12839.     return(0L);%@NL@%
  12840. }%@NL@%
  12841. %@NL@%
  12842. %@NL@%
  12843. %@NL@%
  12844. %@NL@%
  12845. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12846. %@AB@%* PUBDOC START%@NL@%
  12847. %@AB@%* BOOL EXPENTRY DdeFreeData(hDmgData)%@NL@%
  12848. %@AB@%* HDMGDATA hDmgData;        // data handle to destroy%@NL@%
  12849. %@AB@%*%@NL@%
  12850. %@AB@%* This routine should be called by an application wishing to release%@NL@%
  12851. %@AB@%* custody of an hDmgData it owns.%@NL@%
  12852. %@AB@%* An application owns any hDmgData%@NL@%
  12853. %@AB@%* it created with the HDATA_APPOWNED flag or an hDmgData given to%@NL@%
  12854. %@AB@%* it via DdeClientXfer(), DdeCheckQueue(), DdeAppNameServer(),%@NL@%
  12855. %@AB@%* DdeCreateInitPkt() or DdeProcessPkt().%@NL@%
  12856. %@AB@%*%@NL@%
  12857. %@AB@%* Returns fSuccess.  This function will fail if the hDmgData is not%@NL@%
  12858. %@AB@%* owned by the calling app.%@NL@%
  12859. %@AB@%*%@NL@%
  12860. %@AB@%* PUBDOC END%@NL@%
  12861. %@AB@%* History:%@NL@%
  12862. %@AB@%*   Created     12/14/88    Sanfords%@NL@%
  12863. %@AB@%*   6/12/90 sanfords    Fixed to work with non-DLL generated selectors%@NL@%
  12864. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12865. BOOL EXPENTRY DdeFreeData(hDmgData)%@NL@%
  12866. HDMGDATA hDmgData;%@NL@%
  12867. {%@NL@%
  12868.     PAPPINFO pai;%@NL@%
  12869.     USHORT cbSel;%@NL@%
  12870.     TID tid;%@NL@%
  12871. %@NL@%
  12872.     if ((pai = GetCurrentAppInfo(FALSE)) == NULL)%@NL@%
  12873.         return(FALSE);%@NL@%
  12874.         %@NL@%
  12875.     cbSel = CheckSel(SELECTOROF(hDmgData));%@NL@%
  12876.     if (!cbSel) {%@NL@%
  12877.         pai->LastError = DMGERR_INVALID_HDMGDATA;%@NL@%
  12878.         return(FALSE);%@NL@%
  12879.     }%@NL@%
  12880.     SemEnter();%@NL@%
  12881.     %@AB@%/*%@NL@%
  12882. %@AB@%     * Apps can only free handles the DLL does not own or handles from external%@NL@%
  12883. %@AB@%     * non-DLL DDE apps.%@NL@%
  12884. %@AB@%     */%@AE@%%@NL@%
  12885.     if (!FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDmgData, FPI_DELETE)) {%@NL@%
  12886.         pai->LastError = DMGERR_INVALID_HDMGDATA;%@NL@%
  12887.         SemLeave();%@NL@%
  12888.         return(FALSE);%@NL@%
  12889.     }    %@NL@%
  12890.             %@NL@%
  12891.     tid = pai->tid;%@NL@%
  12892.     do {%@NL@%
  12893.         if (FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDmgData, FPI_COUNT)) {%@NL@%
  12894.             SemLeave();%@NL@%
  12895.             return(TRUE);%@NL@%
  12896.         }%@NL@%
  12897.         pai = pai->nextThread;%@NL@%
  12898.     } while (pai && pai->tid != tid);%@NL@%
  12899.     DosFreeSeg(SELECTOROF(hDmgData));%@NL@%
  12900.         %@NL@%
  12901.     SemLeave();%@NL@%
  12902.     return(TRUE);    %@NL@%
  12903. }%@NL@%
  12904. %@NL@%
  12905. %@NL@%
  12906. %@NL@%
  12907. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12908. %@AB@%* PUBDOC START%@NL@%
  12909. %@AB@%* BOOL EXPENTRY DdeCopyBlock(pSrc, pDst, cb)%@NL@%
  12910. %@AB@%* PBYTE pSrc;   // source of copy%@NL@%
  12911. %@AB@%* PBYTE pDst;   // destination of copy%@NL@%
  12912. %@AB@%* ULONG cb;     // size in bytes of copy%@NL@%
  12913. %@AB@%*%@NL@%
  12914. %@AB@%* This copy utility can handle HUGE segments and can be used by any%@NL@%
  12915. %@AB@%* application as a copy utility.  This does not support overlapping huge%@NL@%
  12916. %@AB@%* copies.%@NL@%
  12917. %@AB@%*%@NL@%
  12918. %@AB@%* Returns fSuccess.%@NL@%
  12919. %@AB@%*%@NL@%
  12920. %@AB@%* PUBDOC END%@NL@%
  12921. %@AB@%* History:      1/1/89  created         sanfords%@NL@%
  12922. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12923. BOOL EXPENTRY DdeCopyBlock(pSrc, pDst, cb)%@NL@%
  12924. PBYTE pSrc;%@NL@%
  12925. PBYTE pDst;%@NL@%
  12926. ULONG cb;%@NL@%
  12927. {%@NL@%
  12928.     return(CopyHugeBlock(pSrc, pDst, cb));%@NL@%
  12929. }%@NL@%
  12930. %@NL@%
  12931. %@NL@%
  12932. %@NL@%
  12933. %@NL@%
  12934. %@AB@%/***************************************************************************\%@NL@%
  12935. %@AB@%* PUBDOC START%@NL@%
  12936. %@AB@%* HSZ management notes:%@NL@%
  12937. %@AB@%*%@NL@%
  12938. %@AB@%*   HSZs are used in this DLL to simplify string handling for applications%@NL@%
  12939. %@AB@%*   and for inter-process communication.  Since many applications use a%@NL@%
  12940. %@AB@%*   fixed set of Application/Topic/Item names, it is convenient to convert%@NL@%
  12941. %@AB@%*   them to HSZs and allow quick comparisons for lookups.  This also frees%@NL@%
  12942. %@AB@%*   the DLL up from having to constantly provide string buffers for copying%@NL@%
  12943. %@AB@%*   strings between itself and its clients.%@NL@%
  12944. %@AB@%*%@NL@%
  12945. %@AB@%*   HSZs are the same as atoms except they have no restrictions on length or%@NL@%
  12946. %@AB@%*   number and are 32 bit values.  They are case preserving and can be%@NL@%
  12947. %@AB@%*   compared directly for case sensitive comparisons or via DdeCmpHsz()%@NL@%
  12948. %@AB@%*   for case insensitive comparisons.%@NL@%
  12949. %@AB@%*%@NL@%
  12950. %@AB@%*   When an application creates an HSZ via DdeGetHsz() or increments its%@NL@%
  12951. %@AB@%*   count via DdeIncHszCount() it is essentially claiming the HSZ for%@NL@%
  12952. %@AB@%*   its own use.  On the other hand, when an application is given an%@NL@%
  12953. %@AB@%*   HSZ from the DLL via a callback, it is using another application's HSZ%@NL@%
  12954. %@AB@%*   and should not free that HSZ via DdeFreeHsz().%@NL@%
  12955. %@AB@%*%@NL@%
  12956. %@AB@%*   The DLL insures that during the callback any HSZs given will remain%@NL@%
  12957. %@AB@%*   valid for the duration of the callback.%@NL@%
  12958. %@AB@%*%@NL@%
  12959. %@AB@%*   If an application wishes to keep that HSZ to use for itself as a%@NL@%
  12960. %@AB@%*   standard for future comparisons, it should increment its count so that,%@NL@%
  12961. %@AB@%*   should the owning application free it, the HSZ will not become invalid.%@NL@%
  12962. %@AB@%*   This also prevents an HSZ from changing its value.  (ie, app A frees it%@NL@%
  12963. %@AB@%*   and then app B creates a new one that happens to use the same HSZ code,%@NL@%
  12964. %@AB@%*   then app C, which had the HSZ stored all along (but forgot to increment%@NL@%
  12965. %@AB@%*   its count) now is holding a handle to a different string.)%@NL@%
  12966. %@AB@%*%@NL@%
  12967. %@AB@%*   Applications may free HSZs they have created or incremented at any time%@NL@%
  12968. %@AB@%*   by calling DdeFreeHsz().%@NL@%
  12969. %@AB@%*%@NL@%
  12970. %@AB@%*   The DLL internally increments HSZ counts while in use so that they will%@NL@%
  12971. %@AB@%*   not be destroyed until both the DLL and all applications concerned are%@NL@%
  12972. %@AB@%*   through with them.%@NL@%
  12973. %@AB@%*%@NL@%
  12974. %@AB@%*   IT IS THE APPLICATIONS RESPONSIBILITY TO PROPERLY CREATE AND FREE HSZs!!%@NL@%
  12975. %@AB@%*%@NL@%
  12976. %@AB@%* PUBDOC END%@NL@%
  12977. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  12978. %@NL@%
  12979. %@NL@%
  12980. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  12981. %@AB@%* PUBDOC START%@NL@%
  12982. %@AB@%* HSZ EXPENTRY DdeGetHsz(psz, country, codepage)%@NL@%
  12983. %@AB@%* PSZ psz;          // string to HSZize.%@NL@%
  12984. %@AB@%* USHORT country;   // country ID to use in comparisons.%@NL@%
  12985. %@AB@%* USHORT codepage;  // codepage to use in comparisons.%@NL@%
  12986. %@AB@%*%@NL@%
  12987. %@AB@%* This routine returns a string handle to the psz passed in.%@NL@%
  12988. %@AB@%* 0 is returned on failure or for NULL strings.%@NL@%
  12989. %@AB@%*%@NL@%
  12990. %@AB@%* If country is 0, the default system country code is used.%@NL@%
  12991. %@AB@%* If codepage is 0, the default system codepage code is used.%@NL@%
  12992. %@AB@%*%@NL@%
  12993. %@AB@%* String handles are similar to atoms but without the 255%@NL@%
  12994. %@AB@%* character limit on strings.  String handles are case preserving.%@NL@%
  12995. %@AB@%* see DdeCmpHsz().%@NL@%
  12996. %@AB@%*%@NL@%
  12997. %@AB@%* String handles are consistant across all processes using the DLL.%@NL@%
  12998. %@AB@%*%@NL@%
  12999. %@AB@%* PUBDOC END%@NL@%
  13000. %@AB@%*%@NL@%
  13001. %@AB@%* History:      1/1/89 created         sanfords%@NL@%
  13002. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13003. HSZ EXPENTRY DdeGetHsz(psz, country, codepage)%@NL@%
  13004. PSZ psz;%@NL@%
  13005. USHORT country, codepage;%@NL@%
  13006. {%@NL@%
  13007.     PAPPINFO pai;%@NL@%
  13008. %@NL@%
  13009.     if ((pai = GetCurrentAppInfo(FALSE)) == NULL)%@NL@%
  13010.         return(0);%@NL@%
  13011. %@NL@%
  13012.     return(GetHsz(psz, country, codepage, TRUE));%@NL@%
  13013. }%@NL@%
  13014. %@NL@%
  13015. %@NL@%
  13016. %@NL@%
  13017. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13018. %@AB@%* PUBDOC START%@NL@%
  13019. %@AB@%* BOOL EXPENTRY DdeFreeHsz(hsz)%@NL@%
  13020. %@AB@%* HSZ hsz;      // string handle to free%@NL@%
  13021. %@AB@%*%@NL@%
  13022. %@AB@%* This function decrements the usage count for the HSZ given and frees%@NL@%
  13023. %@AB@%* it if the count becomes 0.%@NL@%
  13024. %@AB@%*%@NL@%
  13025. %@AB@%* PUBDOC END%@NL@%
  13026. %@AB@%*%@NL@%
  13027. %@AB@%* History:      1/1/89 created         sanfords%@NL@%
  13028. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13029. BOOL EXPENTRY DdeFreeHsz(hsz)%@NL@%
  13030. HSZ hsz;%@NL@%
  13031. {%@NL@%
  13032.     PAPPINFO pai;%@NL@%
  13033. %@NL@%
  13034.     if ((pai = GetCurrentAppInfo(FALSE)) == NULL)%@NL@%
  13035.         return(0);%@NL@%
  13036.     return(FreeHsz(hsz));%@NL@%
  13037. }%@NL@%
  13038. %@NL@%
  13039. %@NL@%
  13040. %@NL@%
  13041. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13042. %@AB@%* PUBDOC START%@NL@%
  13043. %@AB@%* BOOL EXPENTRY DdeIncHszCount(hsz)%@NL@%
  13044. %@AB@%* HSZ hsz;  // string handle to increment.%@NL@%
  13045. %@AB@%*%@NL@%
  13046. %@AB@%* This function increments the usage count for the HSZ given.  This is%@NL@%
  13047. %@AB@%* useful when an application wishes to keep an HSZ given to it in its%@NL@%
  13048. %@AB@%* callback.%@NL@%
  13049. %@AB@%*%@NL@%
  13050. %@AB@%* PUBDOC END%@NL@%
  13051. %@AB@%*%@NL@%
  13052. %@AB@%* History:      1/1/89 created         sanfords%@NL@%
  13053. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13054. BOOL EXPENTRY DdeIncHszCount(hsz)%@NL@%
  13055. HSZ hsz;%@NL@%
  13056. {%@NL@%
  13057.     PAPPINFO pai;%@NL@%
  13058. %@NL@%
  13059.     if ((pai = GetCurrentAppInfo(FALSE)) == NULL)%@NL@%
  13060.         return(0);%@NL@%
  13061. %@NL@%
  13062.     return(IncHszCount(hsz));%@NL@%
  13063. }%@NL@%
  13064. %@NL@%
  13065. %@NL@%
  13066. %@NL@%
  13067. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13068. %@AB@%* PUBDOC START%@NL@%
  13069. %@AB@%* USHORT EXPENTRY DdeGetHszString(hsz, psz, cchMax)%@NL@%
  13070. %@AB@%* HSZ hsz;      // string handle to extract string from%@NL@%
  13071. %@AB@%* PSZ psz;      // buffer for case-sensitive string%@NL@%
  13072. %@AB@%* ULONG cchMax; // buffer size.%@NL@%
  13073. %@AB@%*%@NL@%
  13074. %@AB@%* This API is the inverse of DdeGetHsz().  The actual length of the%@NL@%
  13075. %@AB@%* string (without NULL terminator) referenced by hsz is returned.%@NL@%
  13076. %@AB@%*%@NL@%
  13077. %@AB@%* if psz is NULL, no string is returned in psz.%@NL@%
  13078. %@AB@%* 0 is returned if hsz does not exist or is wild.%@NL@%
  13079. %@AB@%* If hsz is wild, psz will be set to a 0 length string.%@NL@%
  13080. %@AB@%*%@NL@%
  13081. %@AB@%* PUBDOC END%@NL@%
  13082. %@AB@%* History:      Created 5/10/89         sanfords%@NL@%
  13083. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13084. USHORT EXPENTRY DdeGetHszString(hsz, psz, cchMax)%@NL@%
  13085. HSZ hsz;%@NL@%
  13086. PSZ psz;%@NL@%
  13087. ULONG cchMax;%@NL@%
  13088. {%@NL@%
  13089.     if (psz) {%@NL@%
  13090.         if (hsz) {%@NL@%
  13091.             return(QueryHszName(hsz, psz, (USHORT)cchMax));%@NL@%
  13092.         } else {%@NL@%
  13093.             *psz = '\0';%@NL@%
  13094.             return(0);%@NL@%
  13095.         }%@NL@%
  13096.     } else if (hsz) {%@NL@%
  13097.         return(QueryHszLength(hsz));%@NL@%
  13098.     } else {%@NL@%
  13099.         return(0);%@NL@%
  13100.     }%@NL@%
  13101. }%@NL@%
  13102. %@NL@%
  13103. %@NL@%
  13104. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13105. %@AB@%* PUBDOC START%@NL@%
  13106. %@AB@%* SHORT EXPENTRY DdeCmpHsz(hsz1, hsz2)%@NL@%
  13107. %@AB@%* HSZ hsz1, hsz2;   // string handles to compare.%@NL@%
  13108. %@AB@%*%@NL@%
  13109. %@AB@%* This routine returns:%@NL@%
  13110. %@AB@%*   0  if hsz1 is of equal  rank to   hsz2%@NL@%
  13111. %@AB@%*   -2 if hsz1 is invalid.%@NL@%
  13112. %@AB@%*   -1 if hsz1 is of lower  rank than hsz2%@NL@%
  13113. %@AB@%*   1  if hsz1 is of higher rank than hsz2.%@NL@%
  13114. %@AB@%*   2  if hsz2 is invalid.%@NL@%
  13115. %@AB@%*%@NL@%
  13116. %@AB@%* Note that direct comparison of hszs (ie (hsz1 == hsz2)) is a case sensitive%@NL@%
  13117. %@AB@%* comparison.  This function performs a case insensitive comparison.  Thus%@NL@%
  13118. %@AB@%* different valued hszs may actually be equal.%@NL@%
  13119. %@AB@%* A ranking is provided for binary searching.%@NL@%
  13120. %@AB@%*%@NL@%
  13121. %@AB@%* PUBDOC END%@NL@%
  13122. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13123. SHORT EXPENTRY DdeCmpHsz(hsz1, hsz2)%@NL@%
  13124. HSZ hsz1, hsz2;%@NL@%
  13125. {%@NL@%
  13126.     return(CmpHsz(hsz1, hsz2));%@NL@%
  13127. }%@NL@%
  13128. %@NL@%
  13129. %@NL@%
  13130. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13131. %@AB@%* PUBDOC START%@NL@%
  13132. %@AB@%* ULONG EXPENTRY DdeCheckQueue(hConv, phDmgData, idXfer, afCmd)%@NL@%
  13133. %@AB@%* HCONV hConv;          // related convesation handle%@NL@%
  13134. %@AB@%* PHDMGDATA phDmgData;  // OUTPUT: for resultant data handle, or NULL%@NL@%
  13135. %@AB@%* ULONG idXfer;         // transaction ID or QID_NEWEST or QID_OLDEST%@NL@%
  13136. %@AB@%* ULONG afCmd;          // queue operation code.%@NL@%
  13137. %@AB@%*%@NL@%
  13138. %@AB@%*       This routine checks a client conversation's assynchronous %@NL@%
  13139. %@AB@%*       transaction queue for queued transaction status.  This allows a %@NL@%
  13140. %@AB@%*       client to extract data or monitor the status of any transaction %@NL@%
  13141. %@AB@%*       previously started asynchronously.  (TIMEOUT_ASSYNC) hConv is %@NL@%
  13142. %@AB@%*       the client conversation who's queue is being checked.  %@NL@%
  13143. %@AB@%*%@NL@%
  13144. %@AB@%*       If phDmgData is not NULL and the referenced item has data to %@NL@%
  13145. %@AB@%*       return to the client, phDmgData is filled.  Returned hDmgDatas %@NL@%
  13146. %@AB@%*       must be freed by the application.  phDmgData will be filled with %@NL@%
  13147. %@AB@%*       0L if no return data is applicable or if the transaction is not %@NL@%
  13148. %@AB@%*       complete.  %@NL@%
  13149. %@AB@%*%@NL@%
  13150. %@AB@%*       If the queue is not periodicly flushed by an application %@NL@%
  13151. %@AB@%*       issueing asynchronous transactions the queue is automaticly%@NL@%
  13152. %@AB@%*       flushed as needed.  Oldest transactions are flushed first.  %@NL@%
  13153. %@AB@%*       DdeProcessPkt() and DdeDisconnect() and DdeEndEnumServers%@NL@%
  13154. %@AB@%*       remove items from this queue.  %@NL@%
  13155. %@AB@%*%@NL@%
  13156. %@AB@%*       idXfer is the transaction id returned by an asynchronous call to %@NL@%
  13157. %@AB@%*       DdeClientXfer().%@NL@%
  13158. %@AB@%* %@NL@%
  13159. %@AB@%* afCmd = CQ_FLUSH - remove all items in the queue - return is fSuccess.%@NL@%
  13160. %@AB@%* afCmd = CQ_REMOVE - the item referenced is removed from the queue.%@NL@%
  13161. %@AB@%* afCmd = CQ_NEXT - references the idXfer AFTER (more recent than) the id %@NL@%
  13162. %@AB@%*       given. 0 is returned if the ID given was the newest in the %@NL@%
  13163. %@AB@%*       queue otherwise the next ID is returned.%@NL@%
  13164. %@AB@%* afCmd = CQ_PREV - references the idXfer BEFORE (less recent than) the id %@NL@%
  13165. %@AB@%*       given. 0 is returned if the ID given was the oldest in the %@NL@%
  13166. %@AB@%*       queue otherwise the previous ID is returned.%@NL@%
  13167. %@AB@%* afCmd = CQ_COUNT    - returns the number of entries in the queue.%@NL@%
  13168. %@AB@%*%@NL@%
  13169. %@AB@%*       By ORing in one of the following flags, the above flags can be %@NL@%
  13170. %@AB@%*       made to reference the apropriate subset of queue entries: %@NL@%
  13171. %@AB@%*%@NL@%
  13172. %@AB@%* afCmd = CQ_ACTIVEONLY - incomplete active transactions only.%@NL@%
  13173. %@AB@%* afCmd = CQ_COMPLETEDONLY - completed transactions only.%@NL@%
  13174. %@AB@%* afCmd = CQ_FAILEDONLY - transactions which had protocol violations or%@NL@%
  13175. %@AB@%*                         communication failures.%@NL@%
  13176. %@AB@%* afCmd = CQ_INACTIVEONLY - The complement of CQ_ACTIVEONLY which is the%@NL@%
  13177. %@AB@%*                           union of CQ_COMPLETEDONLY and CQ_FAILEDONLY.%@NL@%
  13178. %@AB@%* %@NL@%
  13179. %@AB@%* if phdmgdata = NULL, no hdmgdata is returned.%@NL@%
  13180. %@AB@%* if idXfer == QID_NEWEST, the top-most (most recent) entry in the %@NL@%
  13181. %@AB@%*       queue is referenced.%@NL@%
  13182. %@AB@%* if idXfer == QID_OLDEST, the bottom-most (oldest) entry ID is %@NL@%
  13183. %@AB@%*       referenced.%@NL@%
  13184. %@AB@%*%@NL@%
  13185. %@AB@%*       returns the ID of the item processed if it applies, or the count %@NL@%
  13186. %@AB@%*       of items or fSuccess.  %@NL@%
  13187. %@AB@%*%@NL@%
  13188. %@AB@%*%@NL@%
  13189. %@AB@%* Standard usage examples:%@NL@%
  13190. %@AB@%*%@NL@%
  13191. %@AB@%*   To get the state of the oldest transaction:%@NL@%
  13192. %@AB@%*   id = DdeCheckQueue(hConv, &hDmgData, QID_OLDEST, 0)%@NL@%
  13193. %@AB@%*%@NL@%
  13194. %@AB@%*   To get and flush the next completed transaction data, if there is %@NL@%
  13195. %@AB@%*       any:%@NL@%
  13196. %@AB@%*   id = DdeCheckQueue(hConv, &hDmgData, QID_OLDEST, CQ_REMOVE | %@NL@%
  13197. %@AB@%*       CQ_INACTIVEONLY)%@NL@%
  13198. %@AB@%*%@NL@%
  13199. %@AB@%*   To flush all successfully completed transactions:%@NL@%
  13200. %@AB@%*   DdeCheckQueue(hConv, NULL, QID_OLDEST, CQ_FLUSH | CQ_COMPLETEDONLY)%@NL@%
  13201. %@AB@%*%@NL@%
  13202. %@AB@%*   To see if a specific transaction is complete, and if so, to get the%@NL@%
  13203. %@AB@%*   information and remove the transaction from the queue:%@NL@%
  13204. %@AB@%*   if (DdeCheckQueue(hConv, &hDmgData, id, CQ_REMOVE | CQ_INACTIVEONLY))%@NL@%
  13205. %@AB@%*       ProcessAndFreeData(hDmgData);%@NL@%
  13206. %@AB@%*       %@NL@%
  13207. %@AB@%* PUBDOC END%@NL@%
  13208. %@AB@%* History:      Created 6/6/89         sanfords%@NL@%
  13209. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13210. ULONG EXPENTRY DdeCheckQueue(hConv, phDmgData, idXfer, afCmd)%@NL@%
  13211. HCONV hConv;%@NL@%
  13212. PHDMGDATA phDmgData;%@NL@%
  13213. ULONG idXfer;%@NL@%
  13214. ULONG afCmd;%@NL@%
  13215. {%@NL@%
  13216.     PAPPINFO pai;%@NL@%
  13217.     PCLIENTINFO pci;%@NL@%
  13218.     PCQDATA pcqd, pcqdT, pcqdEnd;%@NL@%
  13219.     USHORT err;%@NL@%
  13220.     ULONG retVal = TRUE;%@NL@%
  13221.     int i;%@NL@%
  13222. %@NL@%
  13223.     if ((pai = GetCurrentAppInfo(TRUE)) == 0)%@NL@%
  13224.         return(0);%@NL@%
  13225. %@NL@%
  13226.     SemCheckOut();%@NL@%
  13227.     SemEnter();%@NL@%
  13228.     %@NL@%
  13229.     err = DMGERR_INVALIDPARAMETER;%@NL@%
  13230.     if (!WinIsWindow(DMGHAB, hConv) ||%@NL@%
  13231.             !(BOOL)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_CLIENT, 0L) ||%@NL@%
  13232.             idXfer == QID_SYNC) {%@NL@%
  13233.         goto failExit;%@NL@%
  13234.     }%@NL@%
  13235.     %@NL@%
  13236.     if (!(pci = (PCLIENTINFO)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_ALL, 0L))) %@NL@%
  13237.         goto failExit;%@NL@%
  13238.     %@NL@%
  13239.     err = DMGERR_UNFOUND_QUEUE_ID;%@NL@%
  13240.     if ((pcqd = (PCQDATA)Findqi(pci->pQ, idXfer)) == NULL)%@NL@%
  13241.         goto failExit;%@NL@%
  13242. %@NL@%
  13243.     %@AB@%/*%@NL@%
  13244. %@AB@%     * if referencing an end item, make sure it fits any subset flags.%@NL@%
  13245. %@AB@%     * If it doesn't we alter afCmd to force us to the first qualifying%@NL@%
  13246. %@AB@%     * entry in the correct direction.%@NL@%
  13247. %@AB@%     */%@AE@%%@NL@%
  13248.     if (!fInSubset(pcqd, afCmd)) {%@NL@%
  13249.         if (idXfer & (QID_OLDEST))%@NL@%
  13250.             afCmd |= CQ_NEXT;%@NL@%
  13251.         else if (idXfer & (QID_NEWEST))%@NL@%
  13252.             afCmd |= CQ_PREV;%@NL@%
  13253.         else if (!(afCmd & (CQ_NEXT | CQ_PREV | CQ_COUNT | CQ_FLUSH)))%@NL@%
  13254.             goto failExit;%@NL@%
  13255.     }%@NL@%
  13256.     %@NL@%
  13257.     if (afCmd & CQ_NEXT) {%@NL@%
  13258.         pcqdEnd = (PCQDATA)pci->pQ->pqiHead->next;%@NL@%
  13259.         if ((pcqd = (PCQDATA)pcqd->next) == pcqdEnd)%@NL@%
  13260.             goto failExit;%@NL@%
  13261.         while (!fInSubset(pcqd, afCmd)) {%@NL@%
  13262.             if ((pcqd = (PCQDATA)pcqd->next) == pcqdEnd)%@NL@%
  13263.                 goto failExit;%@NL@%
  13264.         }%@NL@%
  13265.     }%@NL@%
  13266.             %@NL@%
  13267.     if (afCmd & CQ_PREV) {%@NL@%
  13268.         pcqdEnd = (PCQDATA)pci->pQ->pqiHead;%@NL@%
  13269.         if ((pcqd = (PCQDATA)pcqd->prev) == pcqdEnd)%@NL@%
  13270.             goto failExit;%@NL@%
  13271.         while (!fInSubset(pcqd, afCmd)) {%@NL@%
  13272.             if ((pcqd = (PCQDATA)pcqd->prev) == pcqdEnd)%@NL@%
  13273.                 goto failExit;%@NL@%
  13274.         }%@NL@%
  13275.     }%@NL@%
  13276.     %@NL@%
  13277.     %@AB@%/*%@NL@%
  13278. %@AB@%     * pcqd now points to the apropriate entry%@NL@%
  13279. %@AB@%     */%@AE@%%@NL@%
  13280. %@NL@%
  13281.     if (afCmd & CQ_COUNT) %@NL@%
  13282.         retVal = 0;%@NL@%
  13283.     else%@NL@%
  13284.         retVal = MAKEID(pcqd);%@NL@%
  13285. %@NL@%
  13286.     %@AB@%/*%@NL@%
  13287. %@AB@%     * Fill phDmgData if specified.%@NL@%
  13288. %@AB@%     */%@AE@%%@NL@%
  13289.     if (phDmgData != NULL)%@NL@%
  13290.         if ((pcqd->xad.state == CONVST_CONNECTED) &&%@NL@%
  13291.                 CheckSel(SELECTOROF(pcqd->xad.pddes))) {%@NL@%
  13292.             *phDmgData = pcqd->xad.pddes;%@NL@%
  13293.             AddPileItem(pai->pHDataPile, (PBYTE)phDmgData, CmpULONG);%@NL@%
  13294.             if (((PMYDDES)*phDmgData)->magic == MYDDESMAGIC) {%@NL@%
  13295.                 ((PMYDDES)*phDmgData)->fs |= HDATA_READONLY;%@NL@%
  13296.             }%@NL@%
  13297.         } else%@NL@%
  13298.             *phDmgData = NULL;%@NL@%
  13299. %@NL@%
  13300.     %@AB@%/*%@NL@%
  13301. %@AB@%     * remove pcqd if apropriate.%@NL@%
  13302. %@AB@%     */%@AE@%%@NL@%
  13303.     if (afCmd & (CQ_REMOVE | CQ_FLUSH)) {%@NL@%
  13304.         if (!FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&pcqd->xad.pddes,%@NL@%
  13305.                 0))%@NL@%
  13306.             FreeData((PMYDDES)pcqd->xad.pddes, pai);%@NL@%
  13307.         %@AB@%/*%@NL@%
  13308. %@AB@%         * Decrement the use count we incremented when the client started%@NL@%
  13309. %@AB@%         * this transaction.%@NL@%
  13310. %@AB@%         */%@AE@%%@NL@%
  13311.         FreeHsz(pcqd->XferInfo.hszItem);%@NL@%
  13312.         Deleteqi(pci->pQ, MAKEID(pcqd));%@NL@%
  13313.     }%@NL@%
  13314. %@NL@%
  13315.     %@AB@%/*%@NL@%
  13316. %@AB@%     * go through entire list and flush or count if specified.%@NL@%
  13317. %@AB@%     */%@AE@%%@NL@%
  13318.     if (afCmd & (CQ_FLUSH | CQ_COUNT)) {%@NL@%
  13319.         pcqd = (PCQDATA)pci->pQ->pqiHead;%@NL@%
  13320.         for (i = pci->pQ->cItems; i; i--) {%@NL@%
  13321.             if (fInSubset(pcqd, afCmd)) {%@NL@%
  13322.                 if (afCmd & CQ_COUNT) %@NL@%
  13323.                     retVal++;%@NL@%
  13324.                 if (afCmd & CQ_FLUSH) {%@NL@%
  13325.                     pcqdT = (PCQDATA)pcqd->next;%@NL@%
  13326.                     %@AB@%/*%@NL@%
  13327. %@AB@%                     * Only free the data if not logged - ie the user never got a%@NL@%
  13328. %@AB@%                     * copy.%@NL@%
  13329. %@AB@%                     */%@AE@%%@NL@%
  13330.                     if (!FindPileItem(pci->ci.pai->pHDataPile, CmpULONG,%@NL@%
  13331.                             (PBYTE)&pcqd->xad.pddes, 0))%@NL@%
  13332.                         FreeData((PMYDDES)pcqd->xad.pddes, pai);%@NL@%
  13333.                     %@AB@%/*%@NL@%
  13334. %@AB@%                     * Decrement the use count we incremented when the client started%@NL@%
  13335. %@AB@%                     * this transaction.%@NL@%
  13336. %@AB@%                     */%@AE@%%@NL@%
  13337.                     FreeHsz(pcqd->XferInfo.hszItem);%@NL@%
  13338.                     Deleteqi(pci->pQ, MAKEID(pcqd));%@NL@%
  13339.                     pcqd = pcqdT;%@NL@%
  13340.                     continue;%@NL@%
  13341.                 }%@NL@%
  13342.             }%@NL@%
  13343.             pcqd = (PCQDATA)pcqd->next;%@NL@%
  13344.         }%@NL@%
  13345.     }%@NL@%
  13346.         %@NL@%
  13347.     SemLeave();%@NL@%
  13348.     SemCheckOut();%@NL@%
  13349.     return(retVal);%@NL@%
  13350.     %@NL@%
  13351. failExit:%@NL@%
  13352.     pai->LastError = err;%@NL@%
  13353.     SemLeave();%@NL@%
  13354.     SemCheckOut();%@NL@%
  13355.     return(0);%@NL@%
  13356. }%@NL@%
  13357. %@NL@%
  13358. %@NL@%
  13359. %@NL@%
  13360. BOOL fInSubset(pcqd, afCmd)%@NL@%
  13361. PCQDATA pcqd;%@NL@%
  13362. ULONG afCmd;%@NL@%
  13363. {%@NL@%
  13364.     if (afCmd & CQ_ACTIVEONLY && (pcqd->xad.state <= CONVST_INIT1))%@NL@%
  13365.         return(FALSE);%@NL@%
  13366. %@NL@%
  13367.     if (afCmd & CQ_INACTIVEONLY && (pcqd->xad.state > CONVST_INIT1))%@NL@%
  13368.         return(FALSE);%@NL@%
  13369. %@NL@%
  13370.     if (afCmd & CQ_COMPLETEDONLY && (pcqd->xad.state != CONVST_CONNECTED))%@NL@%
  13371.         return(FALSE);%@NL@%
  13372.                             %@NL@%
  13373.     if (afCmd & CQ_FAILEDONLY && (pcqd->xad.state > CONVST_TERMINATED))%@NL@%
  13374.         return(FALSE);%@NL@%
  13375.     return(TRUE);%@NL@%
  13376. }%@NL@%
  13377. %@NL@%
  13378. %@NL@%
  13379. %@NL@%
  13380. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13381. %@AB@%* PUBDOC START%@NL@%
  13382. %@AB@%* BOOL EXPENTRY DdeEnableCallback(hConv, fEnable)%@NL@%
  13383. %@AB@%* HCONV hConv;      // server conversation handle to enable/disable or NULL %@NL@%
  13384. %@AB@%* BOOL fEnable;     // TRUE enables, FALSE disables callbacks.%@NL@%
  13385. %@AB@%*%@NL@%
  13386. %@AB@%* This routine is used by an application that does not want to be interrupted%@NL@%
  13387. %@AB@%* by DLL calls to its Callback function.  When callbacks are disabled,%@NL@%
  13388. %@AB@%* all non critical attempts to call the Callback function instead result in%@NL@%
  13389. %@AB@%* the call being placed on a server transaction queue until callbacks are%@NL@%
  13390. %@AB@%* reenabled.  An application should reenable callbacks in a timely manner%@NL@%
  13391. %@AB@%* to avoid causing synchronous clients to time out.%@NL@%
  13392. %@AB@%*%@NL@%
  13393. %@AB@%* note that DdeProcessPkt() has the side effect of unblocking and removing%@NL@%
  13394. %@AB@%* items from the server transaction queue when processing return packets.%@NL@%
  13395. %@AB@%* DdeDisconnect() and DdeEndEnumServers() have the side effect of removing%@NL@%
  13396. %@AB@%* any transactions for the disconnected conversation.%@NL@%
  13397. %@AB@%*%@NL@%
  13398. %@AB@%* If hConv is non-NULL, only the hConv conversation is affected.%@NL@%
  13399. %@AB@%* If hConv is NULL, all conversations are affected.%@NL@%
  13400. %@AB@%*%@NL@%
  13401. %@AB@%* Callbacks can also be disabled on return from the callback function by%@NL@%
  13402. %@AB@%* returning the constant CBR_BLOCK.  This has the same effect as%@NL@%
  13403. %@AB@%* calling DdeEnableCallback(hConv, FALSE) except that the callback%@NL@%
  13404. %@AB@%* returned from is placed back on the callback queue for later re-submission%@NL@%
  13405. %@AB@%* to the callback function when the conversations callbacks are reenabled.%@NL@%
  13406. %@AB@%* This allows a server that needs a long time to process a request to delay%@NL@%
  13407. %@AB@%* returning the result without blocking within the callback function.%@NL@%
  13408. %@AB@%* %@NL@%
  13409. %@AB@%* No callbacks are made within this function.%@NL@%
  13410. %@AB@%* %@NL@%
  13411. %@AB@%* Note:  Callback transactions that have XTYPF_NOBLOCK set in their usType%@NL@%
  13412. %@AB@%*       parameter cannot be blocked by CBR_BLOCK.%@NL@%
  13413. %@AB@%*       These callbacks are issued to the server regardless of the state of%@NL@%
  13414. %@AB@%*       callback enableing.%@NL@%
  13415. %@AB@%*%@NL@%
  13416. %@AB@%* fSuccess is returned.%@NL@%
  13417. %@AB@%*%@NL@%
  13418. %@AB@%* PUBDOC END%@NL@%
  13419. %@AB@%* History:      Created 6/6/89         sanfords%@NL@%
  13420. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13421. BOOL EXPENTRY DdeEnableCallback(hConv, fEnable)%@NL@%
  13422. HCONV hConv;%@NL@%
  13423. BOOL fEnable;%@NL@%
  13424. {%@NL@%
  13425.     PAPPINFO pai;%@NL@%
  13426. %@NL@%
  13427.     if ((pai = GetCurrentAppInfo(TRUE)) == 0)%@NL@%
  13428.         return(FALSE);%@NL@%
  13429. %@NL@%
  13430.     SemCheckOut();%@NL@%
  13431.     SemEnter();%@NL@%
  13432.     if (hConv == NULL) {%@NL@%
  13433.         pai->fEnableCB = fEnable = fEnable ? TRUE : FALSE;%@NL@%
  13434.         FlushLst(pai->plstCBExceptions);%@NL@%
  13435.     } else if (pai->fEnableCB != fEnable) {%@NL@%
  13436.         if (pai->plstCBExceptions == NULL) %@NL@%
  13437.             pai->plstCBExceptions = CreateLst(pai->hheapApp, sizeof(HWNDLI));%@NL@%
  13438.         AddHwndList((HWND)hConv, pai->plstCBExceptions);%@NL@%
  13439.     }%@NL@%
  13440.     SemLeave();%@NL@%
  13441.     if (fEnable)%@NL@%
  13442.         WinPostMsg(pai->hwndDmg, UM_CHECKCBQ, (MPARAM)pai, 0L);%@NL@%
  13443.     return(TRUE);%@NL@%
  13444. }%@NL@%
  13445. %@NL@%
  13446. %@NL@%
  13447. %@NL@%
  13448. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13449. %@AB@%* PUBDOC START%@NL@%
  13450. %@AB@%* HDMGDATA EXPENTRY DdeAppNameServer(hszApp, afCmd);%@NL@%
  13451. %@AB@%* HSZ hszApp;       // referenced app name%@NL@%
  13452. %@AB@%* USHORT afCmd;     // action code.%@NL@%
  13453. %@AB@%*%@NL@%
  13454. %@AB@%* Updates or queries the DDE DLL application name server.  The DDE name%@NL@%
  13455. %@AB@%* server acts as a filter for initiate messages on behalf of registered%@NL@%
  13456. %@AB@%* applications and serves as a way for an application to determine what%@NL@%
  13457. %@AB@%* other applications are available without the need for wild initiates.%@NL@%
  13458. %@AB@%* Any change in the name server results in XTYP_REGISTER or XTYP_UNREGISTER%@NL@%
  13459. %@AB@%* callbacks to all other applications.  Agents will not be allowed to%@NL@%
  13460. %@AB@%* know about any other agent registrations.%@NL@%
  13461. %@AB@%*%@NL@%
  13462. %@AB@%* afCmd:%@NL@%
  13463. %@AB@%*%@NL@%
  13464. %@AB@%*   ANS_REGISTER%@NL@%
  13465. %@AB@%*       Adds hszApp to the name server.  hszApp cannot be NULL.%@NL@%
  13466. %@AB@%*       All other applications will receive a registration notification%@NL@%
  13467. %@AB@%*       if their callback filters allow it.%@NL@%
  13468. %@AB@%*       fSuccess is returned.%@NL@%
  13469. %@AB@%*%@NL@%
  13470. %@AB@%*   ANS_UNREGISTER%@NL@%
  13471. %@AB@%*       Remove hszApp from the name server.  If hszApp==NULL the name server%@NL@%
  13472. %@AB@%*       is cleared for the calling application.%@NL@%
  13473. %@AB@%*       All other applications will receive a deregistration notification%@NL@%
  13474. %@AB@%*       if their callback filters allow it.%@NL@%
  13475. %@AB@%*       fSuccess is returned.%@NL@%
  13476. %@AB@%*%@NL@%
  13477. %@AB@%*   ANS_QUERYALLBUTME%@NL@%
  13478. %@AB@%*       Returns a zero terminated array of hszApps/hApp pairs registered with%@NL@%
  13479. %@AB@%*       the name server by all other applications.%@NL@%
  13480. %@AB@%*       (Agent applications do not see other agent registered names.)%@NL@%
  13481. %@AB@%*       If hszApp is set, only names matching* hszApp are placed into the list.%@NL@%
  13482. %@AB@%*       0 is returned if no applicable names were found.%@NL@%
  13483. %@AB@%*%@NL@%
  13484. %@AB@%*   ANS_QUERYMINE%@NL@%
  13485. %@AB@%*       Returns a zero terminated array of hszApps registered with the name%@NL@%
  13486. %@AB@%*       server by the calling application.  If hszApp is set, only names%@NL@%
  13487. %@AB@%*       matching hszApp are placed into the list.  0 is returned if no%@NL@%
  13488. %@AB@%*       applicable names were found.%@NL@%
  13489. %@AB@%*%@NL@%
  13490. %@AB@%*   The following flags may be ORed in with one of the above flags:%@NL@%
  13491. %@AB@%*%@NL@%
  13492. %@AB@%*   ANS_FILTERON%@NL@%
  13493. %@AB@%*       Turns on dde initiate callback filtering.  Only wild app names or%@NL@%
  13494. %@AB@%*       those matching a registered name are given to the application for%@NL@%
  13495. %@AB@%*       initiate requests or registration notifications.%@NL@%
  13496. %@AB@%*%@NL@%
  13497. %@AB@%*   ANS_FILTEROFF%@NL@%
  13498. %@AB@%*       Turns off dde initiate callback filtering.  All initiate requests%@NL@%
  13499. %@AB@%*       and registration notifications are passed onto the application.%@NL@%
  13500. %@AB@%*%@NL@%
  13501. %@AB@%* A 0 is returned on error.%@NL@%
  13502. %@AB@%* %@NL@%
  13503. %@AB@%* PUBDOC END%@NL@%
  13504. %@AB@%*%@NL@%
  13505. %@AB@%* History:%@NL@%
  13506. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13507. HDMGDATA EXPENTRY DdeAppNameServer(hszApp, afCmd)%@NL@%
  13508. HSZ hszApp;%@NL@%
  13509. USHORT afCmd;%@NL@%
  13510. {%@NL@%
  13511.     PAPPINFO pai, paiT;%@NL@%
  13512.     BOOL fAgent;%@NL@%
  13513.     HDMGDATA hData;%@NL@%
  13514.     HSZ hsz;%@NL@%
  13515.     %@NL@%
  13516.     if ((pai = GetCurrentAppInfo(TRUE)) == 0)%@NL@%
  13517.         return(FALSE);%@NL@%
  13518. %@NL@%
  13519.     if (afCmd & ANS_FILTERON)%@NL@%
  13520.         pai->afCmd |= DMGCMD_FILTERINITS;%@NL@%
  13521. %@NL@%
  13522.     if (afCmd & ANS_FILTEROFF) %@NL@%
  13523.         pai->afCmd &= ~DMGCMD_FILTERINITS;%@NL@%
  13524. %@NL@%
  13525.     %@NL@%
  13526.     if (afCmd & (ANS_REGISTER | ANS_UNREGISTER)) {%@NL@%
  13527.         %@NL@%
  13528.         if (pai->afCmd & DMGCMD_CLIENTONLY) {%@NL@%
  13529.             pai->LastError = DMGERR_DLL_USAGE;%@NL@%
  13530.             return(FALSE);%@NL@%
  13531.         }%@NL@%
  13532.     %@NL@%
  13533.         fAgent = pai->afCmd & DMGCMD_AGENT ? TRUE : FALSE;%@NL@%
  13534.         %@NL@%
  13535.         if (hszApp == NULL) {%@NL@%
  13536.             if (afCmd & ANS_REGISTER) {%@NL@%
  13537.                 %@AB@%/*%@NL@%
  13538. %@AB@%                 * registering NULL is not allowed!%@NL@%
  13539. %@AB@%                 */%@AE@%%@NL@%
  13540.                 pai->LastError = DMGERR_INVALIDPARAMETER;%@NL@%
  13541.                 return(FALSE);%@NL@%
  13542.             }%@NL@%
  13543.             %@AB@%/*%@NL@%
  13544. %@AB@%             * unregistering NULL is just like unregistering each%@NL@%
  13545. %@AB@%             * registered name.%@NL@%
  13546. %@AB@%             */%@AE@%%@NL@%
  13547.             while (PopPileSubitem(pai->pAppNamePile, (PBYTE)&hsz)) {%@NL@%
  13548.                 for (paiT = pAppInfoList; paiT; paiT = paiT->next) {%@NL@%
  13549.                     if (pai == paiT || (fAgent && (paiT->afCmd & DMGCMD_AGENT))) %@NL@%
  13550.                         continue;%@NL@%
  13551.                     WinPostMsg(paiT->hwndFrame, UM_UNREGISTER, (MPARAM)hsz,%@NL@%
  13552.                             (MPARAM)pai->hwndFrame);%@NL@%
  13553.                 }%@NL@%
  13554.             }%@NL@%
  13555.             return(TRUE);%@NL@%
  13556.         }%@NL@%
  13557.             %@NL@%
  13558.         if (afCmd & ANS_REGISTER) {%@NL@%
  13559.             if (pai->pAppNamePile == NULL) %@NL@%
  13560.                 pai->pAppNamePile = CreatePile(hheapDmg, sizeof(HSZ), 8);%@NL@%
  13561.             AddPileItem(pai->pAppNamePile, (PBYTE)&hszApp, NULL);%@NL@%
  13562.         } else%@NL@%
  13563.             FindPileItem(pai->pAppNamePile, CmpULONG, (PBYTE)&hszApp,%@NL@%
  13564.                     FPI_DELETE);%@NL@%
  13565. %@NL@%
  13566.         for (paiT = pAppInfoList; paiT; paiT = paiT->next) {%@NL@%
  13567.             if (pai == paiT ||%@NL@%
  13568.                     (fAgent && (paiT->afCmd & DMGCMD_AGENT))) {%@NL@%
  13569.                 continue;%@NL@%
  13570.             }%@NL@%
  13571.             WinPostMsg(paiT->hwndFrame,%@NL@%
  13572.                     afCmd & ANS_REGISTER ? UM_REGISTER : UM_UNREGISTER,%@NL@%
  13573.                     (MPARAM)hszApp, (MPARAM)pai->hwndFrame);%@NL@%
  13574.         }%@NL@%
  13575.         return(TRUE);%@NL@%
  13576.     }%@NL@%
  13577. %@NL@%
  13578.     if (afCmd & ANS_QUERYMINE) {%@NL@%
  13579.         hData = PutData(NULL, 10L * sizeof(HSZ),%@NL@%
  13580.                 0L, 0L, 0, HDATA_APPOWNED | HDATA_APPFREEABLE, pai);%@NL@%
  13581.         if (QueryAppNames(pai, hData, hszApp, 0L)) {%@NL@%
  13582.             return(hData);%@NL@%
  13583.         } else {%@NL@%
  13584.             DdeFreeData(hData);%@NL@%
  13585.             return(0L);%@NL@%
  13586.         }%@NL@%
  13587.     }%@NL@%
  13588. %@NL@%
  13589.     if (afCmd & ANS_QUERYALLBUTME) {%@NL@%
  13590.         ULONG offAdd, offAddNew;%@NL@%
  13591.         %@NL@%
  13592.         hData = PutData(NULL, 10L * sizeof(HSZ),%@NL@%
  13593.                 0L, 0L, 0, HDATA_APPOWNED | HDATA_APPFREEABLE, pai);%@NL@%
  13594.         *((PHSZ)DDES_PABDATA((PDDESTRUCT)hData)) = 0L;%@NL@%
  13595.         SemEnter();%@NL@%
  13596.         paiT = pAppInfoList;%@NL@%
  13597.         offAdd = 0L;%@NL@%
  13598.         while (paiT) {%@NL@%
  13599.             if (paiT != pai &&%@NL@%
  13600.                     !(fAgent && (paiT->afCmd & DMGCMD_AGENT))) {%@NL@%
  13601.                 offAddNew = QueryAppNames(paiT, hData, hszApp, offAdd);%@NL@%
  13602.                 if (offAddNew == 0 && offAddNew < offAdd) {%@NL@%
  13603.                     %@AB@%/*%@NL@%
  13604. %@AB@%                     * memory error most likely.%@NL@%
  13605. %@AB@%                     */%@AE@%%@NL@%
  13606.                     SemLeave();%@NL@%
  13607.                     DdeFreeData(hData);%@NL@%
  13608.                     return(0L);%@NL@%
  13609.                 }%@NL@%
  13610.                 offAdd = offAddNew;%@NL@%
  13611.             }%@NL@%
  13612.             paiT = paiT->next;%@NL@%
  13613.         }%@NL@%
  13614.         SemLeave();%@NL@%
  13615.         return(hData);%@NL@%
  13616.     }%@NL@%
  13617. %@NL@%
  13618.     return(0L);%@NL@%
  13619. }%@NL@%
  13620. %@NL@%
  13621. %@NL@%
  13622. %@NL@%
  13623. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13624. %@AB@%* PUBDOC START%@NL@%
  13625. %@AB@%* HDMGDATA EXPENTRY DdeCreateInitPkt(%@NL@%
  13626. %@AB@%* HSZ hszApp,         // initiate app string%@NL@%
  13627. %@AB@%* HSZ hszTopic,       // initiate topic string%@NL@%
  13628. %@AB@%* HDMGDATA hDmgData)  // packet data containing language information.%@NL@%
  13629. %@AB@%*%@NL@%
  13630. %@AB@%* This routine is called by agent applications from within their callback%@NL@%
  13631. %@AB@%* functions which need to store transaction initiate data into a %@NL@%
  13632. %@AB@%* network-portable packet.  On return, HDMGDATA contains the packeted %@NL@%
  13633. %@AB@%* data.  The calling application must free this data handle when %@NL@%
  13634. %@AB@%* through.  Agents are given access to the app string so that they%@NL@%
  13635. %@AB@%* can modify it if needed for their net protocol.%@NL@%
  13636. %@AB@%*%@NL@%
  13637. %@AB@%* PUBDOC END%@NL@%
  13638. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13639. HDMGDATA EXPENTRY DdeCreateInitPkt(hszApp, hszTopic, hDmgData)%@NL@%
  13640. HSZ hszApp;%@NL@%
  13641. HSZ hszTopic;%@NL@%
  13642. HDMGDATA hDmgData;%@NL@%
  13643. {%@NL@%
  13644.     PAPPINFO pai;%@NL@%
  13645. %@NL@%
  13646.     hszApp;%@NL@%
  13647.     hszTopic;%@NL@%
  13648.     hDmgData;%@NL@%
  13649. %@NL@%
  13650.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  13651.         return(0);%@NL@%
  13652.     %@AB@%/*%@NL@%
  13653. %@AB@%     * Add hDataRet to thread list%@NL@%
  13654. %@AB@%     */%@AE@%%@NL@%
  13655.     pai->LastError = DMGERR_NOT_IMPLEMENTED;%@NL@%
  13656. }%@NL@%
  13657. %@NL@%
  13658. %@NL@%
  13659. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13660. %@AB@%* PUBDOC START%@NL@%
  13661. %@AB@%* BOOL EXPENTRY DdeProcessPkt(%@NL@%
  13662. %@AB@%* HDMGDATA hPkt,        // packet from net to process%@NL@%
  13663. %@AB@%* ULONG hAgentFrom);    // foreign agent handle associated with this packet.%@NL@%
  13664. %@AB@%*%@NL@%
  13665. %@AB@%* This routine is called by agent applications which have received a packet%@NL@%
  13666. %@AB@%* from another agent.  This call performs what actions are requested by the%@NL@%
  13667. %@AB@%* hPkt.  If the particular transaction can be done synchronously, a return%@NL@%
  13668. %@AB@%* packet is returned.  If not, an XTYP_RTNPKT callback will eventually be%@NL@%
  13669. %@AB@%* sent to the agent and 0 is returned.  0 is also returned on error.%@NL@%
  13670. %@AB@%*%@NL@%
  13671. %@AB@%* hAgentFrom identifies the agent the packet came from.%@NL@%
  13672. %@AB@%*%@NL@%
  13673. %@AB@%* This call should NOT be made from within a callback.%@NL@%
  13674. %@AB@%*%@NL@%
  13675. %@AB@%* PUBDOC END%@NL@%
  13676. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13677. HDMGDATA EXPENTRY DdeProcessPkt(hPkt, hAgentFrom)%@NL@%
  13678. HDMGDATA hPkt;%@NL@%
  13679. ULONG hAgentFrom;%@NL@%
  13680. {%@NL@%
  13681.     PAPPINFO pai;%@NL@%
  13682. %@NL@%
  13683.     hPkt;%@NL@%
  13684.     hAgentFrom;%@NL@%
  13685.     %@NL@%
  13686.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  13687.         return(0);%@NL@%
  13688.     pai->LastError = DMGERR_NOT_IMPLEMENTED;%@NL@%
  13689. }%@NL@%
  13690. %@NL@%
  13691. %@NL@%
  13692. %@NL@%
  13693. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13694. %@AB@%* PUBDOC START%@NL@%
  13695. %@AB@%* ULONG EXPENTRY DdeQueryVersion()%@NL@%
  13696. %@AB@%*%@NL@%
  13697. %@AB@%* Returns the DLL version number: 0xjjmmuuppL%@NL@%
  13698. %@AB@%* jj = major release;%@NL@%
  13699. %@AB@%* mm = minor release;%@NL@%
  13700. %@AB@%* uu = update number;%@NL@%
  13701. %@AB@%* pp = platform ID; 1=OS/2, 2=DOS, 3=WINDOWS, 4=UNIX, 5=MAC, 6=SUN%@NL@%
  13702. %@AB@%* %@NL@%
  13703. %@AB@%*%@NL@%
  13704. %@AB@%* PUBDOC END%@NL@%
  13705. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13706. ULONG EXPENTRY DdeQueryVersion()%@NL@%
  13707. {%@NL@%
  13708.     return(MAKEULONG(MAKESHORT(1, rup),MAKESHORT(rmm, rmj)));%@NL@%
  13709. }%@NL@%
  13710. %@NL@%
  13711. %@NL@%
  13712. %@NL@%
  13713. %@AB@%/* PUBDOC START%@NL@%
  13714. %@AB@% * ----------------------- Platform specific APIs -----------------------%@NL@%
  13715. %@AB@% * PUBDOC END%@NL@%
  13716. %@AB@% */%@AE@%%@NL@%
  13717. %@NL@%
  13718. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13719. %@AB@%* PUBDOC START%@NL@%
  13720. %@AB@%* HCONV EXPENTRY DdeConverseWithWindow(%@NL@%
  13721. %@AB@%* HWND hwnd,            // server window to converse with%@NL@%
  13722. %@AB@%* HSZ hszApp,           // app name to converse on%@NL@%
  13723. %@AB@%* HSZ hszTopic,         // topic name to converse on%@NL@%
  13724. %@AB@%* PCONVCONTEXT pCC)     // language information to converse on%@NL@%
  13725. %@AB@%* %@NL@%
  13726. %@AB@%* This creates a pre-initiated client conversation with the given hwnd. %@NL@%
  13727. %@AB@%* The conversation is assumed to be on the given app, topic and context.%@NL@%
  13728. %@AB@%* This is useful for implementing such things as drag and drop DDE %@NL@%
  13729. %@AB@%* protocols.  hszApp and hszTopic cannot be NULL.  See%@NL@%
  13730. %@AB@%* DdeCreateServerWindow().%@NL@%
  13731. %@AB@%*  %@NL@%
  13732. %@AB@%* PUBDOC END%@NL@%
  13733. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13734. HCONV EXPENTRY DdeConverseWithWindow(hwnd, hszApp, hszTopic, pCC)%@NL@%
  13735. HWND hwnd;     %@NL@%
  13736. HSZ hszApp, hszTopic;  %@NL@%
  13737. PCONVCONTEXT pCC;%@NL@%
  13738. {%@NL@%
  13739.     PAPPINFO pai;%@NL@%
  13740. %@NL@%
  13741.     UNUSED hwnd;%@NL@%
  13742.     UNUSED hszApp;%@NL@%
  13743.     UNUSED hszTopic;%@NL@%
  13744.     UNUSED pCC;%@NL@%
  13745.     %@NL@%
  13746.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  13747.         return(0);%@NL@%
  13748. %@NL@%
  13749.     if (QuerylatomLength((LATOM)hszApp) == 0 ||%@NL@%
  13750.             QuerylatomLength((LATOM)hszTopic) == 0) {%@NL@%
  13751.         pai->LastError = DMGERR_INVALIDPARAMETER;%@NL@%
  13752.         return(0);%@NL@%
  13753.     }%@NL@%
  13754.     %@NL@%
  13755. }%@NL@%
  13756. %@NL@%
  13757. %@NL@%
  13758. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  13759. %@AB@%* PUBDOC START%@NL@%
  13760. %@AB@%* HWND DdeCreateServerWindow(hszApp, hszTopic, pCC)%@NL@%
  13761. %@AB@%* HSZ hszApp,       // app name to accept conversations on.%@NL@%
  13762. %@AB@%* HSZ hszTopic;     // topic name to accept conversations on.%@NL@%
  13763. %@AB@%* PCONVCONTEXT pCC; // language information to accept or NULL for sys default.%@NL@%
  13764. %@AB@%*    %@NL@%
  13765. %@AB@%* This creates a pre_initiated server DDE window for the caller.  The %@NL@%
  13766. %@AB@%* server window does not know what client window it will be talking to.  As %@NL@%
  13767. %@AB@%* soon as any DDE message is received by the DDE server window, its %@NL@%
  13768. %@AB@%* companion client hwnd is remembered and the conversation is 'locked in'.  %@NL@%
  13769. %@AB@%* The hwnd of the server window is returned.  hszApp and hszTopic cannot %@NL@%
  13770. %@AB@%* be NULL.  %@NL@%
  13771. %@AB@%*    %@NL@%
  13772. %@AB@%* Typically, the server app would call CreateServerWindow() and pass the %@NL@%
  13773. %@AB@%* hwnd to some prospective client via some other transport mechanism.  The %@NL@%
  13774. %@AB@%* client would then call ConverseWithWindow() with the hwnd it received %@NL@%
  13775. %@AB@%* from the server and then begin DDE transactions using the HCONV returned.  %@NL@%
  13776. %@AB@%*    %@NL@%
  13777. %@AB@%* A server may pass this hwnd to many potential clients.  Only the first %@NL@%
  13778. %@AB@%* one that responds would get 'locked in'.  The rest would be out of luck %@NL@%
  13779. %@AB@%* and their API calls would fail.  The server window ignores messages that%@NL@%
  13780. %@AB@%* to not fit the app and topic given.%@NL@%
  13781. %@AB@%*  %@NL@%
  13782. %@AB@%* PUBDOC END%@NL@%
  13783. %@AB@%\****************************************************************************/%@AE@%%@NL@%
  13784. HWND EXPENTRY DdeCreateServerWindow(hszApp, hszTopic, pCC)%@NL@%
  13785. HSZ hszApp, hszTopic;%@NL@%
  13786. PCONVCONTEXT pCC;%@NL@%
  13787. {%@NL@%
  13788.     PAPPINFO pai;%@NL@%
  13789.     INITINFO ii;%@NL@%
  13790.     HWND hwndServer;%@NL@%
  13791.     %@NL@%
  13792.     hszApp;%@NL@%
  13793.     hszTopic;%@NL@%
  13794.     pCC;%@NL@%
  13795.     %@NL@%
  13796.     if ((pai = GetCurrentAppInfo(TRUE)) == NULL)%@NL@%
  13797.         return(0);%@NL@%
  13798.         %@NL@%
  13799.     if (QuerylatomLength((LATOM)hszApp) == 0 ||%@NL@%
  13800.             QuerylatomLength((LATOM)hszTopic) == 0) {%@NL@%
  13801.         pai->LastError = DMGERR_INVALIDPARAMETER;%@NL@%
  13802.         return(0);%@NL@%
  13803.     }%@NL@%
  13804.     %@NL@%
  13805.     if ((hwndServer = CreateServerWindow(pai, hszTopic)) == NULL)%@NL@%
  13806.         return(0);%@NL@%
  13807. %@NL@%
  13808.     ii.hszAppName = hszApp;%@NL@%
  13809.     ii.hszTopic = hszTopic;%@NL@%
  13810.     ii.hwndSend =%@NL@%
  13811.     ii.hwndFrame = NULL;%@NL@%
  13812.     ii.pCC = pCC;%@NL@%
  13813.     WinSendMsg(hwndServer, UMSR_INITIATE, 0L, 0L);%@NL@%
  13814. }%@NL@%
  13815. %@NL@%
  13816. %@NL@%
  13817. %@2@%%@AH@%DDESPY.C%@AE@%%@EH@%%@NL@%
  13818. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DDESPY\DDESPY.C%@AE@%%@NL@%
  13819. %@NL@%
  13820. %@AB@%/***************************** Module Header ******************************\%@NL@%
  13821. %@AB@%* Module Name: ddespy%@NL@%
  13822. %@AB@%*%@NL@%
  13823. %@AB@%* This is a small DDE ddespyr which lets me see whats going on.%@NL@%
  13824. %@AB@%*%@NL@%
  13825. %@AB@%* Created:      sanfords%@NL@%
  13826. %@AB@%*%@NL@%
  13827. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  13828. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  13829. %@AI@%#include %@AE@%"ddespy.h" %@NL@%
  13830. %@NL@%
  13831. %@AB@%/*********** declares *********/%@AE@%%@NL@%
  13832. %@NL@%
  13833. HWND hwndExec = NULL;%@NL@%
  13834. %@NL@%
  13835. SWP gswp[IW_LAST - IW_FIRST + 1];%@NL@%
  13836. PSZ apszTitles[] = {%@NL@%
  13837.         "Applications", "Topics", "System Items", "Data"%@NL@%
  13838.                    };%@NL@%
  13839. %@NL@%
  13840. %@NL@%
  13841. PSZ apszType[] = {%@NL@%
  13842.                         "0-Type"        ,%@NL@%
  13843.                         "ACK"           ,%@NL@%
  13844.                         "ADVDATA"       ,   %@NL@%
  13845.                         "ADVREQ"        ,    %@NL@%
  13846.                         "ADVSTART"      ,  %@NL@%
  13847.                         "ADVSTOP"       ,   %@NL@%
  13848.                         "EXEC"          ,      %@NL@%
  13849.                         "INIT"          ,%@NL@%
  13850.                         "INITCONF"      ,%@NL@%
  13851.                         "MONITOR"       ,%@NL@%
  13852.                         "PKT"           ,%@NL@%
  13853.                         "POKE"          ,%@NL@%
  13854.                         "REGISTER"      ,  %@NL@%
  13855.                         "REQUEST"       ,%@NL@%
  13856.                         "RTNPKT"        ,%@NL@%
  13857.                         "TERM"          ,      %@NL@%
  13858.                         "UNREGISTER"    ,%@NL@%
  13859.                         "WILDINIT"      ,%@NL@%
  13860.                         "XFERCOMP"      ,%@NL@%
  13861.                         "19"            ,%@NL@%
  13862.                         "20"            ,%@NL@%
  13863.                         "21"            ,%@NL@%
  13864.                         "22"            ,%@NL@%
  13865.                         "23"            ,%@NL@%
  13866.                         "24"            ,%@NL@%
  13867.                         "25"            ,%@NL@%
  13868.                         "26"            ,%@NL@%
  13869.                         "27"            ,%@NL@%
  13870.                         "28"            ,%@NL@%
  13871.                         "29"            ,%@NL@%
  13872.                         "30"            ,%@NL@%
  13873.                         "31"            ,%@NL@%
  13874.                };%@NL@%
  13875. %@NL@%
  13876. PSZ apszState[] = {         %@AB@%/* corresponds to convinfo.usStatus */%@AE@%%@NL@%
  13877.                         "DISCONNECTED"      ,%@NL@%
  13878.                         "CONNECTED"         ,%@NL@%
  13879.                         "NOADVISE"          ,%@NL@%
  13880.                         "ADVISE"            ,%@NL@%
  13881.                   };%@NL@%
  13882. %@NL@%
  13883. PSZ apszStatus[] = {        %@AB@%/* corresponds to convionfi.usConvst */%@AE@%%@NL@%
  13884.                         "NOACTIVITY"    ,     %@NL@%
  13885.                         "INCOMPLETE"    ,    %@NL@%
  13886.                         "TERMINATED"    ,    %@NL@%
  13887.                         "CONNECTED"     ,%@NL@%
  13888.                         "INITIATING"    ,         %@NL@%
  13889.                         "REQSENT"       ,       %@NL@%
  13890.                         "DATARCVD"      ,      %@NL@%
  13891.                         "POKESENT"      ,      %@NL@%
  13892.                         "POKEACKRCVD"   ,   %@NL@%
  13893.                         "EXECSENT"      ,      %@NL@%
  13894.                         "EXECACKRCVD"   ,   %@NL@%
  13895.                         "ADVSENT"       ,       %@NL@%
  13896.                         "UNADVSENT"     ,     %@NL@%
  13897.                         "ADVACKRCVD"    ,    %@NL@%
  13898.                         "UNADVACKRCVD"  ,  %@NL@%
  13899.                         "ADVDATASENT"   ,   %@NL@%
  13900.                         "ADVDATAACKRCVD",%@NL@%
  13901.                    };%@NL@%
  13902. %@NL@%
  13903. %@NL@%
  13904. %@AI@%#define %@AE@%GetLBCount(hw) (SHORT)WinSendMsg((hw), LM_QUERYITEMCOUNT, 0L, 0L) %@NL@%
  13905. %@AI@%#define %@AE@%GetLBSelectedItem(hw) \ %@NL@%
  13906.             (SHORT)WinSendMsg((hw), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, 0L)%@NL@%
  13907. %@AI@%#define %@AE@%GetLBItemHandle(hw, i) \ %@NL@%
  13908.             (ULONG)WinSendMsg((hw), LM_QUERYITEMHANDLE, (MPARAM)(i), 0L)%@NL@%
  13909. %@AI@%#define %@AE@%GetLBItemText(hw, i, cch, psz) \ %@NL@%
  13910.             (ULONG)WinSendMsg((hw), LM_QUERYITEMTEXT, MPFROM2SHORT((i),(cch)), (MPARAM)(psz))%@NL@%
  13911. %@AI@%#define %@AE@%DeleteLBItem(hw, i) WinSendMsg(hw, LM_DELETEITEM, MPFROMSHORT(i), 0L) %@NL@%
  13912. %@AI@%#define %@AE@%NotifyOwner(hwnd, msg, mp1, mp2) \ %@NL@%
  13913.             (WinSendMsg(WinQueryWindow(hwnd, QW_OWNER, FALSE), msg, mp1, mp2))%@NL@%
  13914. %@NL@%
  13915. %@NL@%
  13916. void cdecl main(int argc, char **argv);%@NL@%
  13917. void ResizeChildren(USHORT cxNew, USHORT cyNew);%@NL@%
  13918. HDMGDATA EXPENTRY dataxfer(HCONV hConv, HSZ hszTopic, HSZ hszItem,%@NL@%
  13919.         USHORT usFmt, USHORT usType, HDMGDATA hDmgData);%@NL@%
  13920. MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);%@NL@%
  13921. MRESULT EXPENTRY GetTimeoutDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);%@NL@%
  13922. MRESULT EXPENTRY EnhancedEFWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);%@NL@%
  13923. MRESULT EXPENTRY ExecDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);%@NL@%
  13924. void Refresh(void);%@NL@%
  13925. SHORT InsertLBItem(HWND hwndLB, PSZ psz, ULONG ulHandle);%@NL@%
  13926. void SetLBEntries(HCONV hConv, HSZ hszItem, USHORT iwlb);%@NL@%
  13927. void UpdateQueue(HWND hwndCB, HCONV hConv);%@NL@%
  13928. void ConvInfoToString(PCONVINFO pci, PSZ psz, USHORT cbMax);%@NL@%
  13929. PSZ mylstrcat(PSZ psz1, PSZ psz2, PSZ pszLast);%@NL@%
  13930. int lstrlen(PSZ psz);%@NL@%
  13931. %@NL@%
  13932. %@AB@%/************* GLOBAL VARIABLES  ************/%@AE@%%@NL@%
  13933. %@NL@%
  13934. HAB hab;%@NL@%
  13935. HMQ hmq;%@NL@%
  13936. HHEAP hheap;%@NL@%
  13937. HWND hwndFrame;%@NL@%
  13938. HWND hwndClient;%@NL@%
  13939. USHORT cyTitles;%@NL@%
  13940. USHORT cxBorder;%@NL@%
  13941. HCONVLIST hConvListMain;%@NL@%
  13942. HSZ hszSysTopic;%@NL@%
  13943. HSZ hszSysItemTopics;%@NL@%
  13944. HSZ hszSysItemSysItems;%@NL@%
  13945. ULONG gTimeout = 1000L;%@NL@%
  13946. PFNWP lpfnSysEFWndProc;%@NL@%
  13947. %@NL@%
  13948. void cdecl main(argc, argv)%@NL@%
  13949. int argc;%@NL@%
  13950. char **argv;%@NL@%
  13951. {%@NL@%
  13952.     USHORT err;%@NL@%
  13953.     QMSG qmsg;%@NL@%
  13954. %@NL@%
  13955.     argc; argv;%@NL@%
  13956.     %@NL@%
  13957.     hab = WinInitialize(0);%@NL@%
  13958.     hmq = WinCreateMsgQueue(hab, 0);%@NL@%
  13959.     hheap = WinCreateHeap(0, 0, 0, 0, 0, HM_MOVEABLE);%@NL@%
  13960. %@NL@%
  13961.     if (!WinRegisterClass(hab, "DDESpyr Class", ClientWndProc, CS_SIZEREDRAW, 0))%@NL@%
  13962.         goto abort;%@NL@%
  13963. %@NL@%
  13964.     cyTitles = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);%@NL@%
  13965.     cxBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);%@NL@%
  13966. %@NL@%
  13967.     hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, NULL,%@NL@%
  13968.             (PSZ)"DDESpyr Class",%@NL@%
  13969.             (PSZ)"", WS_VISIBLE, (HMODULE)NULL, IDR_MAIN,%@NL@%
  13970.             &hwndClient);%@NL@%
  13971. %@NL@%
  13972.     WinSetWindowText(hwndFrame, "DDE Spy");%@NL@%
  13973.     if (err = DdeInitialize((PFNCALLBACK)dataxfer, 0L, 0L)) {%@NL@%
  13974.         DdePostError(err);%@NL@%
  13975.         goto abort;%@NL@%
  13976.     }%@NL@%
  13977. %@NL@%
  13978.     hszSysTopic = DdeGetHsz((PSZ)SZDDESYS_TOPIC, 0, 0);%@NL@%
  13979.     hszSysItemTopics = DdeGetHsz((PSZ)SZDDESYS_ITEM_TOPICS, 0, 0);%@NL@%
  13980.     hszSysItemSysItems = DdeGetHsz((PSZ)SZDDESYS_ITEM_SYSITEMS, 0, 0);%@NL@%
  13981. %@NL@%
  13982.     Refresh();%@NL@%
  13983. %@NL@%
  13984.     while (WinGetMsg(hab, &qmsg, 0, 0, 0)) {%@NL@%
  13985.         WinDispatchMsg(hab, &qmsg);%@NL@%
  13986.     }%@NL@%
  13987. %@NL@%
  13988.     DdeUninitialize();%@NL@%
  13989. abort:%@NL@%
  13990.     if (hwndFrame)%@NL@%
  13991.         WinDestroyWindow(hwndFrame);%@NL@%
  13992.     if (hheap) {%@NL@%
  13993.         WinDestroyHeap(hheap);%@NL@%
  13994.     }%@NL@%
  13995.     WinTerminate(hab);%@NL@%
  13996.     DosExit(TRUE, 0);%@NL@%
  13997. }%@NL@%
  13998. %@NL@%
  13999. %@NL@%
  14000. MRESULT EXPENTRY ClientWndProc(hwnd, msg, mp1, mp2)%@NL@%
  14001. HWND hwnd;%@NL@%
  14002. USHORT msg;%@NL@%
  14003. MPARAM mp1, mp2;%@NL@%
  14004. {%@NL@%
  14005.     USHORT i;%@NL@%
  14006. %@NL@%
  14007.     switch (msg) {%@NL@%
  14008.     case WM_CREATE:%@NL@%
  14009.         %@AB@%/*%@NL@%
  14010. %@AB@%         * initialize globals%@NL@%
  14011. %@AB@%         */%@AE@%%@NL@%
  14012.         hwndClient = hwnd;%@NL@%
  14013.         for (i = IW_APPSLBOX; i <= IW_ITEMSLBOX; i++) {%@NL@%
  14014.             gswp[i].hwnd = WinCreateWindow(hwndClient, WC_LISTBOX, "",%@NL@%
  14015.                     WS_VISIBLE | LS_NOADJUSTPOS, 0, 0, 0, 0, hwndClient,%@NL@%
  14016.                     HWND_TOP, i, NULL, NULL);%@NL@%
  14017.         }%@NL@%
  14018.         for (i = IW_APPSTITLE; i <= IW_DATATITLE; i++) {%@NL@%
  14019.             gswp[i].hwnd = WinCreateWindow(hwndClient, WC_STATIC,%@NL@%
  14020.                     apszTitles[i - IW_APPSTITLE],%@NL@%
  14021.                     WS_VISIBLE | SS_TEXT | DT_CENTER | DT_BOTTOM,%@NL@%
  14022.                     0, 0, 0, 0, hwndClient,%@NL@%
  14023.                     HWND_TOP, i, NULL, NULL);%@NL@%
  14024.         }%@NL@%
  14025.         gswp[IW_DATATEXT].hwnd = WinCreateWindow(hwndClient, WC_STATIC, "",%@NL@%
  14026.                 WS_VISIBLE | SS_TEXT | DT_WORDBREAK,%@NL@%
  14027.                 0, 0, 0, 0, hwndClient,%@NL@%
  14028.                 HWND_TOP, i, NULL, NULL);%@NL@%
  14029. %@NL@%
  14030.         break;%@NL@%
  14031. %@NL@%
  14032.     case WM_COMMAND:%@NL@%
  14033.         switch (LOUSHORT(mp1)) {%@NL@%
  14034.         case IDM_REFRESH:%@NL@%
  14035.             Refresh();%@NL@%
  14036.             break;%@NL@%
  14037. %@NL@%
  14038.         case IDM_SETTIMEOUT:%@NL@%
  14039.             gTimeout = (USHORT)WinDlgBox(hwndFrame, NULL,%@NL@%
  14040.                     (PFNWP)GetTimeoutDlgProc,%@NL@%
  14041.                     (HMODULE)NULL, IDD_GETTIMEOUT, NULL);%@NL@%
  14042.             break;%@NL@%
  14043. %@NL@%
  14044.         case IDM_EXEC:%@NL@%
  14045.             WinDlgBox(HWND_DESKTOP, hwnd, ExecDlgProc, NULL, IDD_EXEC, NULL);%@NL@%
  14046.             break;%@NL@%
  14047.         }%@NL@%
  14048.         break;%@NL@%
  14049. %@NL@%
  14050.     case WM_CONTROL:%@NL@%
  14051.         switch (LOUSHORT(mp1)) {%@NL@%
  14052.         case IW_APPSLBOX:%@NL@%
  14053.             switch (HIUSHORT(mp1)) {%@NL@%
  14054.             case LN_SELECT:%@NL@%
  14055.                 hwnd = gswp[IW_APPSLBOX].hwnd;%@NL@%
  14056.                 SetLBEntries((HCONV)GetLBItemHandle(hwnd,%@NL@%
  14057.                         GetLBSelectedItem(hwnd)),%@NL@%
  14058.                         hszSysItemTopics, IW_TOPICSLBOX);%@NL@%
  14059.                 SetLBEntries((HCONV)GetLBItemHandle(hwnd,%@NL@%
  14060.                         GetLBSelectedItem(hwnd)),%@NL@%
  14061.                         hszSysItemSysItems, IW_ITEMSLBOX);%@NL@%
  14062.                 break;%@NL@%
  14063.             }%@NL@%
  14064.             break;%@NL@%
  14065. %@NL@%
  14066.         case IW_TOPICSLBOX:%@NL@%
  14067.             break;%@NL@%
  14068. %@NL@%
  14069.         case IW_ITEMSLBOX:%@NL@%
  14070.             break;%@NL@%
  14071. %@NL@%
  14072.         default:%@NL@%
  14073.             goto DoDefAction;%@NL@%
  14074.         }%@NL@%
  14075.         break;%@NL@%
  14076. %@NL@%
  14077.     case WM_SIZE:%@NL@%
  14078.         %@AB@%/*%@NL@%
  14079. %@AB@%         * resize children%@NL@%
  14080. %@AB@%         */%@AE@%%@NL@%
  14081.         ResizeChildren(SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));%@NL@%
  14082.         break;%@NL@%
  14083. %@NL@%
  14084.     case WM_ERASEBACKGROUND:%@NL@%
  14085.         return(TRUE);%@NL@%
  14086.         break;%@NL@%
  14087. %@NL@%
  14088.     default:%@NL@%
  14089. DoDefAction:%@NL@%
  14090.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  14091.     }%@NL@%
  14092.     return(0L);%@NL@%
  14093. }%@NL@%
  14094. %@NL@%
  14095. %@NL@%
  14096. %@NL@%
  14097. void ResizeChildren(cxNew, cyNew)%@NL@%
  14098. USHORT cxNew, cyNew;%@NL@%
  14099. {%@NL@%
  14100.     USHORT i;%@NL@%
  14101. %@NL@%
  14102.     for (i = IW_FIRST; i <= IW_LAST; i++) {%@NL@%
  14103.         gswp[i].fs = SWP_SIZE | SWP_MOVE | SWP_SHOW;%@NL@%
  14104.         gswp[i].hwndInsertBehind = HWND_TOP;%@NL@%
  14105.     }%@NL@%
  14106. %@NL@%
  14107.     for (i = IW_APPSTITLE; i <= IW_ITEMSTITLE; i++) {%@NL@%
  14108.         gswp[i].x =%@NL@%
  14109.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].x = i == IW_APPSTITLE ? -cxBorder :%@NL@%
  14110.                 gswp[i - 1].x + gswp[i - 1].cx - cxBorder;%@NL@%
  14111. %@NL@%
  14112.         gswp[i].y = cyNew - cyTitles;%@NL@%
  14113.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].y = cyNew / 2;%@NL@%
  14114. %@NL@%
  14115.         gswp[i].cx =%@NL@%
  14116.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].cx = cxNew / 3;%@NL@%
  14117. %@NL@%
  14118.         gswp[i].cy = cyTitles;%@NL@%
  14119.         gswp[i - IW_APPSTITLE + IW_APPSLBOX].cy = (cyNew / 2) - cyTitles;%@NL@%
  14120.     }%@NL@%
  14121. %@NL@%
  14122.     gswp[IW_ITEMSLBOX].cx = cxNew - gswp[IW_ITEMSLBOX].x + cxBorder;%@NL@%
  14123. %@NL@%
  14124.     gswp[IW_DATATITLE].cy = cyTitles;%@NL@%
  14125.     gswp[IW_DATATITLE].y =%@NL@%
  14126.     gswp[IW_DATATEXT].cy = cyNew / 2 - cyTitles;%@NL@%
  14127. %@NL@%
  14128.     gswp[IW_DATATITLE].cx =%@NL@%
  14129.     gswp[IW_DATATEXT].cx = cxNew;%@NL@%
  14130. %@NL@%
  14131.     WinSetMultWindowPos(hab, gswp, IW_DATATEXT - IW_APPSTITLE + 1);%@NL@%
  14132. }%@NL@%
  14133. %@NL@%
  14134. %@NL@%
  14135. void Refresh()%@NL@%
  14136. {%@NL@%
  14137.     HCONV hConv;%@NL@%
  14138.     register NPSZ npszAppName;%@NL@%
  14139.     CONVINFO ci;%@NL@%
  14140.     USHORT cb;%@NL@%
  14141. %@NL@%
  14142.     WinLockWindowUpdate(HWND_DESKTOP, gswp[IW_APPSLBOX].hwnd);%@NL@%
  14143.     WinSendMsg(gswp[IW_APPSLBOX].hwnd, LM_DELETEALL, 0L, 0L);%@NL@%
  14144.     WinSendMsg(gswp[IW_TOPICSLBOX].hwnd, LM_DELETEALL, 0L, 0L);%@NL@%
  14145.     WinSendMsg(gswp[IW_ITEMSLBOX].hwnd, LM_DELETEALL, 0L, 0L);%@NL@%
  14146.     %@NL@%
  14147.     hConvListMain = DdeBeginEnumServers(0L, hszSysTopic, hConvListMain, NULL, NULL);%@NL@%
  14148.     if (hConvListMain) {%@NL@%
  14149.         hConv = 0;%@NL@%
  14150.         while (hConv = DdeGetNextServer(hConvListMain, hConv)) {%@NL@%
  14151.             DdeQueryConvInfo(hConv, &ci, QID_SYNC);%@NL@%
  14152.             if (ci.hszAppPartner != 0) {%@NL@%
  14153.                 cb = DdeGetHszString(ci.hszAppPartner, NULL, 0L) + 1;%@NL@%
  14154.                 npszAppName = WinAllocMem(hheap, cb);%@NL@%
  14155.                 DdeGetHszString(ci.hszAppPartner, (PSZ)npszAppName, (ULONG)cb);%@NL@%
  14156.                 InsertLBItem(gswp[IW_APPSLBOX].hwnd, (PSZ)npszAppName,%@NL@%
  14157.                         (ULONG)hConv);%@NL@%
  14158.                 WinFreeMem(hheap, npszAppName, cb);%@NL@%
  14159.             } else {%@NL@%
  14160.                 InsertLBItem(gswp[IW_APPSLBOX].hwnd, SZINDETERMINATE,%@NL@%
  14161.                         (ULONG)hConv);%@NL@%
  14162.             }%@NL@%
  14163.         }%@NL@%
  14164.     }%@NL@%
  14165.     WinLockWindowUpdate(HWND_DESKTOP, NULL);%@NL@%
  14166. }%@NL@%
  14167. %@NL@%
  14168. %@NL@%
  14169. SHORT InsertLBItem(hwndLB, psz, ulHandle)%@NL@%
  14170. HWND hwndLB;%@NL@%
  14171. PSZ psz;%@NL@%
  14172. ULONG ulHandle;%@NL@%
  14173. {%@NL@%
  14174.     SHORT ili;%@NL@%
  14175. %@NL@%
  14176.     ili = (SHORT)WinSendMsg(hwndLB, LM_INSERTITEM, (MPARAM)LIT_SORTASCENDING,%@NL@%
  14177.             (MPARAM)psz);%@NL@%
  14178.     WinSendMsg(hwndLB, LM_SETITEMHANDLE, MPFROMSHORT(ili), (MPARAM)ulHandle);%@NL@%
  14179.     return(ili);%@NL@%
  14180. }%@NL@%
  14181. %@NL@%
  14182. %@NL@%
  14183. void SetLBEntries(hConv, hszItem, iwlb)%@NL@%
  14184. HCONV hConv;%@NL@%
  14185. HSZ hszItem;%@NL@%
  14186. USHORT iwlb;%@NL@%
  14187. {%@NL@%
  14188.     NPSZ npsz, npszT1, npszT2;%@NL@%
  14189.     BOOL fDone = 0;%@NL@%
  14190.     ULONG cb;%@NL@%
  14191.     HDMGDATA hDmgData;%@NL@%
  14192. %@NL@%
  14193.     hDmgData = DdeClientXfer(0L, 0L, hConv, hszItem, DDEFMT_TEXT,%@NL@%
  14194.         XTYP_REQUEST, gTimeout, NULL);%@NL@%
  14195. %@NL@%
  14196.     if (hDmgData == 0) {%@NL@%
  14197.         DdePostError(DdeGetLastError());%@NL@%
  14198.         return;%@NL@%
  14199.     }%@NL@%
  14200. %@NL@%
  14201.     cb = DdeGetData(hDmgData, NULL, 0L, 0L);%@NL@%
  14202.     %@AB@%/*%@NL@%
  14203. %@AB@%     * BUG - may later want to handle the case for cb > 0xFFFF%@NL@%
  14204. %@AB@%     */%@AE@%%@NL@%
  14205.     npsz = WinAllocMem(hheap, (USHORT)cb);%@NL@%
  14206.     if (npsz == NULL) {%@NL@%
  14207.         DdePostError(DMGERR_MEMORY_ERROR);%@NL@%
  14208.         return;%@NL@%
  14209.     }%@NL@%
  14210.     if (DdeGetData(hDmgData, (PBYTE)npsz, cb, 0L) == 0) {%@NL@%
  14211.         DdePostError(DdeGetLastError());%@NL@%
  14212.         goto Exit;%@NL@%
  14213.     }%@NL@%
  14214.     npszT1 = npszT2 = npsz;%@NL@%
  14215.     WinLockWindowUpdate(HWND_DESKTOP, gswp[iwlb].hwnd);%@NL@%
  14216.     WinSendMsg(gswp[iwlb].hwnd, LM_DELETEALL, 0L, 0L);%@NL@%
  14217.     while (!fDone) {%@NL@%
  14218.         while (*npszT2 != '\t' && *npszT2 != '\0')%@NL@%
  14219.             npszT2++;%@NL@%
  14220.         if (*npszT2 == '\t') {%@NL@%
  14221.             *npszT2 = '\0';%@NL@%
  14222.             npszT2++;%@NL@%
  14223.         } else%@NL@%
  14224.             fDone = TRUE;%@NL@%
  14225.         InsertLBItem(gswp[iwlb].hwnd, (PSZ)npszT1,%@NL@%
  14226.                 (ULONG)DdeGetHsz(npszT1, 0, 0));%@NL@%
  14227.         npszT1 = npszT2;%@NL@%
  14228.     }%@NL@%
  14229.     WinLockWindowUpdate(HWND_DESKTOP, NULL);%@NL@%
  14230. %@NL@%
  14231. Exit:%@NL@%
  14232.     WinFreeMem(hheap, (NPBYTE)npsz, (USHORT)cb);%@NL@%
  14233.     return;%@NL@%
  14234. }%@NL@%
  14235. %@NL@%
  14236. %@NL@%
  14237. %@NL@%
  14238. HDMGDATA EXPENTRY dataxfer(hConv, hszTopic, hszItem, usFmt, usType,%@NL@%
  14239.         hDmgData)%@NL@%
  14240. HCONV hConv;%@NL@%
  14241. HSZ hszTopic;%@NL@%
  14242. HSZ hszItem;%@NL@%
  14243. USHORT usFmt;%@NL@%
  14244. USHORT usType;%@NL@%
  14245. HDMGDATA hDmgData;%@NL@%
  14246. {%@NL@%
  14247.     hConv; hszTopic; hszItem; usFmt; usType; hDmgData;%@NL@%
  14248. %@NL@%
  14249.     switch (usType) {%@NL@%
  14250.     case XTYP_XFERCOMPLETE:%@NL@%
  14251.         if (hwndExec) {%@NL@%
  14252.             if (DdeCheckQueue(hConv, &hDmgData, (ULONG)hDmgData, 0L)) {%@NL@%
  14253.                 PSZ psz;%@NL@%
  14254.                 if (psz = (PSZ)DdeAccessData(hDmgData)) {%@NL@%
  14255.                     WinSetDlgItemText(hwndExec, IDEF_DATA, psz);%@NL@%
  14256.                     %@AB@%/*%@NL@%
  14257. %@AB@%                     * Free this data here.%@NL@%
  14258. %@AB@%                     */%@AE@%%@NL@%
  14259.                     DdeFreeData(hDmgData);%@NL@%
  14260.                 }%@NL@%
  14261.             }%@NL@%
  14262.         }%@NL@%
  14263.         break;%@NL@%
  14264.     }%@NL@%
  14265.     return(0);%@NL@%
  14266. }%@NL@%
  14267. %@NL@%
  14268. %@NL@%
  14269. MRESULT EXPENTRY GetTimeoutDlgProc(hwnd, msg, mp1, mp2)%@NL@%
  14270. HWND hwnd;%@NL@%
  14271. USHORT msg;%@NL@%
  14272. MPARAM mp1;%@NL@%
  14273. MPARAM mp2;%@NL@%
  14274. {%@NL@%
  14275.     USHORT usValue;%@NL@%
  14276. %@NL@%
  14277.     switch (msg) {%@NL@%
  14278.     case WM_INITDLG: %@NL@%
  14279.         %@AB@%/*%@NL@%
  14280. %@AB@%         * set up our entryfield to be enhanced.%@NL@%
  14281. %@AB@%         */%@AE@%%@NL@%
  14282.         WinSetDlgItemShort(hwnd, IDC_EF, (USHORT)gTimeout, FALSE);%@NL@%
  14283.         lpfnSysEFWndProc = WinSubclassWindow(WinWindowFromID(hwnd, IDC_EF),%@NL@%
  14284.                 EnhancedEFWndProc);%@NL@%
  14285.         break;%@NL@%
  14286. %@NL@%
  14287.     case ENHAN_ENTER:%@NL@%
  14288.         %@AB@%/*%@NL@%
  14289. %@AB@%         * when the user hits the enter key, it will be passed from the%@NL@%
  14290. %@AB@%         * entryfield to here and we will use it as a signal to exit.%@NL@%
  14291. %@AB@%         */%@AE@%%@NL@%
  14292.         WinQueryDlgItemShort(hwnd, IDC_EF, &usValue, FALSE);%@NL@%
  14293.         WinDismissDlg(hwnd, usValue);%@NL@%
  14294.         break;%@NL@%
  14295. %@NL@%
  14296.     default:%@NL@%
  14297.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  14298.         break;%@NL@%
  14299.     }%@NL@%
  14300.     return(0);%@NL@%
  14301. }%@NL@%
  14302. %@NL@%
  14303. MRESULT EXPENTRY EnhancedEFWndProc(hwnd, msg, mp1, mp2)%@NL@%
  14304. HWND hwnd;%@NL@%
  14305. USHORT msg;%@NL@%
  14306. MPARAM mp1;%@NL@%
  14307. MPARAM mp2;%@NL@%
  14308. {%@NL@%
  14309.     switch (msg) {%@NL@%
  14310.     case WM_CHAR:%@NL@%
  14311.         if (LOUSHORT(mp1) & KC_SCANCODE &&%@NL@%
  14312.                 LOUSHORT(mp1) & KC_KEYUP &&%@NL@%
  14313.                 %@AB@%/*---HACK ALERT!---*/%@AE@%%@NL@%
  14314.                 LOBYTE(LOUSHORT(mp2)) == 0x0d) {%@NL@%
  14315.             NotifyOwner(hwnd, ENHAN_ENTER,%@NL@%
  14316.                     (MPARAM)WinQueryWindowUShort(hwnd, QWS_ID), 0L);%@NL@%
  14317.         }%@NL@%
  14318.         break;%@NL@%
  14319.     }%@NL@%
  14320.     return(lpfnSysEFWndProc(hwnd, msg, mp1, mp2));%@NL@%
  14321. }%@NL@%
  14322. %@NL@%
  14323. %@NL@%
  14324. %@NL@%
  14325. MRESULT EXPENTRY ExecDlgProc(hwnd, msg, mp1, mp2)%@NL@%
  14326. HWND hwnd;%@NL@%
  14327. USHORT msg;%@NL@%
  14328. MPARAM mp1;%@NL@%
  14329. MPARAM mp2;%@NL@%
  14330. {%@NL@%
  14331.     static UCHAR szT[255];%@NL@%
  14332.     static HCONV hConv = NULL;%@NL@%
  14333.     register USHORT i;%@NL@%
  14334.     USHORT cb;%@NL@%
  14335.     register USHORT xtyp;%@NL@%
  14336.     HDMGDATA hDmgData;%@NL@%
  14337.     HSZ hszApp, hszItem, hszTopic;%@NL@%
  14338.     BOOL fAssync;%@NL@%
  14339.     ULONG xid;%@NL@%
  14340. %@NL@%
  14341.     switch (msg) {%@NL@%
  14342.     case WM_INITDLG:%@NL@%
  14343.         hwndExec = hwnd;%@NL@%
  14344.         WinSendDlgItemMsg(hwnd, IDEF_DATA, EM_SETTEXTLIMIT, (MPARAM)MAX_QSTRING, 0L);%@NL@%
  14345.         WinSendDlgItemMsg(hwnd, IDCB_QDATA, EM_SETTEXTLIMIT, (MPARAM)MAX_QSTRING, 0L);%@NL@%
  14346.         if ((i = GetLBSelectedItem(gswp[IW_APPSLBOX].hwnd)) != LIT_NONE) {%@NL@%
  14347.             GetLBItemText(gswp[IW_APPSLBOX].hwnd, i, 255, szT);%@NL@%
  14348.             WinSetDlgItemText(hwnd, IDEF_APP, szT);%@NL@%
  14349.         }%@NL@%
  14350.         if ((i = GetLBSelectedItem(gswp[IW_TOPICSLBOX].hwnd)) != LIT_NONE) {%@NL@%
  14351.             GetLBItemText(gswp[IW_TOPICSLBOX].hwnd, i, 255, szT);%@NL@%
  14352.             WinSetDlgItemText(hwnd, IDEF_TOPIC, szT);%@NL@%
  14353.         }%@NL@%
  14354.         if ((i = GetLBSelectedItem(gswp[IW_ITEMSLBOX].hwnd)) != LIT_NONE) {%@NL@%
  14355.             GetLBItemText(gswp[IW_ITEMSLBOX].hwnd, i, 255, szT);%@NL@%
  14356.             WinSetDlgItemText(hwnd, IDEF_ITEM, szT);%@NL@%
  14357.         }%@NL@%
  14358.         WinSendDlgItemMsg(hwnd, IDRB_REQUEST, BM_CLICK, 0L, 0L);%@NL@%
  14359.         break;%@NL@%
  14360. %@NL@%
  14361.     case WM_CONTROL:%@NL@%
  14362.     case WM_COMMAND:%@NL@%
  14363.         switch (LOUSHORT(mp1)) {%@NL@%
  14364.         case MBID_CANCEL:%@NL@%
  14365.             if (hConv != NULL)%@NL@%
  14366.                 DdeDisconnect(hConv);%@NL@%
  14367.             hConv = NULL;%@NL@%
  14368.             WinDismissDlg(hwnd, 0);%@NL@%
  14369.             break;%@NL@%
  14370.             %@NL@%
  14371.         case IDC_QFLUSH:%@NL@%
  14372.             DdeCheckQueue(hConv, NULL, QID_NEWEST, CQ_FLUSH);%@NL@%
  14373.             WinSetDlgItemText(hwnd, IDCB_QDATA, "");%@NL@%
  14374.             UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);%@NL@%
  14375.             break;%@NL@%
  14376.             %@NL@%
  14377.         case IDC_QUPDATE:%@NL@%
  14378.             UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);%@NL@%
  14379.             WinSendDlgItemMsg(hwnd, IDCB_QDATA, CBM_SHOWLIST, (MPARAM)TRUE, 0L);%@NL@%
  14380.             break;%@NL@%
  14381.             %@NL@%
  14382.         case IDC_DOIT:%@NL@%
  14383.             i = (USHORT)WinSendDlgItemMsg(hwnd, IDRB_ADVSTART,%@NL@%
  14384.                     BM_QUERYCHECKINDEX, 0L, 0L) + IDRB_ADVSTART;%@NL@%
  14385.             WinQueryDlgItemText(hwnd, IDEF_APP, 255, szT);%@NL@%
  14386.             hszApp = DdeGetHsz(szT, 0, 0);%@NL@%
  14387.             WinQueryDlgItemText(hwnd, IDEF_TOPIC, 255, szT);%@NL@%
  14388.             hszTopic = DdeGetHsz(szT, 0, 0);%@NL@%
  14389.             WinQueryDlgItemText(hwnd, IDEF_ITEM, 255, szT);%@NL@%
  14390.             hszItem = DdeGetHsz(szT, 0, 0);%@NL@%
  14391.             if (i != IDRB_REQUEST) {%@NL@%
  14392.                 WinQueryDlgItemText(hwnd, IDEF_DATA, 255, szT);%@NL@%
  14393.                 cb = WinQueryDlgItemTextLength(hwnd, IDEF_DATA);%@NL@%
  14394.             }%@NL@%
  14395.             if (hConv == NULL && !(hConv = DdeConnect(hszApp, hszTopic, NULL, 0L))) {%@NL@%
  14396.                 DdePostError(DdeGetLastError());%@NL@%
  14397.                 if (LOUSHORT(mp1) == MBID_OK)%@NL@%
  14398.                     WinDismissDlg(hwnd, 0);%@NL@%
  14399.                 return(0);%@NL@%
  14400.             }%@NL@%
  14401.             switch (i) {%@NL@%
  14402.             case IDRB_REQUEST:%@NL@%
  14403.                 xtyp = XTYP_REQUEST;%@NL@%
  14404.                 goto XferOut;%@NL@%
  14405.                 break;%@NL@%
  14406.             case IDRB_ADVSTART:%@NL@%
  14407.                 xtyp = XTYP_ADVSTART;%@NL@%
  14408.                 goto XferOut;%@NL@%
  14409.                 break;%@NL@%
  14410.             case IDRB_ADVSTOP:%@NL@%
  14411.                 xtyp = XTYP_ADVSTOP;%@NL@%
  14412.                 goto XferOut;%@NL@%
  14413.                 break;%@NL@%
  14414.             case IDRB_POKE:%@NL@%
  14415.                 xtyp = XTYP_POKE;%@NL@%
  14416.                 goto XferOut;%@NL@%
  14417.                 break;%@NL@%
  14418.             case IDRB_EXECUTE:%@NL@%
  14419.                 xtyp = XTYP_EXEC;%@NL@%
  14420. XferOut:%@NL@%
  14421.                 fAssync = (BOOL)WinSendDlgItemMsg(hwnd, IDCBX_ASSYNC,%@NL@%
  14422.                         BM_QUERYCHECK, 0L, 0L);%@NL@%
  14423.                 if (!(hDmgData = DdeClientXfer((PBYTE)szT, (ULONG)cb + 1,%@NL@%
  14424.                         hConv, hszItem, DDEFMT_TEXT, xtyp,%@NL@%
  14425.                         fAssync ? TIMEOUT_ASYNC : gTimeout, &xid)))%@NL@%
  14426.                     DdePostError(DdeGetLastError());%@NL@%
  14427.                     %@NL@%
  14428.                 if (fAssync) {%@NL@%
  14429.                     UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);%@NL@%
  14430.                 } else {%@NL@%
  14431.                     if (i == IDRB_REQUEST) {%@NL@%
  14432.                         DdeGetData(hDmgData, szT, 255L, 0L);%@NL@%
  14433.                         DdeFreeData(hDmgData);%@NL@%
  14434.                         WinSetWindowText(gswp[IW_DATATEXT].hwnd, szT);%@NL@%
  14435.                         WinSetDlgItemText(hwnd, IDEF_DATA, szT);%@NL@%
  14436.                     }%@NL@%
  14437.                 }%@NL@%
  14438.                 %@NL@%
  14439.             }%@NL@%
  14440.             break;%@NL@%
  14441.         }%@NL@%
  14442.         break;%@NL@%
  14443. %@NL@%
  14444.     case WM_DESTROY:%@NL@%
  14445.         hwndExec = NULL;%@NL@%
  14446.     default:%@NL@%
  14447.         return(WinDefDlgProc(hwnd, msg, mp1, mp2));%@NL@%
  14448.         break;%@NL@%
  14449.     }%@NL@%
  14450.     return(0);%@NL@%
  14451. }%@NL@%
  14452. %@NL@%
  14453. %@NL@%
  14454. %@NL@%
  14455. void UpdateQueue(hwndCB, hConv)%@NL@%
  14456. HWND hwndCB;%@NL@%
  14457. HCONV hConv;%@NL@%
  14458. {%@NL@%
  14459.     SHORT lit;%@NL@%
  14460.     SHORT litSel = LIT_FIRST;%@NL@%
  14461.     CONVINFO ci;%@NL@%
  14462.     ULONG id, idSel;%@NL@%
  14463.     USHORT cItems;%@NL@%
  14464.     char szT[MAX_QSTRING];%@NL@%
  14465.     %@NL@%
  14466.     lit = (SHORT)WinSendMsg(hwndCB, LM_QUERYSELECTION,%@NL@%
  14467.             MPFROMSHORT(LIT_FIRST), 0L);%@NL@%
  14468.     idSel = (SHORT)WinSendMsg(hwndCB, LM_QUERYITEMHANDLE, MPFROMSHORT(lit), 0L);%@NL@%
  14469.     WinSendMsg(hwndCB, LM_DELETEALL, 0L, 0L);%@NL@%
  14470.     cItems = (USHORT)DdeCheckQueue(hConv, NULL, QID_NEWEST, CQ_COUNT);%@NL@%
  14471.     id = DdeCheckQueue(hConv, NULL, QID_NEWEST, 0L);%@NL@%
  14472.     while (cItems--) {%@NL@%
  14473.         DdeQueryConvInfo(hConv, &ci, id);%@NL@%
  14474.         ConvInfoToString(&ci, szT, MAX_QSTRING);%@NL@%
  14475.         lit = (SHORT)WinSendMsg(hwndCB, LM_INSERTITEM, MPFROMSHORT(LIT_END), szT);%@NL@%
  14476.         WinSendMsg(hwndCB, LM_SETITEMHANDLE, MPFROMSHORT(lit), (MPARAM)id);%@NL@%
  14477.         if (id == idSel) %@NL@%
  14478.             litSel = lit;%@NL@%
  14479.         id = DdeCheckQueue(hConv, NULL, id, CQ_NEXT);%@NL@%
  14480.     }%@NL@%
  14481.     WinSendMsg(hwndCB, LM_SELECTITEM, MPFROMSHORT(litSel), (MPARAM)TRUE);%@NL@%
  14482. }%@NL@%
  14483. %@NL@%
  14484. %@NL@%
  14485. %@NL@%
  14486. void ConvInfoToString(pci, psz, cbMax)%@NL@%
  14487. PCONVINFO pci;%@NL@%
  14488. PSZ psz;%@NL@%
  14489. USHORT cbMax;%@NL@%
  14490. {%@NL@%
  14491.     PSZ pszLast;%@NL@%
  14492.     char szT[100];%@NL@%
  14493.     %@NL@%
  14494.     pszLast = psz + cbMax - 1;%@NL@%
  14495.     *psz = '\0';%@NL@%
  14496.     psz = mylstrcat(psz, apszType[(pci->usType >> 4) && 0x1F], pszLast);%@NL@%
  14497.     psz = mylstrcat(psz, ": ", pszLast);%@NL@%
  14498.     psz = mylstrcat(psz, apszState[pci->usStatus & ST_CONNECTED ? 1 : 0], pszLast);%@NL@%
  14499.     psz = mylstrcat(psz, " ", pszLast);%@NL@%
  14500.     psz = mylstrcat(psz, apszState[pci->usStatus & ST_ADVISE ? 3 : 2], pszLast);%@NL@%
  14501.     psz = mylstrcat(psz, " ", pszLast);%@NL@%
  14502.     psz = mylstrcat(psz, apszStatus[pci->usConvst], pszLast);%@NL@%
  14503.     psz = mylstrcat(psz, " ", pszLast);%@NL@%
  14504.     if (pci->usFmt == DDEFMT_TEXT) {%@NL@%
  14505.         psz = mylstrcat(psz, "TEXT", pszLast);%@NL@%
  14506.     } else {   %@NL@%
  14507.         DdeGetHszString(pci->hszItem, szT, 100L);%@NL@%
  14508.         psz = mylstrcat(psz, szT, pszLast);%@NL@%
  14509.     }%@NL@%
  14510.     psz = mylstrcat(psz, " ", pszLast);%@NL@%
  14511.     DdeGetHszString(pci->hszItem, szT, 100L);%@NL@%
  14512.     psz = mylstrcat(psz, szT, pszLast);%@NL@%
  14513.     %@NL@%
  14514.     if (pci->LastError) {%@NL@%
  14515.         psz = mylstrcat(psz, " ", pszLast);%@NL@%
  14516.         DdeGetErrorString(pci->LastError, pszLast - psz, psz);%@NL@%
  14517.     }%@NL@%
  14518.     pszLast = '\0';%@NL@%
  14519. }%@NL@%
  14520. %@NL@%
  14521. %@NL@%
  14522. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  14523. %@AB@%* Concatonates psz1 and psz2 into psz1.%@NL@%
  14524. %@AB@%* returns psz pointing to end of concatonated string.%@NL@%
  14525. %@AB@%* pszLast marks point at which copying must stop.  This makes this operation%@NL@%
  14526. %@AB@%* safe for limited buffer sizes.%@NL@%
  14527. %@AB@%*%@NL@%
  14528. %@AB@%* History:  1/1/89  created sanfords%@NL@%
  14529. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  14530. PSZ mylstrcat(psz1, psz2, pszLast)%@NL@%
  14531. PSZ psz1, psz2, pszLast;%@NL@%
  14532. {%@NL@%
  14533.     psz1 += lstrlen(psz1);%@NL@%
  14534.     while (*psz2 != '\0' && psz1 < pszLast) {%@NL@%
  14535.         *psz1++ = *psz2++;%@NL@%
  14536.     }%@NL@%
  14537.     *psz1 = '\0';%@NL@%
  14538.     return(psz1);%@NL@%
  14539. }%@NL@%
  14540. %@NL@%
  14541. %@NL@%
  14542. %@AB@%/***************************** Private Function ****************************\%@NL@%
  14543. %@AB@%*%@NL@%
  14544. %@AB@%* returns string length not counting null terminator.%@NL@%
  14545. %@AB@%*%@NL@%
  14546. %@AB@%* History:  1/1/89  created     sanfords%@NL@%
  14547. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  14548. int lstrlen(psz)%@NL@%
  14549. PSZ psz;%@NL@%
  14550. {%@NL@%
  14551.     int c = 0;%@NL@%
  14552. %@NL@%
  14553.     while (*psz != 0) {%@NL@%
  14554.         psz++;%@NL@%
  14555.         c++;%@NL@%
  14556.     }%@NL@%
  14557.     return(c);%@NL@%
  14558. }%@NL@%
  14559. %@NL@%
  14560. %@NL@%
  14561. %@NL@%
  14562. %@2@%%@AH@%DEMO.C%@AE@%%@EH@%%@NL@%
  14563. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DEMO\DEMO.C%@AE@%%@NL@%
  14564. %@NL@%
  14565. %@AB@%/****************************** Module Header ******************************\%@NL@%
  14566. %@AB@%* Module Name:  demo.c - Demo application%@NL@%
  14567. %@AB@%*%@NL@%
  14568. %@AB@%* Created:%@NL@%
  14569. %@AB@%*%@NL@%
  14570. %@AB@%* Copyright (c) 1987  Microsoft Corporation%@NL@%
  14571. %@AB@%*%@NL@%
  14572. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  14573. %@NL@%
  14574. %@AI@%#include %@AE@%"demo.h" %@NL@%
  14575. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  14576. %@NL@%
  14577. %@AB@%/************* GLOBAL VARIABLES         */%@AE@%%@NL@%
  14578. %@NL@%
  14579. char szDemoClass[] = "Demo";%@NL@%
  14580. %@NL@%
  14581. HAB  hab;%@NL@%
  14582. HMQ  hmqDemo;%@NL@%
  14583. HWND hwndDemo;%@NL@%
  14584. HWND hwndDemoFrame;%@NL@%
  14585. HCONV hconv = NULL;%@NL@%
  14586. HSZ hszTitle, hszTopicChase, hszItemPos;%@NL@%
  14587. USHORT fmtSWP;%@NL@%
  14588. SWP SWPTarget = { 0 };%@NL@%
  14589. PFNWP RealFrameProc;%@NL@%
  14590. BOOL flee = FALSE;%@NL@%
  14591. USHORT cServers = 0;%@NL@%
  14592. USHORT cxScreen, cyScreen;%@NL@%
  14593. %@NL@%
  14594. %@AI@%#define %@AE@%TIMEOUT 100 %@NL@%
  14595. %@AI@%#define %@AE@%TIMERSPEED 1000 %@NL@%
  14596. %@NL@%
  14597. %@AB@%/**************************************/%@AE@%%@NL@%
  14598. %@NL@%
  14599. VOID CommandMsg(USHORT cmd)%@NL@%
  14600. {%@NL@%
  14601.     UNUSED cmd;%@NL@%
  14602. }%@NL@%
  14603. %@NL@%
  14604. BOOL DemoInit()%@NL@%
  14605. {%@NL@%
  14606.     hab = WinInitialize(0);%@NL@%
  14607. %@NL@%
  14608.     hmqDemo = WinCreateMsgQueue(hab, 0);%@NL@%
  14609. %@NL@%
  14610.     cxScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);%@NL@%
  14611.     cyScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);%@NL@%
  14612.     srand(2);%@NL@%
  14613.     %@NL@%
  14614.     if (!WinRegisterClass(hab, szDemoClass, (PFNWP)DemoWndProc,%@NL@%
  14615.             CS_SIZEREDRAW, 0))%@NL@%
  14616.          return(FALSE);%@NL@%
  14617. %@NL@%
  14618.     %@AB@%/*%@NL@%
  14619. %@AB@%     * Initialize the ddeml%@NL@%
  14620. %@AB@%     */%@AE@%%@NL@%
  14621.     if (DdeInitialize((PFNCALLBACK)callback, 0L, 0L))%@NL@%
  14622.         return(FALSE);%@NL@%
  14623. %@NL@%
  14624.     %@AB@%/*%@NL@%
  14625. %@AB@%     * Now create HSZs for each of our DDE strings.%@NL@%
  14626. %@AB@%     */%@AE@%%@NL@%
  14627.     fmtSWP = WinAddAtom(WinQuerySystemAtomTable(), "SWP FORMAT");%@NL@%
  14628.     hszTitle = DdeGetHsz("Demo", 0, 0);%@NL@%
  14629.     hszTopicChase = DdeGetHsz("Chaser", 0, 0);%@NL@%
  14630.     hszItemPos = DdeGetHsz("Position", 0, 0);%@NL@%
  14631. %@NL@%
  14632.     %@AB@%/*%@NL@%
  14633. %@AB@%     * let others know we are here - available as a server and turn on%@NL@%
  14634. %@AB@%     * filtering so we don't get bothered with any initiates for any%@NL@%
  14635. %@AB@%     * other app names.%@NL@%
  14636. %@AB@%     */%@AE@%%@NL@%
  14637.     DdeAppNameServer(hszTitle, ANS_REGISTER | ANS_FILTERON);%@NL@%
  14638.         %@NL@%
  14639.     return(TRUE);%@NL@%
  14640. }%@NL@%
  14641. %@NL@%
  14642. int cdecl main(int argc, char** argv)%@NL@%
  14643. {%@NL@%
  14644.     ULONG fcf;%@NL@%
  14645.     QMSG qmsg;%@NL@%
  14646. %@NL@%
  14647.     UNUSED argc;%@NL@%
  14648.     UNUSED argv;%@NL@%
  14649. %@NL@%
  14650.     if (!DemoInit()) {%@NL@%
  14651.         WinAlarm(HWND_DESKTOP, WA_ERROR);%@NL@%
  14652.         return(0);%@NL@%
  14653.     }%@NL@%
  14654. %@NL@%
  14655.     fcf = FCF_STANDARD;%@NL@%
  14656. %@NL@%
  14657.     hwndDemoFrame = WinCreateStdWindow(%@NL@%
  14658.             HWND_DESKTOP,%@NL@%
  14659.             WS_VISIBLE,%@NL@%
  14660.             &fcf,%@NL@%
  14661.             szDemoClass,%@NL@%
  14662.             "",%@NL@%
  14663.             WS_VISIBLE, %@NL@%
  14664.             NULL,%@NL@%
  14665.             IDR_DEMO,%@NL@%
  14666.             &hwndDemo);%@NL@%
  14667. %@NL@%
  14668.     WinSetFocus(HWND_DESKTOP, hwndDemo);%@NL@%
  14669. %@NL@%
  14670.     while (WinGetMsg(hab, (PQMSG)&qmsg, NULL, 0, 0)) {%@NL@%
  14671.         WinDispatchMsg(hab, (PQMSG)&qmsg);%@NL@%
  14672.     }%@NL@%
  14673. %@NL@%
  14674.     WinDestroyWindow(hwndDemoFrame);%@NL@%
  14675. %@NL@%
  14676.     WinDestroyMsgQueue(hmqDemo);%@NL@%
  14677.     WinTerminate(hab);%@NL@%
  14678. %@NL@%
  14679.     return(0);%@NL@%
  14680. }%@NL@%
  14681. %@NL@%
  14682. %@AB@%/********** Demo Window Procedure **************/%@AE@%%@NL@%
  14683. %@NL@%
  14684. MRESULT FAR PASCAL DemoWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  14685. {%@NL@%
  14686.     HPS   hps;%@NL@%
  14687.     RECTL rclPaint;%@NL@%
  14688.     SWP swp;%@NL@%
  14689.     SHORT speed;%@NL@%
  14690. %@NL@%
  14691.     switch (msg) {%@NL@%
  14692.     case WM_CREATE:%@NL@%
  14693.         %@AB@%/* Set up this global first thing in case we need it elsewhere */%@AE@%%@NL@%
  14694.         hwndDemo = hwnd;%@NL@%
  14695.         hwndDemoFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);%@NL@%
  14696.         RealFrameProc = WinSubclassWindow(hwndDemoFrame, DemoFrameWndProc);%@NL@%
  14697.         WinSetWindowPos(hwndDemoFrame, NULL, 0, 0, 0, 0, SWP_MINIMIZE | SWP_SHOW);%@NL@%
  14698.         %@AB@%/*%@NL@%
  14699. %@AB@%         * start the timer so we will keep looking for another app like ours%@NL@%
  14700. %@AB@%         * to chase.%@NL@%
  14701. %@AB@%         */%@AE@%%@NL@%
  14702.         WinStartTimer(hab, hwndDemo, 1, TIMERSPEED);%@NL@%
  14703.         return(MRFROMSHORT(FALSE));%@NL@%
  14704.         break;%@NL@%
  14705. %@NL@%
  14706.     case WM_TIMER:%@NL@%
  14707.         %@AB@%/*%@NL@%
  14708. %@AB@%         * We use a timer to keep us moving.%@NL@%
  14709. %@AB@%         */%@AE@%%@NL@%
  14710.         if (!hconv) {%@NL@%
  14711.             HDMGDATA hData;%@NL@%
  14712.             PHSZHAPP phszhapp;%@NL@%
  14713.             %@AB@%/*%@NL@%
  14714. %@AB@%             * no active conversation, try to make one.%@NL@%
  14715. %@AB@%             */%@AE@%%@NL@%
  14716.             WinStopTimer(hab, hwndDemo, 1);%@NL@%
  14717.             %@AB@%/*%@NL@%
  14718. %@AB@%             * find out if any others like us are out there%@NL@%
  14719. %@AB@%             */%@AE@%%@NL@%
  14720.             hData = DdeAppNameServer(hszTitle, ANS_QUERYALLBUTME);%@NL@%
  14721.             if (!hData) {%@NL@%
  14722.                 %@AB@%/*%@NL@%
  14723. %@AB@%                 * wait till others arrive.%@NL@%
  14724. %@AB@%                 */%@AE@%%@NL@%
  14725.                 return(0);%@NL@%
  14726.             }%@NL@%
  14727.             %@AB@%/*%@NL@%
  14728. %@AB@%             * extract the first hApp from the hData so we can connect to it%@NL@%
  14729. %@AB@%             */%@AE@%%@NL@%
  14730.             phszhapp = (PHSZHAPP)DdeAccessData(hData);%@NL@%
  14731.             if (phszhapp->hsz == 0) {%@NL@%
  14732.                 DdeFreeData(hData);%@NL@%
  14733.                 return(0);%@NL@%
  14734.             }%@NL@%
  14735.             %@AB@%/*%@NL@%
  14736. %@AB@%             * perform directed connection to our target%@NL@%
  14737. %@AB@%             */%@AE@%%@NL@%
  14738.             hconv = DdeConnect(hszTitle, hszTopicChase, NULL, phszhapp->hApp);%@NL@%
  14739.             %@AB@%/*%@NL@%
  14740. %@AB@%             * free the hData now that we are done using it.%@NL@%
  14741. %@AB@%             */%@AE@%%@NL@%
  14742.             DdeFreeData(hData);%@NL@%
  14743.             WinStartTimer(hab, hwndDemo, 1, TIMERSPEED);%@NL@%
  14744.             if (!hconv) {%@NL@%
  14745.                 %@AB@%/*%@NL@%
  14746. %@AB@%                 * cant make one, try again later.%@NL@%
  14747. %@AB@%                 */%@AE@%%@NL@%
  14748.                 return(0);%@NL@%
  14749.             }%@NL@%
  14750.             %@AB@%/*%@NL@%
  14751. %@AB@%             * Get the target's position into SWPTarget.%@NL@%
  14752. %@AB@%             */%@AE@%%@NL@%
  14753.             if (hData = DdeClientXfer(NULL, 0L, hconv, hszItemPos, fmtSWP,%@NL@%
  14754.                     XTYP_REQUEST, TIMEOUT, NULL)) {%@NL@%
  14755.                 DdeCopyBlock(DdeAccessData(hData), (PBYTE)&SWPTarget,%@NL@%
  14756.                         sizeof(SWP));%@NL@%
  14757.                 DdeFreeData(hData);%@NL@%
  14758.             }%@NL@%
  14759.             %@AB@%/*%@NL@%
  14760. %@AB@%             * set up an advise loop so our moving target keeps us informed%@NL@%
  14761. %@AB@%             * of where he is.%@NL@%
  14762. %@AB@%             */%@AE@%%@NL@%
  14763.             DdeClientXfer(NULL, 0L, hconv, hszItemPos, fmtSWP,%@NL@%
  14764.                     XTYP_ADVSTART, TIMEOUT, NULL);%@NL@%
  14765.         }%@NL@%
  14766.         %@NL@%
  14767.         if (WinIsWindow(hab, SWPTarget.hwnd)) {%@NL@%
  14768.             %@AB@%/*%@NL@%
  14769. %@AB@%             * target data must be valid, move toward it.%@NL@%
  14770. %@AB@%             */%@AE@%%@NL@%
  14771.             speed = 1;%@NL@%
  14772.             WinQueryWindowPos(hwndDemoFrame, &swp);%@NL@%
  14773.             if (swp.x > SWPTarget.x) %@NL@%
  14774.                 swp.x -= speed;%@NL@%
  14775.             if (swp.x < SWPTarget.x)%@NL@%
  14776.                 swp.x += speed;%@NL@%
  14777.             if (swp.y > SWPTarget.y) %@NL@%
  14778.                 swp.y -= speed;%@NL@%
  14779.             if (swp.y < SWPTarget.y)%@NL@%
  14780.                 swp.y += speed;%@NL@%
  14781.             swp.fs = SWP_MOVE | SWP_NOADJUST;%@NL@%
  14782.             WinSetMultWindowPos(hab, &swp, 1);%@NL@%
  14783.             if ((swp.x == SWPTarget.x) && (swp.y == SWPTarget.y) && (!flee)) {%@NL@%
  14784.                 %@AB@%/*%@NL@%
  14785. %@AB@%                 * he's cought stop chasing him and go find another.%@NL@%
  14786. %@AB@%                 */%@AE@%%@NL@%
  14787.                 WinAlarm(HWND_DESKTOP, WA_NOTE);%@NL@%
  14788.                 DdeDisconnect(hconv);%@NL@%
  14789.                 hconv = NULL;%@NL@%
  14790.                 %@AB@%/*%@NL@%
  14791. %@AB@%                 * move to a random position%@NL@%
  14792. %@AB@%                 */%@AE@%%@NL@%
  14793.                 WinSetWindowPos(hwndDemoFrame, HWND_TOP, rand() % cxScreen,%@NL@%
  14794.                         rand() % cyScreen, 0, 0,%@NL@%
  14795.                         SWP_MOVE | SWP_ZORDER | SWP_NOADJUST);%@NL@%
  14796.             }%@NL@%
  14797.         } else if (hconv) {%@NL@%
  14798.             %@AB@%/*%@NL@%
  14799. %@AB@%             * Target is invalid, disconnect and try a reconnect later.%@NL@%
  14800. %@AB@%             */%@AE@%%@NL@%
  14801.             DdeDisconnect(hconv);%@NL@%
  14802.             hconv = NULL;%@NL@%
  14803.         }%@NL@%
  14804.         break;%@NL@%
  14805. %@NL@%
  14806.     case WM_PAINT:%@NL@%
  14807.         hps = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);%@NL@%
  14808.         DemoPaint(hwnd, hps, &rclPaint);%@NL@%
  14809.         WinEndPaint(hps);%@NL@%
  14810.         break;%@NL@%
  14811. %@NL@%
  14812.     case WM_COMMAND:%@NL@%
  14813.         CommandMsg(LOUSHORT(mp1));%@NL@%
  14814.         break;%@NL@%
  14815. %@NL@%
  14816.     default:%@NL@%
  14817.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  14818.         break;%@NL@%
  14819.     }%@NL@%
  14820.     return(0L);%@NL@%
  14821. }%@NL@%
  14822. %@NL@%
  14823. %@NL@%
  14824. %@NL@%
  14825. MRESULT FAR PASCAL DemoFrameWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  14826. {%@NL@%
  14827.     switch (msg) {%@NL@%
  14828.     case WM_MOVE:%@NL@%
  14829.         DdePostAdvise(hszTopicChase, hszItemPos);%@NL@%
  14830.         %@AB@%/* fall through */%@AE@%%@NL@%
  14831.     default:%@NL@%
  14832.         return(RealFrameProc(hwnd, msg, mp1, mp2));%@NL@%
  14833.         break;%@NL@%
  14834.     }%@NL@%
  14835.     return(0L);%@NL@%
  14836. }%@NL@%
  14837. %@NL@%
  14838. %@NL@%
  14839. VOID DemoPaint(HWND hwnd, HPS hps, RECTL* prcl)%@NL@%
  14840. {%@NL@%
  14841.     RECTL rcl;%@NL@%
  14842. %@NL@%
  14843.     UNUSED prcl;%@NL@%
  14844.     %@NL@%
  14845.     %@AB@%/* get window interior rect */%@AE@%%@NL@%
  14846.     WinQueryWindowRect(hwnd, &rcl);%@NL@%
  14847. %@NL@%
  14848.     %@AB@%/* print "Hello World" centered horizontally and vertically */%@AE@%%@NL@%
  14849.     WinDrawText(hps, -1, "Hello World", &rcl, SYSCLR_WINDOWTEXT,%@NL@%
  14850.             SYSCLR_WINDOW, DT_CENTER | DT_VCENTER | DT_ERASERECT);%@NL@%
  14851. %@NL@%
  14852.     %@AB@%/* draw interior border */%@AE@%%@NL@%
  14853.     WinDrawBorder(hps, &rcl, 6, 6, SYSCLR_WINDOWTEXT, SYSCLR_WINDOW,%@NL@%
  14854.             DB_STANDARD);%@NL@%
  14855. }%@NL@%
  14856. %@NL@%
  14857. %@NL@%
  14858. %@NL@%
  14859. HDMGDATA EXPENTRY callback(%@NL@%
  14860. HCONV hConv,%@NL@%
  14861. HSZ hszTopic,%@NL@%
  14862. HSZ hszItem,%@NL@%
  14863. USHORT usFmt,%@NL@%
  14864. USHORT usType,%@NL@%
  14865. HDMGDATA hDmgData)%@NL@%
  14866. {%@NL@%
  14867.     SWP swp;%@NL@%
  14868. %@NL@%
  14869.     UNUSED hConv;%@NL@%
  14870. %@NL@%
  14871.     if (usType == XTYP_REGISTER && hszItem == hszTitle && !hconv) {%@NL@%
  14872.         %@AB@%/*%@NL@%
  14873. %@AB@%         * someone else came onboard, if we are looking for a target,%@NL@%
  14874. %@AB@%         * restart our clock.%@NL@%
  14875. %@AB@%         */%@AE@%%@NL@%
  14876.         WinStartTimer(hab, hwndDemo, 1, TIMERSPEED);%@NL@%
  14877.     }%@NL@%
  14878.     %@NL@%
  14879.     %@AB@%/*%@NL@%
  14880. %@AB@%     * we only care about stuff on our topic.%@NL@%
  14881. %@AB@%     */%@AE@%%@NL@%
  14882.     if (hszTopic != hszTopicChase)%@NL@%
  14883.         return(0);%@NL@%
  14884. %@NL@%
  14885.     switch (usType) {%@NL@%
  14886.         %@NL@%
  14887.     case XTYP_ADVSTART:%@NL@%
  14888.         %@AB@%/*%@NL@%
  14889. %@AB@%         * Always allow advises on our item%@NL@%
  14890. %@AB@%         */%@AE@%%@NL@%
  14891.         return(hszItem == hszItemPos);%@NL@%
  14892.         break;%@NL@%
  14893. %@NL@%
  14894.     case XTYP_ADVDATA:%@NL@%
  14895.         %@AB@%/*%@NL@%
  14896. %@AB@%         * Always accept advise data on our target's latest position.%@NL@%
  14897. %@AB@%         */%@AE@%%@NL@%
  14898.         if (hszItem == hszItemPos) %@NL@%
  14899.             DdeGetData(hDmgData, (PBYTE)&SWPTarget, sizeof(SWP), 0L);%@NL@%
  14900.         DdeFreeData(hDmgData);%@NL@%
  14901.         return(0);%@NL@%
  14902.         break;%@NL@%
  14903.                 %@NL@%
  14904.     case XTYP_INIT:%@NL@%
  14905.         %@AB@%/*%@NL@%
  14906. %@AB@%         * always allow others to initiate with us on our topic.%@NL@%
  14907. %@AB@%         */%@AE@%%@NL@%
  14908.         return(hszItem == hszTitle && hszTopic == hszTopicChase);%@NL@%
  14909.         break;%@NL@%
  14910. %@NL@%
  14911.     case XTYP_REQUEST:%@NL@%
  14912.     case XTYP_ADVREQ:%@NL@%
  14913.         %@AB@%/*%@NL@%
  14914. %@AB@%         * Respond to data requests as to our whereabouts item and format are%@NL@%
  14915. %@AB@%         * ok.%@NL@%
  14916. %@AB@%         */%@AE@%%@NL@%
  14917.         if (hszItem != hszItemPos || usFmt != fmtSWP) %@NL@%
  14918.             return(0);%@NL@%
  14919.         WinQueryWindowPos(hwndDemoFrame, &swp);%@NL@%
  14920.         return(DdePutData((PBYTE)&swp, sizeof(SWP), 0L, hszItemPos, fmtSWP, 0));%@NL@%
  14921.         break;%@NL@%
  14922. %@NL@%
  14923.     default:%@NL@%
  14924.         return(0);%@NL@%
  14925.     }%@NL@%
  14926. }%@NL@%
  14927. %@NL@%
  14928. %@NL@%
  14929. %@NL@%
  14930. %@NL@%
  14931. %@NL@%
  14932. %@2@%%@AH@%DIALOGS.C%@AE@%%@EH@%%@NL@%
  14933. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CLOCK\DIALOGS.C%@AE@%%@NL@%
  14934. %@NL@%
  14935. %@AB@%/*%@NL@%
  14936. %@AB@%    dialogs.c                Dialog procedures for PM Clock Application%@NL@%
  14937. %@AB@%%@NL@%
  14938. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  14939. %@AB@%*/%@AE@%%@NL@%
  14940. %@AI@%#define %@AE@%INCL_WINDIALOGS %@NL@%
  14941. %@AI@%#define %@AE@%INCL_WINBUTTONS %@NL@%
  14942. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  14943. %@AI@%#include %@AE@%<os2def.h> %@NL@%
  14944. %@AI@%#include %@AE@%<pmwin.h> %@NL@%
  14945. %@AI@%#include %@AE@%"dialogs.h" %@NL@%
  14946. %@NL@%
  14947. %@AB@%/* defined in paint.c */%@AE@%%@NL@%
  14948. extern USHORT usMajorTickPref ;%@NL@%
  14949. extern USHORT usMinorTickPref ;%@NL@%
  14950. extern LONG clrBackground ;%@NL@%
  14951. extern LONG clrFace ;%@NL@%
  14952. extern LONG clrHourHand ;%@NL@%
  14953. extern LONG clrMinuteHand ;%@NL@%
  14954. %@NL@%
  14955. %@AB@%/* defined in clock.c */%@AE@%%@NL@%
  14956. extern HWND hwndFrame ;%@NL@%
  14957. %@NL@%
  14958. %@AB@%/*%@NL@%
  14959. %@AB@%    ClkAboutDlgProc()                 "About..." dialog%@NL@%
  14960. %@AB@%%@NL@%
  14961. %@AB@%    Returns:        MRESULT, 0 or return value from WinDefDlgProc%@NL@%
  14962. %@AB@%*/%@AE@%%@NL@%
  14963. MRESULT EXPENTRY ClkAboutDlgProc ( HWND hwnd , USHORT usMsg ,%@NL@%
  14964.                                    MPARAM mp1 , MPARAM mp2 )%@NL@%
  14965. {%@NL@%
  14966.     if ( usMsg == WM_COMMAND ) {%@NL@%
  14967.         WinDismissDlg ( hwnd , TRUE ) ;%@NL@%
  14968.         return 0L ;%@NL@%
  14969.     }%@NL@%
  14970.     else return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;%@NL@%
  14971. }%@NL@%
  14972. %@NL@%
  14973. %@NL@%
  14974. %@AB@%/*%@NL@%
  14975. %@AB@%    ClkTicksDlgProc()                "Ticks..." dialog%@NL@%
  14976. %@AB@%%@NL@%
  14977. %@AB@%    Returns: MRESULT, 0 or return value from WinDefDlgProc%@NL@%
  14978. %@AB@%*/%@AE@%%@NL@%
  14979. MRESULT EXPENTRY ClkTicksDlgProc ( HWND hwnd , USHORT usMsg ,%@NL@%
  14980.                                    MPARAM mp1 , MPARAM mp2 )%@NL@%
  14981. {%@NL@%
  14982.     static USHORT usMajorTickSel ;%@NL@%
  14983.     static USHORT usMinorTickSel ;%@NL@%
  14984.     USHORT usButtonID ;%@NL@%
  14985. %@NL@%
  14986.     switch ( usMsg ) {%@NL@%
  14987. %@NL@%
  14988.         case WM_INITDLG :%@NL@%
  14989. %@NL@%
  14990.             %@AB@%/* show the current major tick preference */%@AE@%%@NL@%
  14991.             WinSendMsg ( WinWindowFromID ( hwnd ,%@NL@%
  14992.                                            CLKTM_MAJOR | usMajorTickPref ) ,%@NL@%
  14993.                          BM_SETCHECK , MPFROM2SHORT ( TRUE , NULL ) , NULL ) ;%@NL@%
  14994. %@NL@%
  14995.             %@AB@%/* show the current minor tick preference */%@AE@%%@NL@%
  14996.             WinSendMsg ( WinWindowFromID ( hwnd ,%@NL@%
  14997.                                            CLKTM_MINOR | usMinorTickPref ) ,%@NL@%
  14998.                          BM_SETCHECK , MPFROM2SHORT ( TRUE , NULL ) , NULL ) ;%@NL@%
  14999. %@NL@%
  15000.             %@AB@%/* load the selection values from the preferences */%@AE@%%@NL@%
  15001.             usMajorTickSel = usMajorTickPref ;%@NL@%
  15002.             usMinorTickSel = usMinorTickPref ;%@NL@%
  15003. %@NL@%
  15004.             %@AB@%/* let the default dialog procedure handle anything else */%@AE@%%@NL@%
  15005.             break ;%@NL@%
  15006. %@NL@%
  15007.         case WM_COMMAND :%@NL@%
  15008. %@NL@%
  15009.             switch ( LOUSHORT ( mp1 ) ) {%@NL@%
  15010. %@NL@%
  15011.                 case DID_OK :%@NL@%
  15012. %@NL@%
  15013.                     %@AB@%/* store away selections as preferences */%@AE@%%@NL@%
  15014.                     usMajorTickPref = usMajorTickSel ;%@NL@%
  15015.                     usMinorTickPref = usMinorTickSel ;%@NL@%
  15016. %@NL@%
  15017.                     %@AB@%/* repaint with the new preferences */%@AE@%%@NL@%
  15018.                     WinInvalidateRect ( hwndFrame , NULL, TRUE ) ;%@NL@%
  15019. %@NL@%
  15020.                 case DID_CANCEL :%@NL@%
  15021.                     WinDismissDlg ( hwnd , TRUE ) ;%@NL@%
  15022.             }%@NL@%
  15023. %@NL@%
  15024.             return NULL ;%@NL@%
  15025. %@NL@%
  15026.         case WM_CONTROL :%@NL@%
  15027. %@NL@%
  15028.             if ( SHORT2FROMMP ( mp1 ) == BN_CLICKED ) {%@NL@%
  15029. %@NL@%
  15030.                 usButtonID = SHORT1FROMMP ( mp1 ) ;%@NL@%
  15031. %@NL@%
  15032.                 switch ( usButtonID & 0xff00 ) {%@NL@%
  15033. %@NL@%
  15034.                     case CLKTM_MAJOR :%@NL@%
  15035.                         usMajorTickSel = LOBYTE ( usButtonID ) ;%@NL@%
  15036.                         break ;%@NL@%
  15037. %@NL@%
  15038.                     case CLKTM_MINOR :%@NL@%
  15039.                         usMinorTickSel = LOBYTE ( usButtonID ) ;%@NL@%
  15040.                         break ;%@NL@%
  15041.                 }%@NL@%
  15042.             }%@NL@%
  15043. %@NL@%
  15044.             %@AB@%/* fall through to the default control processing */%@AE@%%@NL@%
  15045.     }%@NL@%
  15046. %@NL@%
  15047.     return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;%@NL@%
  15048. }%@NL@%
  15049. %@NL@%
  15050. %@NL@%
  15051. %@AB@%/*%@NL@%
  15052. %@AB@%    ClkColorsDlgProc()                "Clock Color Preferences" Dialog%@NL@%
  15053. %@AB@%%@NL@%
  15054. %@AB@%    Returns: MRESULT, 0 or return value from WinDefDlgProc%@NL@%
  15055. %@AB@%*/%@AE@%%@NL@%
  15056. MRESULT EXPENTRY ClkColorsDlgProc ( HWND hwnd , USHORT usMsg ,%@NL@%
  15057.                                    MPARAM mp1 , MPARAM mp2 )%@NL@%
  15058. {%@NL@%
  15059.     USHORT usButtonID ;%@NL@%
  15060.     static USHORT usCheckedButtonID ;%@NL@%
  15061.     HWND hwndButton ;%@NL@%
  15062.     RECTL rclButton , rclButtonInterior ;%@NL@%
  15063.     static LONG clrBackgroundNew ;%@NL@%
  15064.     static LONG clrFaceNew ;%@NL@%
  15065.     static LONG clrHourHandNew ;%@NL@%
  15066.     static LONG clrMinuteHandNew ;%@NL@%
  15067.     static LONG * pclrNew ;%@NL@%
  15068. %@NL@%
  15069.     switch ( usMsg ) {%@NL@%
  15070. %@NL@%
  15071.         case WM_INITDLG :%@NL@%
  15072. %@NL@%
  15073.             %@AB@%/* load the new values from the current ones */%@AE@%%@NL@%
  15074.             clrBackgroundNew = clrBackground ;%@NL@%
  15075.             clrFaceNew = clrFace ;%@NL@%
  15076.             clrHourHandNew = clrHourHand ;%@NL@%
  15077.             clrMinuteHandNew = clrMinuteHand ;%@NL@%
  15078. %@NL@%
  15079.             %@AB@%/* click the "Background" radio button */%@AE@%%@NL@%
  15080.             WinSendMsg ( WinWindowFromID ( hwnd , CLKCLR_BACKGROUND ) ,%@NL@%
  15081.                          BM_CLICK , MPFROMSHORT ( TRUE ) , NULL ) ;%@NL@%
  15082. %@NL@%
  15083.             %@AB@%/* let the default dialog procedure handle anything else */%@AE@%%@NL@%
  15084.             break ;%@NL@%
  15085. %@NL@%
  15086.         case WM_COMMAND :%@NL@%
  15087. %@NL@%
  15088.             switch ( LOUSHORT ( mp1 ) ) {%@NL@%
  15089.                 case DID_OK :%@NL@%
  15090. %@NL@%
  15091.                     %@AB@%/* store the new values */%@AE@%%@NL@%
  15092.                     clrBackground = clrBackgroundNew ;%@NL@%
  15093.                     clrFace = clrFaceNew ;%@NL@%
  15094.                     clrHourHand = clrHourHandNew ;%@NL@%
  15095.                     clrMinuteHand = clrMinuteHandNew ;%@NL@%
  15096. %@NL@%
  15097.                     %@AB@%/* repaint with the new colors */%@AE@%%@NL@%
  15098.                     WinInvalidateRect ( hwndFrame , NULL, TRUE ) ;%@NL@%
  15099. %@NL@%
  15100.                 case DID_CANCEL :%@NL@%
  15101. %@NL@%
  15102.                     WinDismissDlg ( hwnd , TRUE ) ;%@NL@%
  15103.             }%@NL@%
  15104.             return NULL ;%@NL@%
  15105. %@NL@%
  15106.         case WM_CONTROL :%@NL@%
  15107. %@NL@%
  15108.             usButtonID = SHORT1FROMMP ( mp1 ) ;%@NL@%
  15109. %@NL@%
  15110.             %@AB@%/* selecting a new object */%@AE@%%@NL@%
  15111.             if ( usButtonID & CLKCLR_OBJECTS ) {%@NL@%
  15112. %@NL@%
  15113.                 switch ( usButtonID ) {%@NL@%
  15114.                     case CLKCLR_BACKGROUND :%@NL@%
  15115.                         pclrNew = & clrBackgroundNew ;%@NL@%
  15116.                         break ;%@NL@%
  15117.                     case CLKCLR_FACE :%@NL@%
  15118.                         pclrNew = & clrFaceNew ;%@NL@%
  15119.                         break ;%@NL@%
  15120.                     case CLKCLR_HOURHAND :%@NL@%
  15121.                         pclrNew = & clrHourHandNew ;%@NL@%
  15122.                         break ;%@NL@%
  15123.                     case CLKCLR_MINUTEHAND :%@NL@%
  15124.                         pclrNew = & clrMinuteHandNew ;%@NL@%
  15125.                 }%@NL@%
  15126. %@NL@%
  15127.                 %@AB@%/* click the button for the new object's current color */%@AE@%%@NL@%
  15128.                 WinSendMsg (%@NL@%
  15129.                     WinWindowFromID ( hwnd ,%@NL@%
  15130.                         CLKCLR_BUTTONSHIFT + ( USHORT ) * pclrNew ) ,%@NL@%
  15131.                     BM_CLICK , MPFROMSHORT ( TRUE ) , NULL ) ;%@NL@%
  15132. %@NL@%
  15133.                 break ;%@NL@%
  15134.             }%@NL@%
  15135. %@NL@%
  15136.             switch ( SHORT2FROMMP ( mp1 ) ) {%@NL@%
  15137. %@NL@%
  15138.                 case BN_CLICKED :%@NL@%
  15139. %@NL@%
  15140.                     * pclrNew = ( LONG ) usButtonID - CLKCLR_BUTTONSHIFT ;%@NL@%
  15141. %@NL@%
  15142.                     %@AB@%/* turn off the check state of the previously checked%@NL@%
  15143. %@AB@%                     * button and turn on the check state of the button%@NL@%
  15144. %@AB@%                     * just clicked */%@AE@%%@NL@%
  15145. %@NL@%
  15146.                     WinSendMsg ( WinWindowFromID ( hwnd , usCheckedButtonID ) ,%@NL@%
  15147.                                  BM_SETCHECK , MPFROM2SHORT ( FALSE , NULL ) ,%@NL@%
  15148.                                  NULL ) ;%@NL@%
  15149.                     WinSendMsg ( WinWindowFromID ( hwnd , usButtonID ) ,%@NL@%
  15150.                                  BM_SETCHECK , MPFROM2SHORT ( TRUE , NULL ) ,%@NL@%
  15151.                                  NULL ) ;%@NL@%
  15152. %@NL@%
  15153.                     usCheckedButtonID = usButtonID ;%@NL@%
  15154. %@NL@%
  15155.                     break ;%@NL@%
  15156. %@NL@%
  15157.                 case BN_PAINT :%@NL@%
  15158. %@NL@%
  15159.                     %@AB@%/* fill only the interior of the button, so we don't%@NL@%
  15160. %@AB@%                     * conflict with the focus indicator */%@AE@%%@NL@%
  15161. %@NL@%
  15162.                     hwndButton = ( ( PUSERBUTTON ) mp2 ) -> hwnd ;%@NL@%
  15163.                     WinQueryWindowRect ( hwndButton , & rclButton ) ;%@NL@%
  15164.                     rclButton . xLeft ++ ;%@NL@%
  15165.                     rclButton . yBottom ++ ;%@NL@%
  15166.                     rclButton . xRight -- ;%@NL@%
  15167.                     rclButton . yTop -- ;%@NL@%
  15168.                     WinFillRect ( ( ( PUSERBUTTON ) mp2 ) -> hps ,%@NL@%
  15169.                                   & rclButton ,%@NL@%
  15170.                                   ( LONG ) usButtonID - CLKCLR_BUTTONSHIFT ) ;%@NL@%
  15171. %@NL@%
  15172.                     %@AB@%/* hollow out those buttons which aren't checked */%@AE@%%@NL@%
  15173.                     if ( ! WinSendMsg ( WinWindowFromID ( hwnd , usButtonID ) ,%@NL@%
  15174.                                       BM_QUERYCHECK , NULL , NULL ) ) {%@NL@%
  15175.                         rclButtonInterior . xLeft = rclButton . xLeft + 4 ;%@NL@%
  15176.                         rclButtonInterior . yBottom = rclButton . yBottom + 4 ;%@NL@%
  15177.                         rclButtonInterior . xRight = rclButton . xRight - 4 ;%@NL@%
  15178.                         rclButtonInterior . yTop = rclButton . yTop - 4 ;%@NL@%
  15179.                         WinFillRect ( ( ( PUSERBUTTON ) mp2 ) -> hps ,%@NL@%
  15180.                                       & rclButtonInterior , SYSCLR_WINDOW ) ;%@NL@%
  15181.                     }%@NL@%
  15182. %@NL@%
  15183.                     break ;%@NL@%
  15184.             }%@NL@%
  15185. %@NL@%
  15186.             %@AB@%/* fall through to the default control processing */%@AE@%%@NL@%
  15187.     }%@NL@%
  15188. %@NL@%
  15189.     return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;%@NL@%
  15190. }%@NL@%
  15191. %@NL@%
  15192. %@NL@%
  15193. %@2@%%@AH@%DLGPROC.C%@AE@%%@EH@%%@NL@%
  15194. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\INIEDIT\DLGPROC.C%@AE@%%@NL@%
  15195. %@NL@%
  15196. %@AB@%/******************************* Module Header ******************************\%@NL@%
  15197. %@AB@%* Module Name: DlgProc.c%@NL@%
  15198. %@AB@%*%@NL@%
  15199. %@AB@%* Created by Microsoft Corporation, 1989%@NL@%
  15200. %@AB@%*%@NL@%
  15201. %@AB@%*%@NL@%
  15202. %@AB@%* System Test Application%@NL@%
  15203. %@AB@%*%@NL@%
  15204. %@AB@%*%@NL@%
  15205. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  15206. %@NL@%
  15207. %@NL@%
  15208. %@AI@%#define %@AE@%LINT_ARGS                           // Include needed parts of PM %@NL@%
  15209. %@AI@%#define %@AE@%INCL_WININPUT                       //    definitions %@NL@%
  15210. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  15211. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  15212. %@AI@%#define %@AE@%INCL_WINBUTTONS %@NL@%
  15213. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  15214. %@AI@%#define %@AE@%INCL_WINHEAP %@NL@%
  15215. %@AI@%#define %@AE@%INCL_WINSHELLDATA %@NL@%
  15216. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  15217. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  15218. %@AI@%#define %@AE@%INCL_WINLISTBOXES %@NL@%
  15219. %@AI@%#define %@AE@%INCL_WINENTRYFIELDS %@NL@%
  15220. %@AI@%#define %@AE@%INCL_WINDIALOGS %@NL@%
  15221. %@AI@%#define %@AE@%INCL_GPIBITMAPS %@NL@%
  15222. %@AI@%#define %@AE@%INCL_GPIREGIONS %@NL@%
  15223. %@AI@%#define %@AE@%INCL_GPILCIDS %@NL@%
  15224. %@AI@%#define %@AE@%INCL_GPIPRIMITIVES %@NL@%
  15225. %@AI@%#define %@AE@%INCL_DEV %@NL@%
  15226. %@NL@%
  15227. %@AI@%#include %@AE@%<string.h> %@NL@%
  15228. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  15229. %@NL@%
  15230. %@AI@%#include %@AE@%<os2.h> %@NL@%
  15231. %@NL@%
  15232. %@AI@%#include %@AE@%"IniEdit.h" %@NL@%
  15233. %@NL@%
  15234. %@NL@%
  15235. %@AB@%/******************************* Constants *********************************/%@AE@%%@NL@%
  15236. %@NL@%
  15237. %@AI@%#define %@AE@%BUF_SIZE 132 %@NL@%
  15238. %@NL@%
  15239. %@NL@%
  15240. %@AB@%/******************************** Globals **********************************/%@AE@%%@NL@%
  15241. %@NL@%
  15242. static CHAR   szSearch[BUF_SIZE] = { 0 };           // Current search string%@NL@%
  15243. static USHORT usLastIndex = 0;                      // Last Searched Item%@NL@%
  15244. %@NL@%
  15245. %@AB@%/******************************* Externals *********************************/%@AE@%%@NL@%
  15246. %@NL@%
  15247. extern USHORT        cAppNames;                     // see iniedit.c%@NL@%
  15248. extern HWND          hwndList;%@NL@%
  15249. extern PGROUPSTRUCT  pGroups;%@NL@%
  15250. extern HAB           habIniEdit;%@NL@%
  15251. extern HWND          FocusWindow;%@NL@%
  15252. %@NL@%
  15253. %@NL@%
  15254. %@AB@%/****************************** Function Header ****************************\%@NL@%
  15255. %@AB@%*%@NL@%
  15256. %@AB@%* SearchWndProc%@NL@%
  15257. %@AB@%*%@NL@%
  15258. %@AB@%*%@NL@%
  15259. %@AB@%* Handles the Search Dialog Box messages%@NL@%
  15260. %@AB@%*%@NL@%
  15261. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  15262. %@NL@%
  15263. MRESULT _loadds EXPENTRY SearchWndProc(HWND hwndDialog, USHORT msg,%@NL@%
  15264.         MPARAM mp1, MPARAM mp2)%@NL@%
  15265. {%@NL@%
  15266.     HWND   hwndText;                            // Current Text Window%@NL@%
  15267. %@NL@%
  15268. %@NL@%
  15269.     switch (msg)%@NL@%
  15270.         {%@NL@%
  15271. %@NL@%
  15272.         case WM_INITDLG:%@NL@%
  15273.             hwndText = WinWindowFromID( hwndDialog, IDDI_SEARCH_TEXT );%@NL@%
  15274.             WinSetWindowText(hwndText, szSearch);%@NL@%
  15275.             WinSendMsg( hwndText, EM_SETSEL,%@NL@%
  15276.                     MPFROM2SHORT(0, strlen(szSearch)), (MPARAM)0 );%@NL@%
  15277. %@NL@%
  15278.             break;%@NL@%
  15279. %@NL@%
  15280.         case WM_COMMAND:%@NL@%
  15281.             switch( LOUSHORT( mp1 ) )%@NL@%
  15282.                 {%@NL@%
  15283. %@NL@%
  15284.                 case IDDI_SEARCH_OK:%@NL@%
  15285.                     hwndText = WinWindowFromID( hwndDialog, IDDI_SEARCH_TEXT );%@NL@%
  15286.                     WinQueryWindowText( hwndText, BUF_SIZE, szSearch );%@NL@%
  15287.                     WinDismissDlg( hwndDialog, 0 );%@NL@%
  15288. %@NL@%
  15289.                     if( (usLastIndex = SHORT1FROMMR(WinSendMsg( hwndList, LM_SEARCHSTRING,%@NL@%
  15290.                             MPFROM2SHORT( LSS_SUBSTRING, LIT_FIRST),%@NL@%
  15291.                             MPFROMP( szSearch )) ) != LIT_NONE ))%@NL@%
  15292.                         {%@NL@%
  15293.                         WinSendMsg( hwndList, LM_SELECTITEM,%@NL@%
  15294.                                 MPFROM2SHORT( (usLastIndex), NULL),%@NL@%
  15295.                                 MPFROM2SHORT( TRUE, NULL ) );%@NL@%
  15296.                         }%@NL@%
  15297.                     else  %@AB@%/* not found */%@AE@%%@NL@%
  15298.                         {%@NL@%
  15299.                         usLastIndex = LIT_FIRST;%@NL@%
  15300.                         WinAlarm( HWND_DESKTOP, 0);%@NL@%
  15301.                         }%@NL@%
  15302.                     break;%@NL@%
  15303. %@NL@%
  15304.                 case IDDI_SEARCH_NEXT:%@NL@%
  15305.                     FindNext();%@NL@%
  15306.                     break;%@NL@%
  15307. %@NL@%
  15308.                 default:%@NL@%
  15309.                     return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15310.                     break;%@NL@%
  15311.                 }%@NL@%
  15312. %@NL@%
  15313.         default:%@NL@%
  15314.             return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15315.             break;%@NL@%
  15316.         }%@NL@%
  15317. %@NL@%
  15318.     return 0L;%@NL@%
  15319. %@NL@%
  15320. }  %@AB@%/* SearchWndProc */%@AE@%%@NL@%
  15321. %@NL@%
  15322. %@NL@%
  15323. %@AB@%/****************************** Function Header ****************************\%@NL@%
  15324. %@AB@%*%@NL@%
  15325. %@AB@%* FindNext%@NL@%
  15326. %@AB@%*%@NL@%
  15327. %@AB@%*%@NL@%
  15328. %@AB@%* Finds the next instance of the current search string starting from the%@NL@%
  15329. %@AB@%* Last searched position%@NL@%
  15330. %@AB@%*%@NL@%
  15331. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  15332. %@NL@%
  15333. VOID FindNext()%@NL@%
  15334. {%@NL@%
  15335.    if( (usLastIndex = SHORT1FROMMR(WinSendMsg( hwndList, LM_SEARCHSTRING,%@NL@%
  15336.            MPFROM2SHORT( LSS_SUBSTRING, usLastIndex),%@NL@%
  15337.            MPFROMP( szSearch )) ) != LIT_NONE ))%@NL@%
  15338.        {%@NL@%
  15339.        WinSendMsg( hwndList, LM_SELECTITEM,%@NL@%
  15340.                MPFROM2SHORT( (usLastIndex), NULL),%@NL@%
  15341.                MPFROM2SHORT( TRUE, NULL ) );%@NL@%
  15342.        }%@NL@%
  15343.    else   %@AB@%/* alarm if not found */%@AE@%%@NL@%
  15344.        WinAlarm( HWND_DESKTOP, 0);%@NL@%
  15345. %@NL@%
  15346. }  %@AB@%/* FindNext */%@AE@%%@NL@%
  15347. %@NL@%
  15348. %@NL@%
  15349. %@AB@%/****************************** Function Header ****************************\%@NL@%
  15350. %@AB@%*%@NL@%
  15351. %@AB@%* AddKeyWndProc%@NL@%
  15352. %@AB@%*%@NL@%
  15353. %@AB@%*%@NL@%
  15354. %@AB@%* Handles the AddKey Dialog Box messages%@NL@%
  15355. %@AB@%* Will facilitate adding new keys for a given App Name%@NL@%
  15356. %@AB@%*%@NL@%
  15357. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  15358. %@NL@%
  15359. MRESULT _loadds EXPENTRY AddKeyWndProc(HWND hwndDialog, USHORT msg,%@NL@%
  15360.         MPARAM mp1, MPARAM mp2)%@NL@%
  15361. {%@NL@%
  15362.     HWND   hwndTextApp;                         // Handle for App Text Window%@NL@%
  15363.     HWND   hwndTextKey;%@NL@%
  15364.     HWND   hwndTextValue;%@NL@%
  15365.     CHAR   szApp[BUF_SIZE];                     // String Contents%@NL@%
  15366.     CHAR   szKey[BUF_SIZE];%@NL@%
  15367.     CHAR   szValue[BUF_SIZE];%@NL@%
  15368. %@NL@%
  15369. %@NL@%
  15370.     switch (msg)%@NL@%
  15371.         {%@NL@%
  15372.         case WM_INITDLG:%@NL@%
  15373.             WinSendDlgItemMsg(hwndDialog, IDDI_ADD_KEY_TEXT_APP, EM_SETTEXTLIMIT,%@NL@%
  15374.                     MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15375.             WinSendDlgItemMsg(hwndDialog, IDDI_ADD_KEY_TEXT_KEY, EM_SETTEXTLIMIT,%@NL@%
  15376.                     MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15377.             WinSendDlgItemMsg(hwndDialog, IDDI_ADD_KEY_TEXT_VAL, EM_SETTEXTLIMIT,%@NL@%
  15378.                     MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15379.             break;%@NL@%
  15380.         case WM_COMMAND:%@NL@%
  15381.             switch( LOUSHORT( mp1 ) )%@NL@%
  15382.                 {%@NL@%
  15383. %@NL@%
  15384.                 case IDDI_ADD_KEY_OK:%@NL@%
  15385.                     hwndTextApp = WinWindowFromID( hwndDialog, IDDI_ADD_KEY_TEXT_APP );%@NL@%
  15386.                     WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );%@NL@%
  15387. %@NL@%
  15388.                     hwndTextKey = WinWindowFromID( hwndDialog, IDDI_ADD_KEY_TEXT_KEY );%@NL@%
  15389.                     WinQueryWindowText( hwndTextKey, BUF_SIZE, szKey );%@NL@%
  15390. %@NL@%
  15391.                     hwndTextValue = WinWindowFromID( hwndDialog, IDDI_ADD_KEY_TEXT_VAL );%@NL@%
  15392.                     WinQueryWindowText( hwndTextValue, BUF_SIZE, szValue );%@NL@%
  15393. %@NL@%
  15394.                     WinDismissDlg( hwndDialog, 0 );%@NL@%
  15395. %@NL@%
  15396.                     %@AB@%/* if the App is NULL forget it */%@AE@%%@NL@%
  15397.                     if( *szApp == (CHAR)0 )%@NL@%
  15398.                         {%@NL@%
  15399.                         break;%@NL@%
  15400.                         }%@NL@%
  15401. %@NL@%
  15402.                     %@AB@%/* if the Key is NULL forget it */%@AE@%%@NL@%
  15403.                     if( *szKey == (CHAR)0 )%@NL@%
  15404.                         {%@NL@%
  15405.                         break;%@NL@%
  15406.                         }%@NL@%
  15407. %@NL@%
  15408.                     %@AB@%/* if the Value is NULL forget it */%@AE@%%@NL@%
  15409.                     if( *szValue == (CHAR)0 )%@NL@%
  15410.                         {%@NL@%
  15411.                         break;%@NL@%
  15412.                         }%@NL@%
  15413. %@NL@%
  15414.                     if( !WinWriteProfileString( habIniEdit, szApp, szKey, szValue ) )%@NL@%
  15415.                         ;%@NL@%
  15416.                     break;%@NL@%
  15417. %@NL@%
  15418.                 default:%@NL@%
  15419.                     return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15420.                     break;%@NL@%
  15421.                 }%@NL@%
  15422. %@NL@%
  15423.         default:%@NL@%
  15424.             return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15425.             break;%@NL@%
  15426.         }%@NL@%
  15427. %@NL@%
  15428.     return 0L;%@NL@%
  15429. %@NL@%
  15430. }  %@AB@%/* AddKeyWndProc */%@AE@%%@NL@%
  15431. %@NL@%
  15432. %@NL@%
  15433. %@AB@%/****************************** Function Header ****************************\%@NL@%
  15434. %@AB@%*%@NL@%
  15435. %@AB@%* ChangeKeyWndProc%@NL@%
  15436. %@AB@%*%@NL@%
  15437. %@AB@%*%@NL@%
  15438. %@AB@%* Handles the ChangeKey Dialog Box messages%@NL@%
  15439. %@AB@%* Will facilitate changing a key's value given an app, key and new value%@NL@%
  15440. %@AB@%*%@NL@%
  15441. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  15442. %@NL@%
  15443. MRESULT _loadds EXPENTRY ChangeKeyWndProc(HWND hwndDialog, USHORT msg,%@NL@%
  15444.         MPARAM mp1, MPARAM mp2)%@NL@%
  15445. {%@NL@%
  15446.     HWND     hwndTextApp;                       // Handle for App Text Window%@NL@%
  15447.     HWND     hwndTextKey;%@NL@%
  15448.     HWND     hwndTextVal;%@NL@%
  15449.     CHAR     szApp[BUF_SIZE];                   // String Contents%@NL@%
  15450.     CHAR     szKey[BUF_SIZE];%@NL@%
  15451.     CHAR     szVal[BUF_SIZE];%@NL@%
  15452. %@NL@%
  15453. %@NL@%
  15454.     switch (msg)%@NL@%
  15455.         {%@NL@%
  15456.         case WM_INITDLG:%@NL@%
  15457.             if( FocusWindow )%@NL@%
  15458.                 {%@NL@%
  15459. %@NL@%
  15460.                 FocusWindow = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TEXT_VAL );%@NL@%
  15461.                 WinSetFocus( HWND_DESKTOP, FocusWindow);%@NL@%
  15462.                 WinQueryWindowText( FocusWindow, BUF_SIZE, szVal );%@NL@%
  15463. %@NL@%
  15464.                 FocusWindow = (HWND)NULL;%@NL@%
  15465. %@NL@%
  15466.                 return((MRESULT) TRUE );%@NL@%
  15467.                 } else {%@NL@%
  15468.                 WinSendDlgItemMsg(hwndDialog, IDDI_CHANGE_KEY_TEXT_APP, EM_SETTEXTLIMIT,%@NL@%
  15469.                         MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15470.                 WinSendDlgItemMsg(hwndDialog, IDDI_CHANGE_KEY_TEXT_KEY, EM_SETTEXTLIMIT,%@NL@%
  15471.                         MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15472.                 WinSendDlgItemMsg(hwndDialog, IDDI_CHANGE_KEY_TEXT_VAL, EM_SETTEXTLIMIT,%@NL@%
  15473.                         MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15474.                 }%@NL@%
  15475.             break;%@NL@%
  15476. %@NL@%
  15477.         case WM_COMMAND:%@NL@%
  15478.             switch( LOUSHORT( mp1 ) )%@NL@%
  15479.                 {%@NL@%
  15480. %@NL@%
  15481.                 case IDDI_CHANGE_KEY_OK:%@NL@%
  15482.                     hwndTextApp = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TEXT_APP );%@NL@%
  15483.                     WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );%@NL@%
  15484. %@NL@%
  15485.                     hwndTextKey = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TEXT_KEY );%@NL@%
  15486.                     WinQueryWindowText( hwndTextKey, BUF_SIZE, szKey );%@NL@%
  15487. %@NL@%
  15488.                     hwndTextVal = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TEXT_VAL );%@NL@%
  15489.                     WinQueryWindowText( hwndTextVal, BUF_SIZE, szVal );%@NL@%
  15490. %@NL@%
  15491. %@NL@%
  15492.                     WinDismissDlg( hwndDialog, IDDI_CHANGE_KEY_OK );%@NL@%
  15493. %@NL@%
  15494.                     %@AB@%/* if the App is NULL forget it */%@AE@%%@NL@%
  15495.                     if( *szApp == (CHAR)0 )%@NL@%
  15496.                         {%@NL@%
  15497.                         break;%@NL@%
  15498.                         }%@NL@%
  15499. %@NL@%
  15500.                     %@AB@%/* if the Key is NULL forget it */%@AE@%%@NL@%
  15501.                     if( *szKey == (CHAR)0 )%@NL@%
  15502.                         {%@NL@%
  15503.                         break;%@NL@%
  15504.                         }%@NL@%
  15505. %@NL@%
  15506.                     %@AB@%/* if the Value is NULL forget it */%@AE@%%@NL@%
  15507.                     if( *szVal == (CHAR)0 )%@NL@%
  15508.                         {%@NL@%
  15509.                         break;%@NL@%
  15510.                         }%@NL@%
  15511. %@NL@%
  15512. %@NL@%
  15513.                     if( !WinWriteProfileString( habIniEdit, szApp, szKey, szVal ) )%@NL@%
  15514. %@NL@%
  15515.                     break;%@NL@%
  15516. %@NL@%
  15517.                 default:%@NL@%
  15518.                     return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15519.                     break;%@NL@%
  15520.                 }%@NL@%
  15521. %@NL@%
  15522.         default:%@NL@%
  15523.             return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15524.             break;%@NL@%
  15525.         }%@NL@%
  15526. %@NL@%
  15527.     return 0L;%@NL@%
  15528. %@NL@%
  15529. }  %@AB@%/* ChangeKeyWndProc */%@AE@%%@NL@%
  15530. %@NL@%
  15531. %@NL@%
  15532. %@AB@%/****************************** Function Header ****************************\%@NL@%
  15533. %@AB@%*%@NL@%
  15534. %@AB@%* DelKeyWndProc%@NL@%
  15535. %@AB@%*%@NL@%
  15536. %@AB@%*%@NL@%
  15537. %@AB@%* Handles the DelKey Dialog Box messages%@NL@%
  15538. %@AB@%* Will facilitate deleting a key value given an app and the key%@NL@%
  15539. %@AB@%*%@NL@%
  15540. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  15541. %@NL@%
  15542. MRESULT _loadds EXPENTRY DelKeyWndProc(HWND hwndDialog, USHORT msg,%@NL@%
  15543.         MPARAM mp1, MPARAM mp2)%@NL@%
  15544. {%@NL@%
  15545.     HWND   hwndTextApp;                         // Handle for App Text Window%@NL@%
  15546.     HWND   hwndTextKey;%@NL@%
  15547.     CHAR   szApp[BUF_SIZE];                     // String Contents%@NL@%
  15548.     CHAR   szKey[BUF_SIZE];%@NL@%
  15549. %@NL@%
  15550. %@NL@%
  15551.     switch (msg)%@NL@%
  15552.         {%@NL@%
  15553.         case WM_INITDLG:%@NL@%
  15554.             WinSendDlgItemMsg(hwndDialog, IDDI_DEL_KEY_TEXT_APP, EM_SETTEXTLIMIT,%@NL@%
  15555.                     MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15556.             WinSendDlgItemMsg(hwndDialog, IDDI_DEL_KEY_TEXT_KEY, EM_SETTEXTLIMIT,%@NL@%
  15557.                     MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15558.             break;%@NL@%
  15559.         case WM_COMMAND:%@NL@%
  15560.             switch( LOUSHORT( mp1 ) )%@NL@%
  15561.                 {%@NL@%
  15562. %@NL@%
  15563.                 case IDDI_DEL_KEY_OK:%@NL@%
  15564.                     hwndTextApp = WinWindowFromID( hwndDialog, IDDI_DEL_KEY_TEXT_APP );%@NL@%
  15565.                     WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );%@NL@%
  15566. %@NL@%
  15567.                     hwndTextKey = WinWindowFromID( hwndDialog, IDDI_DEL_KEY_TEXT_KEY );%@NL@%
  15568.                     WinQueryWindowText( hwndTextKey, BUF_SIZE, szKey );%@NL@%
  15569. %@NL@%
  15570. %@NL@%
  15571.                     WinDismissDlg( hwndDialog, 0 );%@NL@%
  15572. %@NL@%
  15573.                     %@AB@%/* if the App is NULL forget it */%@AE@%%@NL@%
  15574.                     if( *szApp == (CHAR)0 )%@NL@%
  15575.                         {%@NL@%
  15576.                         break;%@NL@%
  15577.                         }%@NL@%
  15578. %@NL@%
  15579.                     %@AB@%/* if the Key is NULL forget it */%@AE@%%@NL@%
  15580.                     if( *szKey == (CHAR)0 )%@NL@%
  15581.                         {%@NL@%
  15582.                         break;%@NL@%
  15583.                         }%@NL@%
  15584. %@NL@%
  15585. %@NL@%
  15586.                     if( !WinWriteProfileString( habIniEdit, szApp, szKey, (PCHAR)NULL ) )%@NL@%
  15587.                         ;%@NL@%
  15588.                     break;%@NL@%
  15589. %@NL@%
  15590.                 default:%@NL@%
  15591.                     return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15592.                     break;%@NL@%
  15593.                 }%@NL@%
  15594. %@NL@%
  15595.         default:%@NL@%
  15596.             return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15597.             break;%@NL@%
  15598.         }%@NL@%
  15599. %@NL@%
  15600.     return 0L;%@NL@%
  15601. %@NL@%
  15602. }  %@AB@%/* DelKeyProc */%@AE@%%@NL@%
  15603. %@NL@%
  15604. %@NL@%
  15605. %@AB@%/****************************** Function Header ****************************\%@NL@%
  15606. %@AB@%*%@NL@%
  15607. %@AB@%* DelAppWndProc%@NL@%
  15608. %@AB@%*%@NL@%
  15609. %@AB@%*%@NL@%
  15610. %@AB@%* Handles the DelApp Dialog Box messages%@NL@%
  15611. %@AB@%* Will facilitate deleting all keys from a given app name%@NL@%
  15612. %@AB@%*%@NL@%
  15613. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  15614. %@NL@%
  15615. MRESULT _loadds EXPENTRY DelAppWndProc(HWND hwndDialog, USHORT msg,%@NL@%
  15616.         MPARAM mp1, MPARAM mp2)%@NL@%
  15617. {%@NL@%
  15618.     HWND   hwndTextApp;                         // App Name Window%@NL@%
  15619.     CHAR   szApp[BUF_SIZE];                     // String Contents of Window%@NL@%
  15620. %@NL@%
  15621. %@NL@%
  15622.     switch (msg)%@NL@%
  15623.         {%@NL@%
  15624.         case WM_INITDLG:%@NL@%
  15625.             WinSendDlgItemMsg(hwndDialog, IDDI_DEL_APP_TEXT_APP, EM_SETTEXTLIMIT,%@NL@%
  15626.                     MPFROMSHORT(MAX_STRING_LEN), 0L);%@NL@%
  15627.             break;%@NL@%
  15628. %@NL@%
  15629.         case WM_COMMAND:%@NL@%
  15630.             switch( LOUSHORT( mp1 ) )%@NL@%
  15631.                 {%@NL@%
  15632. %@NL@%
  15633.                 case IDDI_DEL_APP_OK:%@NL@%
  15634.                     hwndTextApp = WinWindowFromID( hwndDialog, IDDI_DEL_APP_TEXT_APP );%@NL@%
  15635.                     WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );%@NL@%
  15636. %@NL@%
  15637.                     WinDismissDlg( hwndDialog, 0 );%@NL@%
  15638. %@NL@%
  15639.                     %@AB@%/* if the App is NULL forget it */%@AE@%%@NL@%
  15640.                     if( *szApp == (CHAR)0 )%@NL@%
  15641.                         {%@NL@%
  15642.                         break;%@NL@%
  15643.                         }%@NL@%
  15644. %@NL@%
  15645.                     if( !WinWriteProfileString( habIniEdit, szApp, (PCHAR)NULL, (PCHAR)NULL ) )%@NL@%
  15646.                         ;%@NL@%
  15647. %@NL@%
  15648.                     break;%@NL@%
  15649. %@NL@%
  15650.                 default:%@NL@%
  15651.                     return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15652.                     break;%@NL@%
  15653.                 }%@NL@%
  15654. %@NL@%
  15655.         default:%@NL@%
  15656.             return WinDefDlgProc(hwndDialog, msg, mp1, mp2);%@NL@%
  15657.             break;%@NL@%
  15658.         }%@NL@%
  15659. %@NL@%
  15660.     return 0L;%@NL@%
  15661. %@NL@%
  15662. }  %@AB@%/* DelAppWndProc */%@AE@%%@NL@%
  15663. %@NL@%
  15664. %@NL@%
  15665. %@2@%%@AH@%DLGSAMP.C%@AE@%%@EH@%%@NL@%
  15666. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DLGSAMP\DLGSAMP.C%@AE@%%@NL@%
  15667. %@NL@%
  15668. %@AB@%/*%@NL@%
  15669. %@AB@%    DLGSAMP -- Dialog Box Sample Application%@NL@%
  15670. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  15671. %@AB@%*/%@AE@%%@NL@%
  15672.  %@NL@%
  15673. %@AI@%#define %@AE@%INCL_WINBUTTONS %@NL@%
  15674. %@AI@%#define %@AE@%INCL_WINDIALOGS %@NL@%
  15675. %@AI@%#define %@AE@%INCL_WINERRORS %@NL@%
  15676. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  15677. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  15678. %@AI@%#define %@AE@%INCL_WINLISTBOXES %@NL@%
  15679. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  15680. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  15681. %@AI@%#define %@AE@%INCL_WINRECTANGLES %@NL@%
  15682. %@AI@%#define %@AE@%INCL_WINSWITCHLIST %@NL@%
  15683. %@AI@%#define %@AE@%INCL_WINSYS %@NL@%
  15684. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  15685. %@AI@%#define %@AE@%M_I86L %@NL@%
  15686. %@AI@%#include %@AE@%<os2.h> %@NL@%
  15687.  %@NL@%
  15688. %@AI@%#include %@AE@%<string.h> %@NL@%
  15689. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  15690.  %@NL@%
  15691. %@AI@%#include %@AE@%"dlgsamp.h" %@NL@%
  15692. %@AI@%#include %@AE@%"dlgsamp1.h" %@NL@%
  15693.  %@NL@%
  15694. %@AB@%/*%@NL@%
  15695. %@AB@%    Function Prototypes%@NL@%
  15696. %@AB@%*/%@AE@%%@NL@%
  15697.  %@NL@%
  15698. VOID NEAR cdecl main(VOID);%@NL@%
  15699. %@NL@%
  15700. %@AB@%/* Local Routines */%@AE@%%@NL@%
  15701. VOID cdecl CenterDlgBox(HWND);%@NL@%
  15702. VOID cdecl CheckColor(HWND, SHORT, COLOR *);%@NL@%
  15703. VOID cdecl EnableModality(HWND, BOOL);%@NL@%
  15704. BOOL cdecl IsIntInRange(HWND, SHORT, SHORT, SHORT, SHORT, SHORT);%@NL@%
  15705. VOID cdecl LoadDialog(HWND, HWND, SHORT, PFNWP, BOOL);%@NL@%
  15706. VOID cdecl MainWndCommand(HWND, USHORT, BOOL *);%@NL@%
  15707. VOID cdecl MainWndPaint(HWND);%@NL@%
  15708. VOID cdecl SetModality(HWND, BOOL);%@NL@%
  15709. VOID cdecl Trace(PSZ, PSZ);%@NL@%
  15710.  %@NL@%
  15711. %@AB@%/* Window Procedures */%@AE@%%@NL@%
  15712. MRESULT EXPENTRY fnwpMainWnd(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  15713. MRESULT EXPENTRY fnwpEntryFieldDlg(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  15714. MRESULT EXPENTRY fnwpAutoRadioButtonDlg(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  15715. MRESULT EXPENTRY fnwpCheckBoxDlg(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  15716. MRESULT EXPENTRY fnwpListBoxDlg(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  15717. MRESULT EXPENTRY fnwpAboutBoxDlg(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  15718.  %@NL@%
  15719. %@AB@%/*%@NL@%
  15720. %@AB@%    Global variables%@NL@%
  15721. %@AB@%*/%@AE@%%@NL@%
  15722. COLOR colorClient = CLR_RED | CLR_BLUE;    %@AB@%/* Color of client area    */%@AE@%%@NL@%
  15723.  %@NL@%
  15724. CHAR  szEntryField1[10] = "";              %@AB@%/* Used to pass back info  */%@AE@%%@NL@%
  15725. CHAR  szEntryField2[10] = "";              %@AB@%/* from entry fields       */%@AE@%%@NL@%
  15726.                                            %@AB@%/* in EntryFieldDlg        */%@AE@%%@NL@%
  15727.  %@NL@%
  15728. BOOL  bModality = TRUE;                    %@AB@%/* Does the user want modal*/%@AE@%%@NL@%
  15729.                                            %@AB@%/* or modeless dialogs?    */%@AE@%%@NL@%
  15730. COLOR colorSave;%@NL@%
  15731. CHAR  szSelection[LEN_LISTBOXENTRY] = "";  %@AB@%/* Used to pass back       */%@AE@%%@NL@%
  15732.                                            %@AB@%/* list box item selected  */%@AE@%%@NL@%
  15733.                                            %@AB@%/* in ListBoxDlg           */%@AE@%%@NL@%
  15734.  %@NL@%
  15735. HAB   hab;                                 %@AB@%/* Anchor block handle     */%@AE@%%@NL@%
  15736. HWND  hwndClient;                          %@AB@%/* Client Window handle    */%@AE@%%@NL@%
  15737. HWND  hwndFrame;                           %@AB@%/* Frame Window handle     */%@AE@%%@NL@%
  15738. HWND  hwndModelessDlg;                     %@AB@%/* Modeless Dialog handle  */%@AE@%%@NL@%
  15739.  %@NL@%
  15740. %@AB@%/**************************************************************************%@NL@%
  15741. %@AB@%*%@NL@%
  15742. %@AB@%*   FUNCTION: main%@NL@%
  15743. %@AB@%*%@NL@%
  15744. %@AB@%*   Typical PM main function which initializes PM, creates a message queue,%@NL@%
  15745. %@AB@%*   registers a window class, creates a window, gets and dispatches%@NL@%
  15746. %@AB@%*   messages to its winproc until its time to quit, and then tidies up%@NL@%
  15747. %@AB@%*   before terminating.%@NL@%
  15748. %@AB@%*%@NL@%
  15749. %@AB@%**************************************************************************/%@AE@%%@NL@%
  15750.  %@NL@%
  15751. VOID NEAR cdecl main(  )%@NL@%
  15752. {%@NL@%
  15753.   HMQ     hmq;                        %@AB@%/* Message Queue handle         */%@AE@%%@NL@%
  15754.   QMSG    qmsg;                       %@AB@%/* Message                      */%@AE@%%@NL@%
  15755.   ULONG   flCreate;%@NL@%
  15756.  %@NL@%
  15757.   hab   = WinInitialize( 0 );         %@AB@%/* Initialize PM                */%@AE@%%@NL@%
  15758.   hmq   = WinCreateMsgQueue( hab, 0 );%@AB@%/* Create application msg queue */%@AE@%%@NL@%
  15759.  %@NL@%
  15760.   WinRegisterClass(                   %@AB@%/* Register Window Class        */%@AE@%%@NL@%
  15761.       hab,                            %@AB@%/* Anchor block handle          */%@AE@%%@NL@%
  15762.       "DlgSamp Class",                %@AB@%/* Window Class name            */%@AE@%%@NL@%
  15763.       fnwpMainWnd,                    %@AB@%/* Address of Window Procedure  */%@AE@%%@NL@%
  15764.       (ULONG) NULL,                   %@AB@%/* No special class style       */%@AE@%%@NL@%
  15765.       0                               %@AB@%/* No extra window words        */%@AE@%%@NL@%
  15766.       );%@NL@%
  15767.  %@NL@%
  15768.   flCreate = FCF_STANDARD & ~FCF_ACCELTABLE;%@NL@%
  15769.  %@NL@%
  15770.   hwndFrame = WinCreateStdWindow(%@NL@%
  15771.         HWND_DESKTOP,                   %@AB@%/* Desktop Window is parent     */%@AE@%%@NL@%
  15772.         WS_VISIBLE,                     %@AB@%/* Window styles                */%@AE@%%@NL@%
  15773.         (PVOID)&flCreate,               %@AB@%/* Window creation parameters   */%@AE@%%@NL@%
  15774.         "DlgSamp Class",                %@AB@%/* Window Class name            */%@AE@%%@NL@%
  15775.         "",                             %@AB@%/* Window Text                  */%@AE@%%@NL@%
  15776.         0L,                             %@AB@%/* Client style                 */%@AE@%%@NL@%
  15777.         (HMODULE) NULL,                 %@AB@%/* Module handle                */%@AE@%%@NL@%
  15778.         ID_MAINWND,                     %@AB@%/* Window ID                    */%@AE@%%@NL@%
  15779.         (HWND FAR *)&hwndClient         %@AB@%/* Client Window handle         */%@AE@%%@NL@%
  15780.         );%@NL@%
  15781.  %@NL@%
  15782.  %@NL@%
  15783.   %@AB@%/* Message Loop */%@AE@%%@NL@%
  15784.   while( WinGetMsg( hab, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )%@NL@%
  15785.     WinDispatchMsg( hab, (PQMSG)&qmsg );%@NL@%
  15786.  %@NL@%
  15787.   %@AB@%/* Cleanup code */%@AE@%%@NL@%
  15788.   WinDestroyWindow( hwndFrame );%@NL@%
  15789.   WinDestroyMsgQueue( hmq );%@NL@%
  15790.   WinTerminate( hab );%@NL@%
  15791. }%@NL@%
  15792.  %@NL@%
  15793. %@AB@%/***********************************************************************%@NL@%
  15794. %@AB@%*%@NL@%
  15795. %@AB@%*   WinProc: fnwpMainWnd%@NL@%
  15796. %@AB@%*%@NL@%
  15797. %@AB@%*   Controls the state of the menu, and loads various dialogs.  The%@NL@%
  15798. %@AB@%*   dialogs will be modal or modeless depending on the setting of the%@NL@%
  15799. %@AB@%*   Modality menuitem.%@NL@%
  15800. %@AB@%*%@NL@%
  15801. %@AB@%***********************************************************************/%@AE@%%@NL@%
  15802.  %@NL@%
  15803. MRESULT  EXPENTRY fnwpMainWnd( hwnd, message, mp1, mp2 )%@NL@%
  15804. HWND    hwnd;%@NL@%
  15805. USHORT  message;%@NL@%
  15806. MPARAM  mp1;%@NL@%
  15807. MPARAM  mp2;%@NL@%
  15808. {%@NL@%
  15809.   USHORT   Command;   %@AB@%/* Command passed by WM_COMMAND */%@AE@%%@NL@%
  15810.   SHORT    id;        %@AB@%/* ID of item selected from the list box */%@AE@%%@NL@%
  15811.  %@NL@%
  15812.   switch(message)%@NL@%
  15813.   {%@NL@%
  15814.     case WM_PAINT:%@NL@%
  15815.       MainWndPaint( hwnd );  %@AB@%/* Invoke window painting routine */%@AE@%%@NL@%
  15816.       break;%@NL@%
  15817.     case WM_HELP:%@NL@%
  15818. %@AB@%/*********************************************************************%@NL@%
  15819. %@AB@%*%@NL@%
  15820. %@AB@%*   This will be received when either:-%@NL@%
  15821. %@AB@%*%@NL@%
  15822. %@AB@%*   1. The user hits the F1 key%@NL@%
  15823. %@AB@%*   2. The user clicks on the action bar item F1=Help%@NL@%
  15824. %@AB@%*%@NL@%
  15825. %@AB@%*********************************************************************/%@AE@%%@NL@%
  15826.       WinMessageBox( HWND_DESKTOP,%@NL@%
  15827.                      hwndFrame,%@NL@%
  15828.                      (PSZ)"Dialog Sample Application: Help",%@NL@%
  15829.                      (PSZ)"Try out the pulldown menus, or Alt+selection",%@NL@%
  15830.                      ID_MB,%@NL@%
  15831.                      MB_OK );%@NL@%
  15832.       break;%@NL@%
  15833.     case WM_COMMAND:%@NL@%
  15834.       Command = SHORT1FROMMP( mp1 );%@NL@%
  15835.       MainWndCommand( hwnd, Command, &bModality );%@NL@%
  15836.       break;%@NL@%
  15837.     case DLGSAMP_EFCOMPLETE:%@NL@%
  15838.       WinQueryWindowText( WinWindowFromID( hwndModelessDlg, EF_1 ),%@NL@%
  15839.                           sizeof( szEntryField1 ), szEntryField1 );%@NL@%
  15840.       WinQueryWindowText( WinWindowFromID( hwndModelessDlg, EF_2 ),%@NL@%
  15841.                           sizeof( szEntryField2 ), szEntryField2 );%@NL@%
  15842.       WinInvalidateRect( hwnd, NULL, FALSE );%@AB@%/* Request whole window repaint */%@AE@%%@NL@%
  15843.       break;%@NL@%
  15844.     case DLGSAMP_LBCOMPLETE:%@NL@%
  15845.       id = SHORT1FROMMR( WinSendDlgItemMsg( hwndModelessDlg,%@NL@%
  15846.                                             LB_1,%@NL@%
  15847.                                             LM_QUERYSELECTION,%@NL@%
  15848.                                             0L,%@NL@%
  15849.                                             0L ) );%@NL@%
  15850.       if( id == LIT_NONE )%@NL@%
  15851.         strcpy( szSelection, "" );%@NL@%
  15852.       else%@NL@%
  15853.         WinSendDlgItemMsg( hwndModelessDlg,%@NL@%
  15854.                            LB_1,%@NL@%
  15855.                            LM_QUERYITEMTEXT,%@NL@%
  15856.                            MPFROM2SHORT( id, sizeof( szSelection ) ),%@NL@%
  15857.                            MPFROMP( szSelection ) );%@NL@%
  15858.       break;%@NL@%
  15859.     case DLGSAMP_RBCOMPLETE:%@NL@%
  15860.     case DLGSAMP_CBCOMPLETE:%@NL@%
  15861.       break;%@NL@%
  15862.     case DLGSAMP_DESTROYDLG:%@NL@%
  15863.       WinDestroyWindow( hwndModelessDlg );%@NL@%
  15864.       EnableModality( hwndFrame, TRUE );%@NL@%
  15865.       WinInvalidateRect( hwnd, NULL, FALSE );%@AB@%/* Request whole window repaint */%@AE@%%@NL@%
  15866.       break;%@NL@%
  15867.     case WM_CLOSE:%@NL@%
  15868.       WinPostMsg( hwnd, WM_QUIT, 0L, 0L );  %@AB@%/* Cause termination    */%@AE@%%@NL@%
  15869.       break;%@NL@%
  15870.     default:%@NL@%
  15871.       return WinDefWindowProc( hwnd, message, mp1, mp2 );%@NL@%
  15872.   }%@NL@%
  15873.   return FALSE;%@NL@%
  15874. }%@NL@%
  15875.  %@NL@%
  15876. %@AB@%/***********************************************************************%@NL@%
  15877. %@AB@%*%@NL@%
  15878. %@AB@%*  DlgProc:  fnwpEntryFieldDlg%@NL@%
  15879. %@AB@%*%@NL@%
  15880. %@AB@%*  A dialog proc which captures and validates the contents of two%@NL@%
  15881. %@AB@%*  entry fields.%@NL@%
  15882. %@AB@%*%@NL@%
  15883. %@AB@%***********************************************************************/%@AE@%%@NL@%
  15884.  %@NL@%
  15885. MRESULT EXPENTRY fnwpEntryFieldDlg( hwndDlg, message, mp1, mp2 )%@NL@%
  15886. HWND    hwndDlg;%@NL@%
  15887. USHORT  message;%@NL@%
  15888. MPARAM  mp1;%@NL@%
  15889. MPARAM  mp2;%@NL@%
  15890. {%@NL@%
  15891.   switch (message)%@NL@%
  15892.   {%@NL@%
  15893.     case WM_INITDLG:%@NL@%
  15894.       CenterDlgBox( hwndDlg );%@NL@%
  15895.       break;%@NL@%
  15896.     case WM_COMMAND:%@NL@%
  15897.       switch( SHORT1FROMMP( mp1 ) )%@NL@%
  15898.       {%@NL@%
  15899.         case DID_OK: %@AB@%/* Enter key or pushbutton pressed/ selected */%@AE@%%@NL@%
  15900.  %@NL@%
  15901. %@AB@%/***************************************************************************%@NL@%
  15902. %@AB@%*%@NL@%
  15903. %@AB@%*   Validate the contents of the two entry fields%@NL@%
  15904. %@AB@%*%@NL@%
  15905. %@AB@%***************************************************************************/%@AE@%%@NL@%
  15906.  %@NL@%
  15907.           if( !IsIntInRange( hwndDlg, EF_1, 1, 100, ERR_EFINVALID, ID_MB ) )%@NL@%
  15908.             return FALSE;%@NL@%
  15909.           if( !IsIntInRange( hwndDlg, EF_2, 1, 100, ERR_EFINVALID, ID_MB ) )%@NL@%
  15910.             return FALSE;%@NL@%
  15911.  %@NL@%
  15912. %@AB@%/***************************************************************************%@NL@%
  15913. %@AB@%*%@NL@%
  15914. %@AB@%*   A modal dialog is destroyed before control is returned to the%@NL@%
  15915. %@AB@%*   invoking winproc, so it must pass the contents of its Entry Fields etc.%@NL@%
  15916. %@AB@%*   back to the invoking window before it returns.%@NL@%
  15917. %@AB@%*%@NL@%
  15918. %@AB@%*   When a modeless dialog box returns it still continues to exist. It%@NL@%
  15919. %@AB@%*   could pass the contents of its Entry Fields etc. back to the%@NL@%
  15920. %@AB@%*   invoking window in several ways.%@NL@%
  15921. %@AB@%*%@NL@%
  15922. %@AB@%*   Here a user message is posted to the invoking window to say that the%@NL@%
  15923. %@AB@%*   dialog has completed. The invoking window then has an opportunity%@NL@%
  15924. %@AB@%*   to extract the contents of the Entry Fields etc.%@NL@%
  15925. %@AB@%*%@NL@%
  15926. %@AB@%***************************************************************************/%@AE@%%@NL@%
  15927.  %@NL@%
  15928.           if( bModality )%@NL@%
  15929.           {%@NL@%
  15930.             WinQueryWindowText( WinWindowFromID( hwndDlg, EF_1 ),%@NL@%
  15931.                                 sizeof( szEntryField1),%@NL@%
  15932.                                 szEntryField1 );%@NL@%
  15933.             WinQueryWindowText( WinWindowFromID( hwndDlg, EF_2 ),%@NL@%
  15934.                                 sizeof( szEntryField2),%@NL@%
  15935.                                 szEntryField2 );%@NL@%
  15936.           }%@NL@%
  15937.           else%@NL@%
  15938.             WinPostMsg( hwndClient, DLGSAMP_EFCOMPLETE, 0L, 0L );%@NL@%
  15939.  %@NL@%
  15940.         case DID_CANCEL:%@AB@%/* Escape key or CANCEL pushbutton pressed/selected */%@AE@%%@NL@%
  15941.           if( bModality )%@NL@%
  15942.             WinDismissDlg( hwndDlg,TRUE );%@NL@%
  15943.           else%@NL@%
  15944.             WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );%@NL@%
  15945.           return FALSE;%@NL@%
  15946.         default:%@NL@%
  15947.           break;%@NL@%
  15948.       }%@NL@%
  15949.       break;%@NL@%
  15950.  %@NL@%
  15951.     default:  %@AB@%/* Pass all other messages to the default dialog proc */%@AE@%%@NL@%
  15952.       return WinDefDlgProc( hwndDlg, message, mp1, mp2 );%@NL@%
  15953.   }%@NL@%
  15954.   return FALSE;%@NL@%
  15955. }%@NL@%
  15956.  %@NL@%
  15957. %@AB@%/***********************************************************************%@NL@%
  15958. %@AB@%*%@NL@%
  15959. %@AB@%*  DlgProc:  fnwpAutoRadioButtonDlg%@NL@%
  15960. %@AB@%*%@NL@%
  15961. %@AB@%*  A dialog procedure which uses auto radio buttons to change the%@NL@%
  15962. %@AB@%*  color of the Client Area window.%@NL@%
  15963. %@AB@%*%@NL@%
  15964. %@AB@%***********************************************************************/%@AE@%%@NL@%
  15965.  %@NL@%
  15966. MRESULT EXPENTRY fnwpAutoRadioButtonDlg( hwndDlg, message, mp1, mp2 )%@NL@%
  15967. HWND    hwndDlg;%@NL@%
  15968. USHORT  message;%@NL@%
  15969. MPARAM  mp1;%@NL@%
  15970. MPARAM  mp2;%@NL@%
  15971. {%@NL@%
  15972.   switch (message)%@NL@%
  15973.   {%@NL@%
  15974.     case WM_INITDLG:%@NL@%
  15975.       colorSave = colorClient;%@NL@%
  15976.       CenterDlgBox( hwndDlg );%@NL@%
  15977.       if ( colorClient == CLR_RED )%@NL@%
  15978.         WinPostMsg( WinWindowFromID( hwndDlg, RB_RED ),%@NL@%
  15979.                     BM_SETCHECK,%@NL@%
  15980.                     MPFROM2SHORT( TRUE, 0 ),%@NL@%
  15981.                     0L );%@NL@%
  15982. %@NL@%
  15983.       if ( colorClient == CLR_GREEN )%@NL@%
  15984.         WinPostMsg( WinWindowFromID( hwndDlg, RB_GREEN ),%@NL@%
  15985.                     BM_SETCHECK,%@NL@%
  15986.                     MPFROM2SHORT( TRUE, 0 ),%@NL@%
  15987.                     0L );%@NL@%
  15988. %@NL@%
  15989.       if ( colorClient == CLR_BLUE )%@NL@%
  15990.         WinPostMsg( WinWindowFromID( hwndDlg, RB_BLUE ),%@NL@%
  15991.                     BM_SETCHECK,%@NL@%
  15992.                     MPFROM2SHORT( TRUE, 0 ),%@NL@%
  15993.                     0L );%@NL@%
  15994. %@NL@%
  15995.       break;%@NL@%
  15996.     case WM_CONTROL:%@NL@%
  15997.       if( SHORT2FROMMP( mp1 ) == BN_CLICKED )%@NL@%
  15998.         switch( SHORT1FROMMP( mp1 ) )%@NL@%
  15999.         {%@NL@%
  16000.           case RB_RED:%@NL@%
  16001.             colorClient = CLR_RED;%@NL@%
  16002.             break;%@NL@%
  16003.           case RB_GREEN:%@NL@%
  16004.             colorClient = CLR_GREEN;%@NL@%
  16005.             break;%@NL@%
  16006.           case RB_BLUE:%@NL@%
  16007.             colorClient = CLR_BLUE;%@NL@%
  16008.             break;%@NL@%
  16009.           default:%@NL@%
  16010.            return FALSE;%@NL@%
  16011.         }%@NL@%
  16012.         WinInvalidateRect( hwndClient, NULL, FALSE );%@NL@%
  16013.         break;%@NL@%
  16014.     case WM_COMMAND:%@NL@%
  16015.       switch( SHORT1FROMMP( mp1 ) )%@NL@%
  16016.       {%@NL@%
  16017.         case DID_OK:     %@AB@%/* Enter key or pushbutton pressed/ selected        */%@AE@%%@NL@%
  16018.           if( !bModality )%@NL@%
  16019.             WinPostMsg( hwndClient, DLGSAMP_RBCOMPLETE, 0L, 0L );%@NL@%
  16020.           break;%@NL@%
  16021.         case DID_CANCEL: %@AB@%/* Escape key or CANCEL pushbutton pressed/selected */%@AE@%%@NL@%
  16022.           colorClient = colorSave;%@NL@%
  16023.           break;%@NL@%
  16024.         default:%@NL@%
  16025.           return WinDefDlgProc( hwndDlg, message, mp1, mp2 );%@NL@%
  16026.       }%@NL@%
  16027.       if( bModality )%@NL@%
  16028.         WinDismissDlg( hwndDlg, TRUE );%@NL@%
  16029.       else%@NL@%
  16030.         WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );%@NL@%
  16031.       break;%@NL@%
  16032.  %@NL@%
  16033.     default:  %@AB@%/* Pass all other messages to the default dialog proc */%@AE@%%@NL@%
  16034.       return WinDefDlgProc( hwndDlg, message, mp1, mp2 );%@NL@%
  16035.   }%@NL@%
  16036.   return FALSE;%@NL@%
  16037. }%@NL@%
  16038.  %@NL@%
  16039.  %@NL@%
  16040. %@AB@%/***********************************************************************%@NL@%
  16041. %@AB@%*%@NL@%
  16042. %@AB@%*  DlgProc:  fnwpCheckBoxDlg%@NL@%
  16043. %@AB@%*%@NL@%
  16044. %@AB@%*  A dialog procedure to which use checkboxes to change the color%@NL@%
  16045. %@AB@%*  of the Client Area Window.%@NL@%
  16046. %@AB@%*%@NL@%
  16047. %@AB@%***********************************************************************/%@AE@%%@NL@%
  16048.  %@NL@%
  16049. MRESULT EXPENTRY fnwpCheckBoxDlg( hwndDlg, message, mp1, mp2 )%@NL@%
  16050. HWND    hwndDlg;%@NL@%
  16051. USHORT  message;%@NL@%
  16052. MPARAM  mp1;%@NL@%
  16053. MPARAM  mp2;%@NL@%
  16054. {%@NL@%
  16055.   switch (message)%@NL@%
  16056.   {%@NL@%
  16057.     case WM_INITDLG:%@NL@%
  16058.       CenterDlgBox( hwndDlg );%@NL@%
  16059.       colorSave = colorClient;%@NL@%
  16060.       if( (colorClient & CLR_RED) == CLR_RED )%@NL@%
  16061.         WinPostMsg( WinWindowFromID( hwndDlg, CB_RED ),%@NL@%
  16062.                     BM_SETCHECK,%@NL@%
  16063.                     MPFROM2SHORT( TRUE,0 ),%@NL@%
  16064.                     0L );%@NL@%
  16065.       if( (colorClient & CLR_GREEN) == CLR_GREEN )%@NL@%
  16066.         WinPostMsg( WinWindowFromID( hwndDlg, CB_GREEN ),%@NL@%
  16067.                     BM_SETCHECK,%@NL@%
  16068.                     MPFROM2SHORT( TRUE,0 ),%@NL@%
  16069.                     0L );%@NL@%
  16070.       if( (colorClient & CLR_BLUE) == CLR_BLUE )%@NL@%
  16071.         WinPostMsg( WinWindowFromID( hwndDlg, CB_BLUE ),%@NL@%
  16072.                     BM_SETCHECK,%@NL@%
  16073.                     MPFROM2SHORT( TRUE,0 ),%@NL@%
  16074.                     0L );%@NL@%
  16075.       break;%@NL@%
  16076.     case WM_CONTROL:                  %@AB@%/* User has clicked on a checkbox */%@AE@%%@NL@%
  16077.       if( SHORT2FROMMP( mp1 ) == BN_CLICKED )%@NL@%
  16078.         CheckColor( hwndDlg, SHORT1FROMMP( mp1 ), &colorClient );%@NL@%
  16079.       WinInvalidateRect( hwndClient, NULL, FALSE );%@NL@%
  16080.       break;%@NL@%
  16081.     case WM_COMMAND:%@NL@%
  16082.       switch( SHORT1FROMMP( mp1 ) )%@NL@%
  16083.       {%@NL@%
  16084.         case DID_OK:     %@AB@%/* Enter key or pushbutton pressed/ selected */%@AE@%%@NL@%
  16085.           if( !bModality )%@NL@%
  16086.             WinPostMsg( hwndClient, DLGSAMP_CBCOMPLETE, 0L, 0L );%@NL@%
  16087.           break;%@NL@%
  16088.         case DID_CANCEL: %@AB@%/* Escape key or CANCEL pushbutton pressed/selected */%@AE@%%@NL@%
  16089.           colorClient = colorSave;%@NL@%
  16090.           break;%@NL@%
  16091.         default:%@NL@%
  16092.           return WinDefDlgProc( hwndDlg, message, mp1, mp2 );%@NL@%
  16093.       }%@NL@%
  16094.       if( bModality )%@NL@%
  16095.         WinDismissDlg( hwndDlg, TRUE );%@NL@%
  16096.       else%@NL@%
  16097.         WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );%@NL@%
  16098.       return FALSE;%@NL@%
  16099.  %@NL@%
  16100.     default:  %@AB@%/* Pass all other messages to the default dialog proc */%@AE@%%@NL@%
  16101.       return WinDefDlgProc( hwndDlg, message, mp1, mp2 );%@NL@%
  16102.   }%@NL@%
  16103.   return FALSE;%@NL@%
  16104. }%@NL@%
  16105.  %@NL@%
  16106. %@AB@%/***********************************************************************%@NL@%
  16107. %@AB@%*%@NL@%
  16108. %@AB@%*  DlgProc:  fnwpListBoxDlg%@NL@%
  16109. %@AB@%*%@NL@%
  16110. %@AB@%***********************************************************************/%@AE@%%@NL@%
  16111.  %@NL@%
  16112. MRESULT EXPENTRY fnwpListBoxDlg( hwndDlg, message, mp1, mp2 )%@NL@%
  16113. HWND    hwndDlg;%@NL@%
  16114. USHORT  message;%@NL@%
  16115. MPARAM  mp1;%@NL@%
  16116. MPARAM  mp2;%@NL@%
  16117. {%@NL@%
  16118.   CHAR szBuffer[LEN_LISTBOXENTRY];%@NL@%
  16119.   SHORT  i;%@NL@%
  16120.   SHORT  id;%@NL@%
  16121.  %@NL@%
  16122.   switch (message)%@NL@%
  16123.   {%@NL@%
  16124.     case WM_INITDLG:%@NL@%
  16125.       CenterDlgBox( hwndDlg );%@NL@%
  16126.  %@NL@%
  16127. %@AB@%/*************************************************************************%@NL@%
  16128. %@AB@%*%@NL@%
  16129. %@AB@%*   Initialize the listbox with a set of strings loaded from a%@NL@%
  16130. %@AB@%*   resource file.%@NL@%
  16131. %@AB@%*%@NL@%
  16132. %@AB@%*************************************************************************/%@AE@%%@NL@%
  16133.  %@NL@%
  16134.       for ( i = 0; i < NUM_LISTBOXENTRIES; i++ )%@NL@%
  16135.       {%@NL@%
  16136.         WinLoadString( hab,%@NL@%
  16137.                        (HMODULE) NULL,%@NL@%
  16138.                        LBI_1 + i,%@NL@%
  16139.                        LEN_LISTBOXENTRY,%@NL@%
  16140.                        (PSZ)szBuffer%@NL@%
  16141.                      );%@NL@%
  16142.         WinSendDlgItemMsg( hwndDlg,%@NL@%
  16143.                            LB_1,%@NL@%
  16144.                            LM_INSERTITEM,%@NL@%
  16145.                            MPFROM2SHORT( LIT_END, 0 ),%@NL@%
  16146.                            MPFROMP( szBuffer )%@NL@%
  16147.                          );%@NL@%
  16148.       }%@NL@%
  16149.       break;%@NL@%
  16150.     case WM_COMMAND:%@NL@%
  16151.       switch( SHORT1FROMMP( mp1 ) )%@NL@%
  16152.       {%@NL@%
  16153.         case DID_OK:     %@AB@%/* Enter key or pushbutton pressed/ selected */%@AE@%%@NL@%
  16154.           if( bModality )%@NL@%
  16155.           {%@NL@%
  16156.  %@NL@%
  16157. %@AB@%/***********************************************************************%@NL@%
  16158. %@AB@%*%@NL@%
  16159. %@AB@%*   Find out which item (if any) was selected and return the selected%@NL@%
  16160. %@AB@%*   item text.%@NL@%
  16161. %@AB@%*%@NL@%
  16162. %@AB@%***********************************************************************/%@AE@%%@NL@%
  16163.  %@NL@%
  16164.             id = SHORT1FROMMR( WinSendDlgItemMsg( hwndDlg,%@NL@%
  16165.                                                   LB_1,%@NL@%
  16166.                                                   LM_QUERYSELECTION,%@NL@%
  16167.                                                   0L,%@NL@%
  16168.                                                   0L ) );%@NL@%
  16169.             if( id == LIT_NONE )%@NL@%
  16170.               strcpy( szSelection, "" );%@NL@%
  16171.             else%@NL@%
  16172.               WinSendDlgItemMsg( hwndDlg,%@NL@%
  16173.                                  LB_1,%@NL@%
  16174.                                  LM_QUERYITEMTEXT,%@NL@%
  16175.                                  MPFROM2SHORT( id, LEN_LISTBOXENTRY ),%@NL@%
  16176.                                  MPFROMP( szSelection ) );%@NL@%
  16177.           }%@NL@%
  16178.           else%@NL@%
  16179.             WinPostMsg( hwndClient, DLGSAMP_LBCOMPLETE, 0L, 0L );%@NL@%
  16180.         case DID_CANCEL: %@AB@%/* Escape key or CANCEL pushbutton pressed/selected */%@AE@%%@NL@%
  16181.           if( bModality )%@NL@%
  16182.             WinDismissDlg( hwndDlg, TRUE );%@NL@%
  16183.           else%@NL@%
  16184.             WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );%@NL@%
  16185.           return FALSE;%@NL@%
  16186.         default:%@NL@%
  16187.           break;%@NL@%
  16188.       }%@NL@%
  16189.       break;%@NL@%
  16190.  %@NL@%
  16191.     default:  %@AB@%/* Pass all other messages to the default dialog proc */%@AE@%%@NL@%
  16192.       return WinDefDlgProc( hwndDlg, message, mp1, mp2 );%@NL@%
  16193.   }%@NL@%
  16194.   return FALSE;%@NL@%
  16195. }%@NL@%
  16196.  %@NL@%
  16197. %@AB@%/*************************************************************************%@NL@%
  16198. %@AB@%*%@NL@%
  16199. %@AB@%*   FUNCTION : CenterDlgBox%@NL@%
  16200. %@AB@%*%@NL@%
  16201. %@AB@%*   Positions the dialog box in the center of the screen%@NL@%
  16202. %@AB@%*%@NL@%
  16203. %@AB@%*************************************************************************/%@AE@%%@NL@%
  16204.  %@NL@%
  16205. VOID cdecl CenterDlgBox( hwnd )%@NL@%
  16206. HWND hwnd;%@NL@%
  16207. {%@NL@%
  16208.   SHORT ix, iy;%@NL@%
  16209.   SHORT iwidth, idepth;%@NL@%
  16210.   SWP   swp;%@NL@%
  16211.  %@NL@%
  16212.   iwidth = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );%@NL@%
  16213.   idepth = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );%@NL@%
  16214.   WinQueryWindowPos( hwnd, (PSWP)&swp );%@NL@%
  16215.   ix = ( iwidth  - swp.cx ) / 2;%@NL@%
  16216.   iy = ( idepth  - swp.cy ) / 2;%@NL@%
  16217.   WinSetWindowPos( hwnd, HWND_TOP, ix, iy, 0, 0, SWP_MOVE );%@NL@%
  16218. }%@NL@%
  16219.  %@NL@%
  16220. %@AB@%/***************************************************************************%@NL@%
  16221. %@AB@%*%@NL@%
  16222. %@AB@%*  FUNCTION: CheckColor%@NL@%
  16223. %@AB@%*%@NL@%
  16224. %@AB@%*  Toggle the Checked/UnChecked state of a checkbox and add/remove%@NL@%
  16225. %@AB@%*  the corresponding CLR color component of the Client Area Color.%@NL@%
  16226. %@AB@%*%@NL@%
  16227. %@AB@%***************************************************************************/%@AE@%%@NL@%
  16228.  %@NL@%
  16229. VOID cdecl CheckColor( hwndDlg, iDlgItem, colorClient )%@NL@%
  16230. HWND   hwndDlg;%@NL@%
  16231. SHORT  iDlgItem;%@NL@%
  16232. COLOR *colorClient;%@NL@%
  16233. {%@NL@%
  16234.   BOOL  bChecked;%@NL@%
  16235.   COLOR color;%@NL@%
  16236.  %@NL@%
  16237.   switch( iDlgItem )%@NL@%
  16238.   {%@NL@%
  16239.     case CB_RED:%@NL@%
  16240.       color = CLR_RED;%@NL@%
  16241.       break;%@NL@%
  16242.     case CB_GREEN:%@NL@%
  16243.       color = CLR_GREEN;%@NL@%
  16244.       break;%@NL@%
  16245.     case CB_BLUE:%@NL@%
  16246.       color = CLR_BLUE;%@NL@%
  16247.       break;%@NL@%
  16248.     default:%@NL@%
  16249.       return;%@NL@%
  16250.   }%@NL@%
  16251.  %@NL@%
  16252.   bChecked = SHORT1FROMMR( WinSendMsg( WinWindowFromID( hwndDlg , iDlgItem ),%@NL@%
  16253.                                        BM_QUERYCHECK,%@NL@%
  16254.                                        0L,%@NL@%
  16255.                                        0L ) );%@NL@%
  16256.   WinPostMsg( WinWindowFromID( hwndDlg, iDlgItem ),%@NL@%
  16257.               BM_SETCHECK,%@NL@%
  16258.               MPFROM2SHORT( !bChecked, 0 ),%@NL@%
  16259.               0L );%@NL@%
  16260.   if( bChecked )                   %@AB@%/* If color previously checked */%@AE@%%@NL@%
  16261.     *colorClient -= color;         %@AB@%/* subtract it ... else        */%@AE@%%@NL@%
  16262.   else%@NL@%
  16263.     *colorClient += color;         %@AB@%/* ... add it.                 */%@AE@%%@NL@%
  16264. }%@NL@%
  16265.  %@NL@%
  16266. %@AB@%/**************************************************************************%@NL@%
  16267. %@AB@%*%@NL@%
  16268. %@AB@%*   FUNCTION: EnableModality%@NL@%
  16269. %@AB@%*%@NL@%
  16270. %@AB@%*   Enable or disable the Modality menuitems depending on the value%@NL@%
  16271. %@AB@%*   of modal. This is done to prevent the user from altering the%@NL@%
  16272. %@AB@%*   modality setting while a modeless dialog is active.%@NL@%
  16273. %@AB@%*%@NL@%
  16274. %@AB@%**************************************************************************/%@AE@%%@NL@%
  16275.  %@NL@%
  16276. VOID cdecl EnableModality( hwnd, bModal )%@NL@%
  16277. HWND hwnd;%@NL@%
  16278. BOOL bModal;%@NL@%
  16279. {%@NL@%
  16280.   if( bModal )%@NL@%
  16281.   {%@NL@%
  16282.     WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),%@NL@%
  16283.                 MM_SETITEMATTR,%@NL@%
  16284.                 MPFROM2SHORT( MI_MODAL, TRUE ),%@NL@%
  16285.                 MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED ) );%@NL@%
  16286.     WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),%@NL@%
  16287.                 MM_SETITEMATTR,%@NL@%
  16288.                 MPFROM2SHORT( MI_MODELESS, TRUE ),%@NL@%
  16289.                 MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED ) );%@NL@%
  16290.   }%@NL@%
  16291.   else%@NL@%
  16292.   {%@NL@%
  16293.     WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),%@NL@%
  16294.                 MM_SETITEMATTR,%@NL@%
  16295.                 MPFROM2SHORT( MI_MODAL, TRUE ),%@NL@%
  16296.                 MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED ) );%@NL@%
  16297.     WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),%@NL@%
  16298.                 MM_SETITEMATTR,%@NL@%
  16299.                 MPFROM2SHORT( MI_MODELESS, TRUE ),%@NL@%
  16300.                 MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED ) );%@NL@%
  16301.   }%@NL@%
  16302. }%@NL@%
  16303.  %@NL@%
  16304. %@AB@%/***************************************************************************%@NL@%
  16305. %@AB@%*%@NL@%
  16306. %@AB@%*  FUNCTION: IsIntInRange.%@NL@%
  16307. %@AB@%*%@NL@%
  16308. %@AB@%*  Checks whether the value of a dialog item is in an integer in%@NL@%
  16309. %@AB@%*  a given range.%@NL@%
  16310. %@AB@%*%@NL@%
  16311. %@AB@%***************************************************************************/%@AE@%%@NL@%
  16312.  %@NL@%
  16313. BOOL cdecl IsIntInRange( hwndDlg,  idEntryField,%@NL@%
  16314.                          iLoRange, iHiRange,%@NL@%
  16315.                          idErrMsg, idMessageBox )%@NL@%
  16316. HWND hwndDlg;%@NL@%
  16317. SHORT  idEntryField;%@NL@%
  16318. SHORT  iLoRange;%@NL@%
  16319. SHORT  iHiRange;%@NL@%
  16320. SHORT  idErrMsg;%@NL@%
  16321. SHORT  idMessageBox;%@NL@%
  16322. {%@NL@%
  16323.   SHORT ivalue;%@NL@%
  16324.   CHAR  szErrMsg[80];%@NL@%
  16325.  %@NL@%
  16326. %@AB@%/****************************************************************************%@NL@%
  16327. %@AB@%*%@NL@%
  16328. %@AB@%*   Validate an entry field.%@NL@%
  16329. %@AB@%*%@NL@%
  16330. %@AB@%*   If validation fails leave the dialog visible, issue an error message%@NL@%
  16331. %@AB@%*   using a messagebox, and when the user dismisses the messagebox,%@NL@%
  16332. %@AB@%*   set the input focus to the entry field containing the error. Leave%@NL@%
  16333. %@AB@%*   the contents of the entry field unchanged, and return FALSE.%@NL@%
  16334. %@AB@%*%@NL@%
  16335. %@AB@%*   If validation is successful return the value in ivalue and return%@NL@%
  16336. %@AB@%*   TRUE.%@NL@%
  16337. %@AB@%*%@NL@%
  16338. %@AB@%****************************************************************************/%@AE@%%@NL@%
  16339.  %@NL@%
  16340.   if( !WinQueryDlgItemShort( hwndDlg, idEntryField, &ivalue, TRUE ) ||%@NL@%
  16341.       ( ivalue < iLoRange ) ||%@NL@%
  16342.       ( ivalue > iHiRange ) )%@NL@%
  16343.   {%@NL@%
  16344.     WinLoadString( hab, (HMODULE) NULL, idErrMsg, sizeof( szErrMsg ), szErrMsg );%@NL@%
  16345.     WinMessageBox( HWND_DESKTOP,%@NL@%
  16346.                    hwndFrame,%@NL@%
  16347.                    (PSZ)szErrMsg,%@NL@%
  16348.                    NULL,%@NL@%
  16349.                    idMessageBox,%@NL@%
  16350.                    MB_OK );%@NL@%
  16351.     WinSetFocus( HWND_DESKTOP, WinWindowFromID( hwndDlg, idEntryField ) );%@NL@%
  16352.     return FALSE;%@NL@%
  16353.   }%@NL@%
  16354.   else%@NL@%
  16355.     return TRUE;%@NL@%
  16356. }%@NL@%
  16357.  %@NL@%
  16358. %@AB@%/***********************************************************************%@NL@%
  16359. %@AB@%*%@NL@%
  16360. %@AB@%*  FUNCTION: LoadDialog%@NL@%
  16361. %@AB@%*%@NL@%
  16362. %@AB@%*  Use the appropriate functions to put up a modal or modeless%@NL@%
  16363. %@AB@%*  dialog box depending on the setting of the bModality parameter.%@NL@%
  16364. %@AB@%*%@NL@%
  16365. %@AB@%***********************************************************************/%@AE@%%@NL@%
  16366.  %@NL@%
  16367. VOID cdecl LoadDialog( hwndParent, hwndOwner, idDlg, fnwpDlgProc, bModality )%@NL@%
  16368. HWND  hwndParent;%@NL@%
  16369. HWND  hwndOwner;%@NL@%
  16370. SHORT idDlg;%@NL@%
  16371. PFNWP fnwpDlgProc;%@NL@%
  16372. BOOL  bModality;%@NL@%
  16373. {%@NL@%
  16374.   EnableModality( hwndOwner, FALSE ); %@AB@%/* Disable the Modality menu item */%@AE@%%@NL@%
  16375.  %@NL@%
  16376.   if( bModality )%@NL@%
  16377.   {%@NL@%
  16378.     WinDlgBox( hwndParent,        %@AB@%/* Parent                    */%@AE@%%@NL@%
  16379.                hwndOwner,         %@AB@%/* Owner                     */%@AE@%%@NL@%
  16380.                fnwpDlgProc,       %@AB@%/* Address of dialog proc    */%@AE@%%@NL@%
  16381.                (HMODULE) NULL,              %@AB@%/* Module handle             */%@AE@%%@NL@%
  16382.                idDlg,             %@AB@%/* Id of dialog in resource  */%@AE@%%@NL@%
  16383.                NULL );            %@AB@%/* Initialisation data       */%@AE@%%@NL@%
  16384.     EnableModality( hwndOwner, TRUE ); %@AB@%/* Enable the Modality menu item */%@AE@%%@NL@%
  16385.   }%@NL@%
  16386.   else%@NL@%
  16387.   {%@NL@%
  16388.     %@AB@%/*******************************************************************%@NL@%
  16389. %@AB@%    *%@NL@%
  16390. %@AB@%    *   Check to see if a modeless dialog is already running: if%@NL@%
  16391. %@AB@%    *   so destroy it before for loading the requested dialog. Save%@NL@%
  16392. %@AB@%    *   the handle of the new dialog in a global variable so that in%@NL@%
  16393. %@AB@%    *   can be accessed by the WinProc that issued LoadDialog.%@NL@%
  16394. %@AB@%    *%@NL@%
  16395. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  16396.  %@NL@%
  16397.     if( WinIsWindow( hab, hwndModelessDlg ) )%@NL@%
  16398.       WinDestroyWindow( hwndModelessDlg );%@NL@%
  16399.     hwndModelessDlg = WinLoadDlg( hwndParent,%@NL@%
  16400.                                   hwndOwner,%@NL@%
  16401.                                   fnwpDlgProc,%@NL@%
  16402.                                   (HMODULE) NULL,%@NL@%
  16403.                                   idDlg,%@NL@%
  16404.                                   NULL );%@NL@%
  16405.   }%@NL@%
  16406. }%@NL@%
  16407.  %@NL@%
  16408. %@AB@%/*************************************************************************%@NL@%
  16409. %@AB@%*%@NL@%
  16410. %@AB@%*   FUNCTION: MainWndCommand%@NL@%
  16411. %@AB@%*%@NL@%
  16412. %@AB@%*   Take the appropriate action when a WM_COMMAND message is received by%@NL@%
  16413. %@AB@%*   MainWndProc.  Issues calls which load dialogs in the prevailing state%@NL@%
  16414. %@AB@%*   of modality.%@NL@%
  16415. %@AB@%*%@NL@%
  16416. %@AB@%*************************************************************************/%@AE@%%@NL@%
  16417.  %@NL@%
  16418. VOID cdecl MainWndCommand( hwnd, Command, bModality )%@NL@%
  16419. HWND   hwnd;%@NL@%
  16420. USHORT Command;%@NL@%
  16421. BOOL   *bModality;%@NL@%
  16422. {%@NL@%
  16423.   USHORT idDlg;%@NL@%
  16424.   PFNWP  pfnDlgProc;%@NL@%
  16425.  %@NL@%
  16426.   switch( Command )%@NL@%
  16427.   {%@NL@%
  16428.     case MI_MODAL:%@NL@%
  16429.     case MI_MODELESS:%@NL@%
  16430.       *bModality = ( Command == MI_MODAL ) ? TRUE%@NL@%
  16431.                                            : FALSE;%@NL@%
  16432.       SetModality( WinQueryWindow( hwnd, QW_PARENT, FALSE ), *bModality );%@NL@%
  16433.       WinInvalidateRect( hwnd, NULL, FALSE );%@NL@%
  16434.       return;%@NL@%
  16435.     case MI_ENTRYFIELDEXAMPLE:%@NL@%
  16436.       idDlg      = DLG_ENTRYFIELDEXAMPLE;%@NL@%
  16437.       pfnDlgProc = (PFNWP)fnwpEntryFieldDlg;%@NL@%
  16438.       break;%@NL@%
  16439.     case MI_AUTORADIOBUTTONEXAMPLE:%@NL@%
  16440.       idDlg      = DLG_AUTORADIOBUTTONEXAMPLE;%@NL@%
  16441.       pfnDlgProc = (PFNWP)fnwpAutoRadioButtonDlg;%@NL@%
  16442.       break;%@NL@%
  16443.     case MI_CHECKBOXEXAMPLE:%@NL@%
  16444.       idDlg      = DLG_CHECKBOXEXAMPLE;%@NL@%
  16445.       pfnDlgProc = (PFNWP)fnwpCheckBoxDlg;%@NL@%
  16446.       break;%@NL@%
  16447.     case MI_LISTBOXEXAMPLE:%@NL@%
  16448.       idDlg      = DLG_LISTBOXEXAMPLE;%@NL@%
  16449.       pfnDlgProc = (PFNWP)fnwpListBoxDlg;%@NL@%
  16450.       break;%@NL@%
  16451.     case MI_ABOUTBOX:%@NL@%
  16452.       WinDlgBox(HWND_DESKTOP, hwnd, fnwpAboutBoxDlg, (HMODULE) NULL, DLG_ABOUT, NULL);%@NL@%
  16453.       return;%@NL@%
  16454.     default:%@NL@%
  16455.       return;%@NL@%
  16456.   }%@NL@%
  16457.   LoadDialog( HWND_DESKTOP,%@NL@%
  16458.               hwndFrame,%@NL@%
  16459.               idDlg,%@NL@%
  16460.               pfnDlgProc,%@NL@%
  16461.               *bModality );%@NL@%
  16462.   if( *bModality )%@NL@%
  16463.     WinInvalidateRect( hwnd, NULL, FALSE );  %@AB@%/* Request whole window repaint */%@AE@%%@NL@%
  16464. }%@NL@%
  16465.  %@NL@%
  16466. %@AB@%/************************************************************************%@NL@%
  16467. %@AB@%*%@NL@%
  16468. %@AB@%*   FUNCTION: MainWndPaint%@NL@%
  16469. %@AB@%*%@NL@%
  16470. %@AB@%*   An unsophisticated window painting routine which simply repaints the%@NL@%
  16471. %@AB@%*   entire window when a WM_PAINT message is received. In a real%@NL@%
  16472. %@AB@%*   application more sophisticated techniques could be used to determine%@NL@%
  16473. %@AB@%*   the minimum region needing repainting, and to paint only that%@NL@%
  16474. %@AB@%*   region%@NL@%
  16475. %@AB@%*%@NL@%
  16476. %@AB@%************************************************************************/%@AE@%%@NL@%
  16477.  %@NL@%
  16478. VOID cdecl MainWndPaint( hwnd )%@NL@%
  16479. HWND hwnd;%@NL@%
  16480. {%@NL@%
  16481.   POINTL   pointl;%@NL@%
  16482.   HPS      hps;                          %@AB@%/* Presentation space handle */%@AE@%%@NL@%
  16483.   RECTL    rcl;                          %@AB@%/* Window rectangle          */%@AE@%%@NL@%
  16484.   CHAR     string[50];%@NL@%
  16485.  %@NL@%
  16486.   hps = WinBeginPaint( hwnd, (HPS)NULL, (PRECTL)&rcl );%@NL@%
  16487.   %@AB@%/*%@NL@%
  16488. %@AB@%        Color in the background%@NL@%
  16489. %@AB@%  */%@AE@%%@NL@%
  16490.   switch ((int) colorClient) {%@NL@%
  16491.         case 0:                %@AB@%/* (r,g,b) = (0,0,0) */%@AE@%%@NL@%
  16492.             WinFillRect( hps, (PRECTL)&rcl, CLR_BLACK );%@NL@%
  16493.             break;%@NL@%
  16494.         case 7:                %@AB@%/* (r,g,b) = (1,1,1) */%@AE@%%@NL@%
  16495.             WinFillRect( hps, (PRECTL)&rcl, CLR_WHITE );%@NL@%
  16496.             break;%@NL@%
  16497.         default:%@NL@%
  16498.             WinFillRect( hps, (PRECTL)&rcl, colorClient );%@NL@%
  16499.             break;%@NL@%
  16500.   }%@NL@%
  16501.   %@AB@%/*%@NL@%
  16502. %@AB@%        Set the text character colors%@NL@%
  16503. %@AB@%  */%@AE@%%@NL@%
  16504.   GpiSetColor( hps, (colorClient == 0L) ? CLR_WHITE%@NL@%
  16505.                                         : CLR_BLACK );%@NL@%
  16506.   pointl.x = 10L; pointl.y = 70L;%@NL@%
  16507.   strcpy( string, "Dialog modality    = " );%@NL@%
  16508.   strcat( string, (bModality) ? "Modal"%@NL@%
  16509.                               : "Modeless" );%@NL@%
  16510.   GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );%@NL@%
  16511.   pointl.y = 50L;%@NL@%
  16512.   strcpy( string, "Entry Field 1      = " );%@NL@%
  16513.   strcat( string, szEntryField1 );%@NL@%
  16514.   GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );%@NL@%
  16515.   pointl.y = 30L;%@NL@%
  16516.   strcpy( string, "Entry Field 2      = " );%@NL@%
  16517.   strcat( string, szEntryField2 );%@NL@%
  16518.   GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );%@NL@%
  16519.   pointl.y = 10L;%@NL@%
  16520.   strcpy( string, "List Box Selection = " );%@NL@%
  16521.   strcat( string, szSelection );%@NL@%
  16522.   GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );%@NL@%
  16523.   WinEndPaint( hps );%@NL@%
  16524.  }%@NL@%
  16525.  %@NL@%
  16526. %@AB@%/**************************************************************************%@NL@%
  16527. %@AB@%*%@NL@%
  16528. %@AB@%*  FUNCTION: SetModality%@NL@%
  16529. %@AB@%*%@NL@%
  16530. %@AB@%*  Check or uncheck Modal and Modeless menu items as appropriate.%@NL@%
  16531. %@AB@%*%@NL@%
  16532. %@AB@%**************************************************************************/%@AE@%%@NL@%
  16533.  %@NL@%
  16534. VOID cdecl SetModality( hwnd, bModal )%@NL@%
  16535. HWND hwnd;%@NL@%
  16536. BOOL bModal;%@NL@%
  16537. {%@NL@%
  16538.   WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),%@NL@%
  16539.               MM_SETITEMATTR,%@NL@%
  16540.               MPFROM2SHORT( MI_MODAL, TRUE ),%@NL@%
  16541.               MPFROM2SHORT( MIA_CHECKED, (bModal) ? ( MIA_CHECKED)%@NL@%
  16542.                                                   : (~MIA_CHECKED) ) );%@NL@%
  16543.  %@NL@%
  16544.   WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),%@NL@%
  16545.               MM_SETITEMATTR,%@NL@%
  16546.               MPFROM2SHORT( MI_MODELESS, TRUE ),%@NL@%
  16547.               MPFROM2SHORT( MIA_CHECKED, (bModal) ? (~MIA_CHECKED)%@NL@%
  16548.                                                   : ( MIA_CHECKED) ) );%@NL@%
  16549.  %@NL@%
  16550. }%@NL@%
  16551. %@NL@%
  16552. MRESULT EXPENTRY fnwpAboutBoxDlg(hDlg, msg, mp1, mp2)%@NL@%
  16553. %@AB@%/*%@NL@%
  16554. %@AB@%    About... dialog procedure%@NL@%
  16555. %@AB@%*/%@AE@%%@NL@%
  16556. HWND        hDlg;%@NL@%
  16557. USHORT        msg;%@NL@%
  16558. MPARAM        mp1;%@NL@%
  16559. MPARAM        mp2;%@NL@%
  16560. {%@NL@%
  16561.     switch(msg) {%@NL@%
  16562.         case WM_COMMAND:%@NL@%
  16563.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  16564.                 case DID_OK: WinDismissDlg(hDlg, TRUE); break;%@NL@%
  16565.                 default: break;%@NL@%
  16566.             }%@NL@%
  16567.         default: return WinDefDlgProc(hDlg, msg, mp1, mp2);%@NL@%
  16568.     }%@NL@%
  16569.     return FALSE;%@NL@%
  16570. }%@NL@%
  16571. %@NL@%
  16572. %@NL@%
  16573. %@2@%%@AH@%DMGDB.C%@AE@%%@EH@%%@NL@%
  16574. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGDB.C%@AE@%%@NL@%
  16575. %@NL@%
  16576. %@AB@%/****************************** Module Header ******************************\%@NL@%
  16577. %@AB@%* Module Name: DMGDB.C%@NL@%
  16578. %@AB@%*%@NL@%
  16579. %@AB@%* DDE manager data handling routines%@NL@%
  16580. %@AB@%*%@NL@%
  16581. %@AB@%* Created: 12/14/88 Sanford Staab%@NL@%
  16582. %@AB@%*%@NL@%
  16583. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  16584. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16585. %@AI@%#include %@AE@%"ddemlp.h" %@NL@%
  16586. %@NL@%
  16587. %@AB@%/***************************** Private Function ****************************\%@NL@%
  16588. %@AB@%* PAPPINFO GetCurrentAppInfo()%@NL@%
  16589. %@AB@%*%@NL@%
  16590. %@AB@%* DESCRIPTION:%@NL@%
  16591. %@AB@%* This routine uses the pid of the current thread to locate the information%@NL@%
  16592. %@AB@%* pertaining to that thread.  If not found, 0 is returned.%@NL@%
  16593. %@AB@%*%@NL@%
  16594. %@AB@%* This call fails if the DLL is in a callback state to prevent recursion.%@NL@%
  16595. %@AB@%* if fChkCallback is set.%@NL@%
  16596. %@AB@%*%@NL@%
  16597. %@AB@%* History:      1/1/89  Created         sanfords%@NL@%
  16598. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16599. PAPPINFO GetCurrentAppInfo(fChkCallback)%@NL@%
  16600. BOOL fChkCallback;%@NL@%
  16601. {%@NL@%
  16602.     PAPPINFO pai;%@NL@%
  16603. %@NL@%
  16604.     SemEnter();%@NL@%
  16605.     if (pAppInfoList == NULL || !CheckSel(SELECTOROF(pAppInfoList))) {%@NL@%
  16606.         SemLeave();%@NL@%
  16607.         return(0);%@NL@%
  16608.     }%@NL@%
  16609.     pai = pAppInfoList;%@NL@%
  16610.     while (pai) {%@NL@%
  16611.         if (pai->pid == FSRSemDmg.pid && pai->tid == FSRSemDmg.tid) {%@NL@%
  16612.             if (fChkCallback && pai->cInCallback > MAX_RECURSE) {%@NL@%
  16613.                 pai->LastError = DMGERR_REENTRANCY;%@NL@%
  16614.                 break;%@NL@%
  16615.             } else {%@NL@%
  16616.                 SemLeave();%@NL@%
  16617.                 return(pai);%@NL@%
  16618.             }%@NL@%
  16619.         }%@NL@%
  16620.         pai = pai->next;%@NL@%
  16621.     }%@NL@%
  16622.     SemLeave();%@NL@%
  16623.     return(0);%@NL@%
  16624. }%@NL@%
  16625. %@NL@%
  16626. %@NL@%
  16627. %@AB@%/***************************** Private Function ****************************\%@NL@%
  16628. %@AB@%* void UnlinkAppInfo(pai)%@NL@%
  16629. %@AB@%* PAPPINFO pai;%@NL@%
  16630. %@AB@%*%@NL@%
  16631. %@AB@%* DESCRIPTION:%@NL@%
  16632. %@AB@%*   unlinks an pai safely.  Does nothing if not linked.%@NL@%
  16633. %@AB@%*%@NL@%
  16634. %@AB@%* History:      1/1/89  Created         sanfords%@NL@%
  16635. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16636. void UnlinkAppInfo(pai)%@NL@%
  16637. PAPPINFO pai;%@NL@%
  16638. {%@NL@%
  16639.     PAPPINFO paiT;%@NL@%
  16640. %@NL@%
  16641.     AssertF(pai != NULL, "UnlinkAppInfo - NULL input");%@NL@%
  16642.     SemEnter();%@NL@%
  16643.     if (pai == pAppInfoList) {%@NL@%
  16644.         pAppInfoList = pai->next;%@NL@%
  16645.         SemLeave();%@NL@%
  16646.         return;%@NL@%
  16647.     }%@NL@%
  16648.     paiT = pAppInfoList;%@NL@%
  16649.     while (paiT && paiT->next != pai)%@NL@%
  16650.         paiT = paiT->next;%@NL@%
  16651.     if (paiT)%@NL@%
  16652.         paiT->next = pai->next;%@NL@%
  16653.     SemLeave();%@NL@%
  16654.     return;%@NL@%
  16655. }%@NL@%
  16656. %@NL@%
  16657. %@NL@%
  16658. %@NL@%
  16659. %@NL@%
  16660. %@NL@%
  16661. %@AB@%/***************************** Private Functions ***************************\%@NL@%
  16662. %@AB@%* General List management functions.%@NL@%
  16663. %@AB@%*%@NL@%
  16664. %@AB@%* History:%@NL@%
  16665. %@AB@%*   Created     12/15/88    sanfords%@NL@%
  16666. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16667. PLST CreateLst(hheap, cbItem)%@NL@%
  16668. HHEAP hheap;%@NL@%
  16669. USHORT cbItem;%@NL@%
  16670. {%@NL@%
  16671.     PLST pLst;%@NL@%
  16672. %@NL@%
  16673.     SemEnter();%@NL@%
  16674.     if (!(pLst = (PLST)FarAllocMem(hheap, sizeof(LST)))) {%@NL@%
  16675.         SemLeave();%@NL@%
  16676.         return(NULL);%@NL@%
  16677.     }%@NL@%
  16678.     pLst->hheap = hheap;%@NL@%
  16679.     pLst->cbItem = cbItem;%@NL@%
  16680.     pLst->pItemFirst = (PLITEM)NULL;%@NL@%
  16681.     SemLeave();%@NL@%
  16682.     return(pLst);%@NL@%
  16683. }%@NL@%
  16684. %@NL@%
  16685. %@NL@%
  16686. %@NL@%
  16687. void FlushLst(pLst)%@NL@%
  16688. PLST pLst;%@NL@%
  16689. {%@NL@%
  16690.     if (pLst == NULL)%@NL@%
  16691.         return;%@NL@%
  16692.     SemEnter();%@NL@%
  16693.     while (pLst->pItemFirst) %@NL@%
  16694.         RemoveLstItem(pLst, pLst->pItemFirst);%@NL@%
  16695.     SemLeave();%@NL@%
  16696. }%@NL@%
  16697. %@NL@%
  16698. %@NL@%
  16699. %@NL@%
  16700. void DestroyLst(pLst)%@NL@%
  16701. PLST pLst;%@NL@%
  16702. {%@NL@%
  16703.     if (pLst == NULL)%@NL@%
  16704.         return;%@NL@%
  16705.     SemEnter();%@NL@%
  16706.     while (pLst->pItemFirst) %@NL@%
  16707.         RemoveLstItem(pLst, pLst->pItemFirst);%@NL@%
  16708.     FarFreeMem(pLst->hheap, pLst, sizeof(LST));%@NL@%
  16709.     SemLeave();%@NL@%
  16710. }%@NL@%
  16711. %@NL@%
  16712. %@NL@%
  16713. %@NL@%
  16714. PLITEM FindLstItem(pLst, npfnCmp, piSearch)%@NL@%
  16715. PLST pLst;%@NL@%
  16716. NPFNCMP npfnCmp;%@NL@%
  16717. PLITEM piSearch;%@NL@%
  16718. {%@NL@%
  16719.     PLITEM pi;%@NL@%
  16720. %@NL@%
  16721.     if (pLst == NULL)%@NL@%
  16722.         return(NULL);%@NL@%
  16723.     SemEnter();%@NL@%
  16724.     pi = pLst->pItemFirst;%@NL@%
  16725.     while (pi) {%@NL@%
  16726.         if ((*npfnCmp)%@NL@%
  16727.                 ((PBYTE)pi + sizeof(LITEM), (PBYTE)piSearch + sizeof(LITEM))) {%@NL@%
  16728.             SemLeave();%@NL@%
  16729.             return(pi);%@NL@%
  16730.         }%@NL@%
  16731.         pi = pi->next;%@NL@%
  16732.     }%@NL@%
  16733.     SemLeave();%@NL@%
  16734. }%@NL@%
  16735. %@NL@%
  16736. %@NL@%
  16737. %@NL@%
  16738. %@AB@%/*%@NL@%
  16739. %@AB@% * Comparison functions for FindLstItem() and FindPileItem()%@NL@%
  16740. %@AB@% */%@AE@%%@NL@%
  16741. %@NL@%
  16742. BOOL CmpULONG(pb1, pb2)%@NL@%
  16743. PBYTE pb1;%@NL@%
  16744. PBYTE pb2;%@NL@%
  16745. {%@NL@%
  16746.     return(*(PULONG)pb1 == *(PULONG)pb2);%@NL@%
  16747. }%@NL@%
  16748. %@NL@%
  16749. BOOL CmppHsz(pb1, pb2)%@NL@%
  16750. PBYTE pb1;%@NL@%
  16751. PBYTE pb2;%@NL@%
  16752. {%@NL@%
  16753.     return(CmpHsz(*(PHSZ)pb1, *(PHSZ)pb2) ? FALSE : TRUE);%@NL@%
  16754. }%@NL@%
  16755. %@NL@%
  16756. %@NL@%
  16757. %@NL@%
  16758. %@NL@%
  16759. %@AB@%/***************************** Private Function ****************************\%@NL@%
  16760. %@AB@%* This routine creates a new list item for pLst and links it in according%@NL@%
  16761. %@AB@%* to the ILST_ constant in afCmd.  Returns a pointer to the new item%@NL@%
  16762. %@AB@%* or NULL on failure.%@NL@%
  16763. %@AB@%*%@NL@%
  16764. %@AB@%* Note:  This MUST be in the semaphore for use since the new list item%@NL@%
  16765. %@AB@%* is filled with garbage on return yet is linked in.  %@NL@%
  16766. %@AB@%* %@NL@%
  16767. %@AB@%*%@NL@%
  16768. %@AB@%* History:%@NL@%
  16769. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  16770. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16771. PLITEM NewLstItem(pLst, afCmd)%@NL@%
  16772. PLST pLst;%@NL@%
  16773. USHORT afCmd;%@NL@%
  16774. {%@NL@%
  16775.     PLITEM pi, piT;%@NL@%
  16776. %@NL@%
  16777.     if (pLst == NULL)%@NL@%
  16778.         return(NULL);%@NL@%
  16779.     SemCheckIn();%@NL@%
  16780.     %@NL@%
  16781.     pi = (PLITEM)FarAllocMem(pLst->hheap, pLst->cbItem + sizeof(LITEM));%@NL@%
  16782.     if (pi == NULL) {%@NL@%
  16783.         AssertF(FALSE, "NewLstItem - memory failure");    %@NL@%
  16784.         return(NULL);%@NL@%
  16785.     }%@NL@%
  16786. %@NL@%
  16787.     if (afCmd & ILST_NOLINK) %@NL@%
  16788.         return(pi);%@NL@%
  16789.         %@NL@%
  16790.     if (((piT = pLst->pItemFirst) == NULL) || (afCmd & ILST_FIRST)) {%@NL@%
  16791.         pi->next = piT;%@NL@%
  16792.         pLst->pItemFirst = pi;%@NL@%
  16793.     } else {                            %@AB@%/* ILST_LAST assumed */%@AE@%%@NL@%
  16794.         while (piT->next != NULL) %@NL@%
  16795.             piT = piT->next;%@NL@%
  16796.         piT->next = pi;%@NL@%
  16797.         pi->next = NULL;%@NL@%
  16798.     }%@NL@%
  16799.     return(pi);%@NL@%
  16800. }%@NL@%
  16801. %@NL@%
  16802. %@NL@%
  16803. %@NL@%
  16804. %@AB@%/***************************** Private Function ****************************\%@NL@%
  16805. %@AB@%* This routine unlinks and frees pi from pLst.  If pi cannot be located%@NL@%
  16806. %@AB@%* within pLst, it is freed anyway.%@NL@%
  16807. %@AB@%*%@NL@%
  16808. %@AB@%* History:%@NL@%
  16809. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  16810. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16811. BOOL RemoveLstItem(pLst, pi)%@NL@%
  16812. PLST pLst;%@NL@%
  16813. PLITEM pi;%@NL@%
  16814. {%@NL@%
  16815.     PLITEM piT;%@NL@%
  16816. %@NL@%
  16817.     if (pLst == NULL || pi == NULL)%@NL@%
  16818.         return(FALSE);%@NL@%
  16819.         %@NL@%
  16820.     SemCheckIn();%@NL@%
  16821.     %@NL@%
  16822.     if ((piT = pLst->pItemFirst) != NULL) {%@NL@%
  16823.         if (pi == piT) {%@NL@%
  16824.             pLst->pItemFirst = pi->next;%@NL@%
  16825.         } else {%@NL@%
  16826.             while (piT->next != pi && piT->next != NULL)%@NL@%
  16827.                 piT = piT->next;%@NL@%
  16828.             if (piT->next != NULL)%@NL@%
  16829.                 piT->next = pi->next; %@AB@%/* unlink */%@AE@%%@NL@%
  16830.         }%@NL@%
  16831.     } else {%@NL@%
  16832.         AssertF(pi == NULL, "Improper list item removal");%@NL@%
  16833.     }%@NL@%
  16834.     FarFreeMem(pLst->hheap, pi, pLst->cbItem + sizeof(LITEM));%@NL@%
  16835.     return(TRUE);%@NL@%
  16836. }%@NL@%
  16837. %@NL@%
  16838. %@NL@%
  16839. %@NL@%
  16840. %@AB@%/***************************** Private Function ****************************\%@NL@%
  16841. %@AB@%* This routine uses ILST_ constants to insert a list item into the apropriate%@NL@%
  16842. %@AB@%* spot of the pLst given.  Only ILST_FIRST or ILST_LAST are allowed.%@NL@%
  16843. %@AB@%*%@NL@%
  16844. %@AB@%* History:%@NL@%
  16845. %@AB@%*   Created     9/11/89    Sanfords%@NL@%
  16846. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16847. BOOL InsertLstItem(pLst, pi, afCmd)%@NL@%
  16848. PLST pLst;%@NL@%
  16849. PLITEM pi;%@NL@%
  16850. USHORT afCmd;%@NL@%
  16851. {%@NL@%
  16852.     PLITEM piT;%@NL@%
  16853. %@NL@%
  16854.     if (pLst == NULL)%@NL@%
  16855.         return(FALSE);%@NL@%
  16856.         %@NL@%
  16857.     SemEnter();%@NL@%
  16858.     %@NL@%
  16859.     if (pLst->pItemFirst == NULL || afCmd & ILST_FIRST) {%@NL@%
  16860.         pi->next = pLst->pItemFirst;%@NL@%
  16861.         pLst->pItemFirst = pi;%@NL@%
  16862.     } else {                    %@AB@%/* ILST_LAST assumed */%@AE@%%@NL@%
  16863.         piT = pLst->pItemFirst;%@NL@%
  16864.         while (piT->next) %@NL@%
  16865.             piT = piT->next;%@NL@%
  16866.         piT->next = pi;%@NL@%
  16867.         pi->next = NULL;%@NL@%
  16868.     }%@NL@%
  16869.     %@NL@%
  16870.     SemLeave();%@NL@%
  16871.     return(TRUE);%@NL@%
  16872. }%@NL@%
  16873. %@NL@%
  16874. %@NL@%
  16875. %@NL@%
  16876. %@NL@%
  16877. %@AB@%/*%@NL@%
  16878. %@AB@% * ------------- Specific list routines -------------%@NL@%
  16879. %@AB@% */%@AE@%%@NL@%
  16880. %@NL@%
  16881. %@AB@%/*%@NL@%
  16882. %@AB@% * This function is HIGHLY dependent on the ADVLI structure.%@NL@%
  16883. %@AB@% * This will match an exact hsz/fmt pair with a 0 format being wild.%@NL@%
  16884. %@AB@% */%@AE@%%@NL@%
  16885. BOOL CmpAdv(pb1, pb2)%@NL@%
  16886. PBYTE pb1;%@NL@%
  16887. PBYTE pb2;%@NL@%
  16888. {%@NL@%
  16889.     USHORT usFmt;%@NL@%
  16890.     %@NL@%
  16891.     if (*(PHSZ)pb1 == *(PHSZ)pb2) {%@NL@%
  16892.         if ((usFmt = *(PUSHORT)(pb2 + 4)) == 0)%@NL@%
  16893.             return(TRUE);%@NL@%
  16894.         if (usFmt == *(PUSHORT)(pb1 + 4))%@NL@%
  16895.             return(TRUE);%@NL@%
  16896.     }%@NL@%
  16897.     return(FALSE);%@NL@%
  16898. }%@NL@%
  16899. %@NL@%
  16900. %@NL@%
  16901. %@NL@%
  16902. BOOL fSearchHwndList(pLst, hwnd)%@NL@%
  16903. PLST pLst;%@NL@%
  16904. HWND hwnd;%@NL@%
  16905. {%@NL@%
  16906.     HWNDLI hwndi;%@NL@%
  16907. %@NL@%
  16908.     hwndi.hwnd = hwnd;%@NL@%
  16909.     return((BOOL)FindLstItem(pLst, CmpHwnd, (PLITEM)&hwndi));%@NL@%
  16910. }%@NL@%
  16911. %@NL@%
  16912. %@NL@%
  16913. %@NL@%
  16914. void AddHwndList(hwnd, pLst)%@NL@%
  16915. HWND hwnd;%@NL@%
  16916. PLST pLst;%@NL@%
  16917. {%@NL@%
  16918.     HWNDLI hwndli;%@NL@%
  16919.     PHWNDLI pli;%@NL@%
  16920. %@NL@%
  16921.     AssertF(pLst != NULL, "AddHwndList - NULL pLst");%@NL@%
  16922.     AssertF(pLst->cbItem == sizeof(HWNDLI), "AddHwndList - Bad item size");%@NL@%
  16923.     SemEnter();%@NL@%
  16924.     hwndli.hwnd = hwnd;%@NL@%
  16925.     if ((hwnd == NULL) || FindLstItem(pLst, CmpHwnd, (PLITEM)&hwndli)) {%@NL@%
  16926.         SemLeave();%@NL@%
  16927.         return;%@NL@%
  16928.     }%@NL@%
  16929.     pli = (PHWNDLI)NewLstItem(pLst, ILST_FIRST);%@NL@%
  16930.     pli->hwnd = hwnd;%@NL@%
  16931.     SemLeave();%@NL@%
  16932. }%@NL@%
  16933. %@NL@%
  16934. %@NL@%
  16935. %@NL@%
  16936. %@AB@%/*%@NL@%
  16937. %@AB@% * Insert the given data into the list if one does not already exist%@NL@%
  16938. %@AB@% * under the given hwnd.%@NL@%
  16939. %@AB@% */%@AE@%%@NL@%
  16940. void AddAckHwndList(hwnd, hszApp, hszTopic, pLst)%@NL@%
  16941. HWND hwnd;%@NL@%
  16942. HSZ hszApp;%@NL@%
  16943. HSZ hszTopic;%@NL@%
  16944. PLST pLst;%@NL@%
  16945. {%@NL@%
  16946.     HWNDLI hwndli;%@NL@%
  16947.     PACKHWNDLI pli;%@NL@%
  16948. %@NL@%
  16949.     AssertF(pLst != NULL, "AddAckHwndList - NULL pLst");%@NL@%
  16950.     AssertF(pLst->cbItem == sizeof(ACKHWNDLI), "AddAckHwndList - Bad item size");%@NL@%
  16951.     SemEnter();%@NL@%
  16952.     hwndli.hwnd = hwnd;%@NL@%
  16953.     if ((hwnd == NULL) || FindLstItem(pLst, CmpHwnd, (PLITEM)&hwndli)) {%@NL@%
  16954.         SemLeave();%@NL@%
  16955.         return;%@NL@%
  16956.     }%@NL@%
  16957.     pli = (PACKHWNDLI)NewLstItem(pLst, ILST_FIRST);%@NL@%
  16958.     pli->hwnd = hwnd;%@NL@%
  16959.     pli->hszApp = hszApp;%@NL@%
  16960.     pli->hszTopic = hszTopic;%@NL@%
  16961.     SemLeave();%@NL@%
  16962. }%@NL@%
  16963. %@NL@%
  16964. %@NL@%
  16965. %@NL@%
  16966. %@NL@%
  16967. %@AB@%/***************************** Private Function ****************************\%@NL@%
  16968. %@AB@%* hwnd-hsz list functions%@NL@%
  16969. %@AB@%*%@NL@%
  16970. %@AB@%* History:      1/20/89     Created         sanfords%@NL@%
  16971. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  16972. void AddHwndHszList(hsz, hwnd, pLst)%@NL@%
  16973. HSZ hsz;%@NL@%
  16974. HWND hwnd;%@NL@%
  16975. PLST pLst;%@NL@%
  16976. {%@NL@%
  16977.     PHWNDHSZLI phhi;%@NL@%
  16978. %@NL@%
  16979.     AssertF(pLst->cbItem == sizeof(HWNDHSZLI), "AddHwndHszList - Bad item size");%@NL@%
  16980.     SemEnter();%@NL@%
  16981.     if ((hsz == NULL) || (BOOL)HwndFromHsz(hsz, pLst)) {%@NL@%
  16982.         SemLeave();%@NL@%
  16983.         return;%@NL@%
  16984.     }%@NL@%
  16985.     phhi = (PHWNDHSZLI)NewLstItem(pLst, ILST_FIRST);%@NL@%
  16986.     phhi->hwnd = hwnd;%@NL@%
  16987.     phhi->hsz = hsz;%@NL@%
  16988.     IncHszCount(hsz);%@NL@%
  16989.     SemLeave();%@NL@%
  16990. }%@NL@%
  16991. %@NL@%
  16992. %@NL@%
  16993. void DestroyHwndHszList(pLst)%@NL@%
  16994. PLST pLst;%@NL@%
  16995. {%@NL@%
  16996.     AssertF(pLst->cbItem == sizeof(HWNDHSZLI), "DestroyHwndHszList - Bad item size");%@NL@%
  16997.     SemEnter();%@NL@%
  16998.     while(pLst->pItemFirst) {%@NL@%
  16999.         FreeHsz(((PHWNDHSZLI)pLst->pItemFirst)->hsz);%@NL@%
  17000.         RemoveLstItem(pLst, pLst->pItemFirst);%@NL@%
  17001.     }%@NL@%
  17002.     FarFreeMem(pLst->hheap, pLst, sizeof(LST));%@NL@%
  17003.     SemLeave();%@NL@%
  17004. }%@NL@%
  17005. %@NL@%
  17006. %@NL@%
  17007. %@NL@%
  17008. HWND HwndFromHsz(hsz, pLst)%@NL@%
  17009. HSZ hsz;%@NL@%
  17010. PLST pLst;%@NL@%
  17011. {%@NL@%
  17012.     HWNDHSZLI hhli;%@NL@%
  17013.     PHWNDHSZLI phhli;%@NL@%
  17014. %@NL@%
  17015.     hhli.hsz = hsz;%@NL@%
  17016.     if (!(phhli = (PHWNDHSZLI)FindLstItem(pLst, CmppHsz, (PLITEM)&hhli)))%@NL@%
  17017.         return(NULL);%@NL@%
  17018.     return(phhli->hwnd);%@NL@%
  17019. }%@NL@%
  17020. %@NL@%
  17021. %@NL@%
  17022. %@NL@%
  17023. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17024. %@AB@%* DESCRIPTION:%@NL@%
  17025. %@AB@%*   Advise list helper functions.%@NL@%
  17026. %@AB@%*%@NL@%
  17027. %@AB@%* History:      1/20/89     Created         sanfords%@NL@%
  17028. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17029. BOOL AddAdvList(pLst, hszItem, fsStatus, usFmt)%@NL@%
  17030. PLST pLst;%@NL@%
  17031. HSZ hszItem;%@NL@%
  17032. USHORT fsStatus;%@NL@%
  17033. USHORT usFmt;%@NL@%
  17034. {%@NL@%
  17035.     PADVLI pali;%@NL@%
  17036. %@NL@%
  17037.     AssertF(pLst->cbItem == sizeof(ADVLI), "AddAdvList - bad item size");%@NL@%
  17038.     if (hszItem == NULL) %@NL@%
  17039.         return(TRUE);%@NL@%
  17040.     SemEnter();%@NL@%
  17041.     if (!(pali = FindAdvList(pLst, hszItem, usFmt))) {%@NL@%
  17042.         IncHszCount(hszItem);%@NL@%
  17043.         pali = (PADVLI)NewLstItem(pLst, ILST_FIRST);%@NL@%
  17044.     }%@NL@%
  17045.     AssertF((BOOL)pali, "AddAdvList - NewLstItem() failed")%@NL@%
  17046.     if (pali != NULL) {%@NL@%
  17047.         pali->hszItem = hszItem;%@NL@%
  17048.         pali->usFmt = usFmt;%@NL@%
  17049.         pali->fsStatus = fsStatus;%@NL@%
  17050.     }%@NL@%
  17051.     SemLeave();%@NL@%
  17052.     return((BOOL)pali);    %@NL@%
  17053. }%@NL@%
  17054. %@NL@%
  17055. %@NL@%
  17056. %@NL@%
  17057. %@AB@%/*%@NL@%
  17058. %@AB@% * This will delete the matching Advise loop entry.  If usFmt is 0, all%@NL@%
  17059. %@AB@% * entries with the same hszItem are deleted.  Returns fNotEmptyAfterDelete.%@NL@%
  17060. %@AB@% */%@AE@%%@NL@%
  17061. BOOL DeleteAdvList(pLst, hszItem, usFmt)%@NL@%
  17062. PLST pLst;%@NL@%
  17063. HSZ hszItem;%@NL@%
  17064. USHORT usFmt;%@NL@%
  17065. {%@NL@%
  17066.     PADVLI pali;%@NL@%
  17067. %@NL@%
  17068.     if (hszItem == NULL) %@NL@%
  17069.         return((BOOL)pLst->pItemFirst);%@NL@%
  17070.     SemEnter();%@NL@%
  17071.     while (pali = (PADVLI)FindAdvList(pLst, hszItem, usFmt)) {%@NL@%
  17072.         FreeHsz((pali)->hszItem);%@NL@%
  17073.         RemoveLstItem(pLst, (PLITEM)pali);%@NL@%
  17074.     }%@NL@%
  17075.     SemLeave();%@NL@%
  17076.     return((BOOL)pLst->pItemFirst);%@NL@%
  17077. }%@NL@%
  17078. %@NL@%
  17079. %@NL@%
  17080. %@NL@%
  17081. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17082. %@AB@%* This routine searches the advise list for and entry in hszItem.  It returns%@NL@%
  17083. %@AB@%* pAdvli only if the item is found.%@NL@%
  17084. %@AB@%*%@NL@%
  17085. %@AB@%* History:%@NL@%
  17086. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  17087. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17088. PADVLI FindAdvList(pLst, hszItem, usFmt)%@NL@%
  17089. PLST pLst;%@NL@%
  17090. HSZ hszItem;%@NL@%
  17091. USHORT usFmt;%@NL@%
  17092. {%@NL@%
  17093.     ADVLI advli;%@NL@%
  17094. %@NL@%
  17095.     advli.hszItem = hszItem;%@NL@%
  17096.     advli.usFmt = usFmt;%@NL@%
  17097.     return((PADVLI)FindLstItem(pLst, CmpAdv, (PLITEM)&advli));%@NL@%
  17098. }%@NL@%
  17099. %@NL@%
  17100. %@NL@%
  17101. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17102. %@AB@%* This routine searches for the next entry for hszItem.  It returns%@NL@%
  17103. %@AB@%* pAdvli only if the item is found.%@NL@%
  17104. %@AB@%*%@NL@%
  17105. %@AB@%* History:%@NL@%
  17106. %@AB@%*   Created     11/15/89    Sanfords%@NL@%
  17107. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17108. PADVLI FindNextAdv(padvli, hszItem)%@NL@%
  17109. PADVLI padvli;%@NL@%
  17110. HSZ hszItem;%@NL@%
  17111. {%@NL@%
  17112.     %@NL@%
  17113.     SemEnter();%@NL@%
  17114.     while ((padvli = (PADVLI)padvli->next) != NULL) {%@NL@%
  17115.         if (padvli->hszItem == hszItem) {%@NL@%
  17116.             SemLeave();%@NL@%
  17117.             return(padvli);%@NL@%
  17118.         }%@NL@%
  17119.     }%@NL@%
  17120.     SemLeave();%@NL@%
  17121.     return(NULL);%@NL@%
  17122. }%@NL@%
  17123. %@NL@%
  17124. %@NL@%
  17125. %@NL@%
  17126. %@AB@%/***************************** Pile Functions ********************************\%@NL@%
  17127. %@AB@%*%@NL@%
  17128. %@AB@%*  A pile is a list where each item is an array of subitems.  This allows%@NL@%
  17129. %@AB@%*  a more memory efficient method of handling unordered lists.%@NL@%
  17130. %@AB@%*%@NL@%
  17131. %@AB@%\*****************************************************************************/%@AE@%%@NL@%
  17132. %@NL@%
  17133. PPILE CreatePile(hheap, cbItem, cItemsPerBlock)%@NL@%
  17134. HHEAP hheap;%@NL@%
  17135. USHORT cbItem;%@NL@%
  17136. USHORT cItemsPerBlock;%@NL@%
  17137. {%@NL@%
  17138.     PPILE ppile;%@NL@%
  17139. %@NL@%
  17140.     if (!(ppile = (PPILE)FarAllocMem(hheap, sizeof(PILE)))) {%@NL@%
  17141.         SemLeave();%@NL@%
  17142.         return(NULL);%@NL@%
  17143.     }%@NL@%
  17144.     ppile->pBlockFirst = (PLITEM)NULL;%@NL@%
  17145.     ppile->hheap = hheap;%@NL@%
  17146.     ppile->cbBlock = cbItem * cItemsPerBlock + sizeof(PILEB);%@NL@%
  17147.     ppile->cSubItemsMax = cItemsPerBlock;%@NL@%
  17148.     ppile->cbSubItem = cbItem;%@NL@%
  17149.     return(ppile);%@NL@%
  17150. }%@NL@%
  17151. %@NL@%
  17152. %@NL@%
  17153. PPILE DestroyPile(pPile)%@NL@%
  17154. PPILE pPile;%@NL@%
  17155. {%@NL@%
  17156.     if (pPile == NULL)%@NL@%
  17157.         return(NULL);%@NL@%
  17158.     SemEnter();%@NL@%
  17159.     while (pPile->pBlockFirst) %@NL@%
  17160.         RemoveLstItem((PLST)pPile, (PLITEM)pPile->pBlockFirst);%@NL@%
  17161.     FarFreeMem(pPile->hheap, pPile, sizeof(PILE));%@NL@%
  17162.     SemLeave();%@NL@%
  17163.     return(NULL);%@NL@%
  17164. }%@NL@%
  17165. %@NL@%
  17166. void FlushPile(pPile)%@NL@%
  17167. PPILE pPile;%@NL@%
  17168. {%@NL@%
  17169.     if (pPile == NULL)%@NL@%
  17170.         return;%@NL@%
  17171.     SemEnter();%@NL@%
  17172.     while (pPile->pBlockFirst) %@NL@%
  17173.         RemoveLstItem((PLST)pPile, (PLITEM)pPile->pBlockFirst);%@NL@%
  17174.     SemLeave();%@NL@%
  17175. }%@NL@%
  17176. %@NL@%
  17177. %@NL@%
  17178. USHORT QPileItemCount(pPile)%@NL@%
  17179. PPILE pPile;%@NL@%
  17180. {%@NL@%
  17181.     register USHORT c;%@NL@%
  17182.     PPILEB pBlock;%@NL@%
  17183. %@NL@%
  17184.     if (pPile == NULL)%@NL@%
  17185.         return(0);%@NL@%
  17186. %@NL@%
  17187.     SemEnter();%@NL@%
  17188.     pBlock = pPile->pBlockFirst;%@NL@%
  17189.     c = 0;%@NL@%
  17190.     while (pBlock) {%@NL@%
  17191.         c += pBlock->cItems;%@NL@%
  17192.         pBlock = pBlock->next;%@NL@%
  17193.     }%@NL@%
  17194.     SemLeave();%@NL@%
  17195.     return(c);%@NL@%
  17196. }%@NL@%
  17197. %@NL@%
  17198. %@NL@%
  17199. BOOL CopyPileItems(pPile, pDst)%@NL@%
  17200. PPILE pPile;%@NL@%
  17201. PBYTE pDst;%@NL@%
  17202. {%@NL@%
  17203.     PPILEB pBlock;%@NL@%
  17204.     %@NL@%
  17205.     AssertF(pDst != NULL, "CopyPileItems - NULL destination");%@NL@%
  17206.     if (pPile == NULL)%@NL@%
  17207.         return(FALSE);%@NL@%
  17208. %@NL@%
  17209.     SemEnter();%@NL@%
  17210.     pBlock = pPile->pBlockFirst;%@NL@%
  17211.     while (pBlock) {%@NL@%
  17212.         CopyBlock((PBYTE)pBlock + sizeof(PILEB), pDst,%@NL@%
  17213.                 pBlock->cItems * pPile->cbSubItem);%@NL@%
  17214.         pDst += pBlock->cItems * pPile->cbSubItem;%@NL@%
  17215.         pBlock = pBlock->next;%@NL@%
  17216.     }%@NL@%
  17217.     SemLeave();%@NL@%
  17218. %@NL@%
  17219.     return(TRUE);%@NL@%
  17220. }%@NL@%
  17221. %@NL@%
  17222. %@NL@%
  17223. %@NL@%
  17224. %@NL@%
  17225. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17226. %@AB@%* Locate and return the pointer to the pile subitem who's key fields match%@NL@%
  17227. %@AB@%* pbSearch using npfnCmp to compare the fields.  If pbSearch == NULL, or%@NL@%
  17228. %@AB@%* npfnCmp == NULL, the first subitem is returned.%@NL@%
  17229. %@AB@%*%@NL@%
  17230. %@AB@%* afCmd may be:%@NL@%
  17231. %@AB@%* FPI_DELETE - delete the located item%@NL@%
  17232. %@AB@%* FPI_COUNT - count number of items that match%@NL@%
  17233. %@AB@%* In this case, the returned pointer is not valid.%@NL@%
  17234. %@AB@%*%@NL@%
  17235. %@AB@%* pppb points to where to store a pointer to the block which contained%@NL@%
  17236. %@AB@%* the located item.%@NL@%
  17237. %@AB@%*%@NL@%
  17238. %@AB@%* if pppb == NULL, it is ignored.%@NL@%
  17239. %@AB@%*%@NL@%
  17240. %@AB@%* NULL is returned if pbSearch was not found or if the list was empty.%@NL@%
  17241. %@AB@%*%@NL@%
  17242. %@AB@%* History:%@NL@%
  17243. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  17244. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17245. PBYTE FindPileItem(pPile, npfnCmp, pbSearch, afCmd)%@NL@%
  17246. PPILE pPile;%@NL@%
  17247. NPFNCMP npfnCmp;%@NL@%
  17248. PBYTE pbSearch;%@NL@%
  17249. USHORT afCmd;%@NL@%
  17250. {%@NL@%
  17251.     PBYTE pb;%@NL@%
  17252.     PPILEB ppbT;%@NL@%
  17253.     register int i;%@NL@%
  17254.     register int c;%@NL@%
  17255. %@NL@%
  17256.     if (pPile == NULL)%@NL@%
  17257.         return(NULL);%@NL@%
  17258.     c = 0;%@NL@%
  17259.     SemEnter();%@NL@%
  17260.     ppbT = pPile->pBlockFirst;%@NL@%
  17261.     while (ppbT) {%@NL@%
  17262.         %@AB@%/*%@NL@%
  17263. %@AB@%         * for each block...%@NL@%
  17264. %@AB@%         */%@AE@%%@NL@%
  17265.         for (pb = (PBYTE)ppbT + sizeof(PILEB), i = 0;%@NL@%
  17266.                 i < ppbT->cItems; pb += pPile->cbSubItem, i++) {%@NL@%
  17267.             %@AB@%/*%@NL@%
  17268. %@AB@%             * and each item within that block..%@NL@%
  17269. %@AB@%             */%@AE@%%@NL@%
  17270.             if (pbSearch == NULL || npfnCmp == NULL ||%@NL@%
  17271.                     (*npfnCmp)(pb, pbSearch)) {%@NL@%
  17272.                 %@AB@%/*%@NL@%
  17273. %@AB@%                 * If it matches or we don't care...%@NL@%
  17274. %@AB@%                 */%@AE@%%@NL@%
  17275.                 if (afCmd & FPI_DELETE) {%@NL@%
  17276.                     %@AB@%/*%@NL@%
  17277. %@AB@%                     * remove entire block if this was the last subitem in it.%@NL@%
  17278. %@AB@%                     */%@AE@%%@NL@%
  17279.                     if (--ppbT->cItems == 0) {%@NL@%
  17280.                         RemoveLstItem((PLST)pPile, (PLITEM)ppbT);%@NL@%
  17281.                     } else {%@NL@%
  17282.                         %@AB@%/*%@NL@%
  17283. %@AB@%                         * copy last subitem in the block over the removed item.%@NL@%
  17284. %@AB@%                         */%@AE@%%@NL@%
  17285.                         CopyBlock((PBYTE)ppbT + sizeof(PILEB) +%@NL@%
  17286.                                 pPile->cbSubItem * ppbT->cItems,%@NL@%
  17287.                                 pb, pPile->cbSubItem);%@NL@%
  17288.                     }%@NL@%
  17289.                 }%@NL@%
  17290.                 if (afCmd & FPI_COUNT) {%@NL@%
  17291.                     c++;%@NL@%
  17292.                 } else {%@NL@%
  17293.                     SemLeave();%@NL@%
  17294.                     return(pb);%@NL@%
  17295.                 }%@NL@%
  17296.                 if (afCmd & FPI_DELETE) {%@NL@%
  17297.                     pb = (PBYTE)ppbT + sizeof(PILEB);%@NL@%
  17298.                     i = 0;%@NL@%
  17299.                 }%@NL@%
  17300.             }%@NL@%
  17301.         }%@NL@%
  17302.         ppbT = (PPILEB)ppbT->next;%@NL@%
  17303.     }%@NL@%
  17304.     SemLeave();%@NL@%
  17305.     return((PBYTE)(ULONG)c);%@NL@%
  17306. }%@NL@%
  17307. %@NL@%
  17308. %@NL@%
  17309. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17310. %@AB@%* Places a copy of the subitem pointed to by pb into the first available%@NL@%
  17311. %@AB@%* spot in the pile pPile.  If npfnCmp != NULL, the pile is first searched%@NL@%
  17312. %@AB@%* for a pb match.  If found, pb replaces the located data but FALSE is%@NL@%
  17313. %@AB@%* returned to show that no real addition took place.%@NL@%
  17314. %@AB@%*%@NL@%
  17315. %@AB@%* History:%@NL@%
  17316. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  17317. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17318. BOOL AddPileItem(pPile, pb, npfnCmp)%@NL@%
  17319. PPILE pPile;%@NL@%
  17320. PBYTE pb;%@NL@%
  17321. BOOL (*npfnCmp)(PBYTE pb, PBYTE pbSearch);%@NL@%
  17322. {%@NL@%
  17323.     PBYTE pbDst;%@NL@%
  17324.     PPILEB ppb;%@NL@%
  17325. %@NL@%
  17326.     if (pPile == NULL)%@NL@%
  17327.         return(FALSE);%@NL@%
  17328.     SemEnter();%@NL@%
  17329.     if (npfnCmp != NULL &&%@NL@%
  17330.             (pbDst = FindPileItem(pPile, npfnCmp, pb, 0)) != NULL) {%@NL@%
  17331.         CopyBlock(pb, pbDst, pPile->cbSubItem);%@NL@%
  17332.         SemLeave();%@NL@%
  17333.         return(FALSE);%@NL@%
  17334.     }%@NL@%
  17335.     ppb = pPile->pBlockFirst;%@NL@%
  17336.     %@AB@%/*%@NL@%
  17337. %@AB@%     * locate a block with room%@NL@%
  17338. %@AB@%     */%@AE@%%@NL@%
  17339.     while ((ppb != NULL) && ppb->cItems == pPile->cSubItemsMax) {%@NL@%
  17340.         ppb = (PPILEB)ppb->next;%@NL@%
  17341.     }%@NL@%
  17342.     %@AB@%/*%@NL@%
  17343. %@AB@%     * If all full or no blocks, make a new one, link it on the bottom.%@NL@%
  17344. %@AB@%     */%@AE@%%@NL@%
  17345.     if (ppb == NULL) {%@NL@%
  17346.         if ((ppb = (PPILEB)NewLstItem((PLST)pPile, ILST_LAST)) == NULL) {%@NL@%
  17347.             SemLeave();%@NL@%
  17348.             return(FALSE);%@NL@%
  17349.         }%@NL@%
  17350.         ppb->cItems = 0;%@NL@%
  17351.     }%@NL@%
  17352.     %@AB@%/*%@NL@%
  17353. %@AB@%     * add the subitem%@NL@%
  17354. %@AB@%     */%@AE@%%@NL@%
  17355.     CopyBlock(pb, (PBYTE)ppb + sizeof(PILEB) + pPile->cbSubItem * ppb->cItems++,%@NL@%
  17356.         pPile->cbSubItem);%@NL@%
  17357.      %@NL@%
  17358.     SemLeave();%@NL@%
  17359.     return(TRUE);%@NL@%
  17360. }%@NL@%
  17361. %@NL@%
  17362. %@NL@%
  17363. %@NL@%
  17364. %@NL@%
  17365. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17366. %@AB@%* Fills pb with a copy of the top item's data and removes it from the pile.%@NL@%
  17367. %@AB@%* returns FALSE if the pile was empty.%@NL@%
  17368. %@AB@%*%@NL@%
  17369. %@AB@%* History:%@NL@%
  17370. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  17371. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17372. BOOL PopPileSubitem(pPile, pb)%@NL@%
  17373. PPILE pPile;%@NL@%
  17374. PBYTE pb;%@NL@%
  17375. {%@NL@%
  17376.     PPILEB ppb;%@NL@%
  17377.     PBYTE pSrc;%@NL@%
  17378. %@NL@%
  17379.     %@NL@%
  17380.     if ((pPile == NULL) || ((ppb = pPile->pBlockFirst) == NULL))%@NL@%
  17381.         return(FALSE);%@NL@%
  17382.         %@NL@%
  17383.     SemEnter();%@NL@%
  17384.     pSrc = (PBYTE)pPile->pBlockFirst + sizeof(PILEB);%@NL@%
  17385.     CopyBlock(pSrc, pb, pPile->cbSubItem);%@NL@%
  17386.     %@AB@%/*%@NL@%
  17387. %@AB@%     * remove entire block if this was the last subitem in it.%@NL@%
  17388. %@AB@%     */%@AE@%%@NL@%
  17389.     if (pPile->pBlockFirst->cItems == 1) {%@NL@%
  17390.         RemoveLstItem((PLST)pPile, (PLITEM)pPile->pBlockFirst);%@NL@%
  17391.     } else {%@NL@%
  17392.         %@AB@%/*%@NL@%
  17393. %@AB@%         * move last item in block to replace copied subitem and decrement%@NL@%
  17394. %@AB@%         * subitem count.%@NL@%
  17395. %@AB@%         */%@AE@%%@NL@%
  17396.         CopyBlock(pSrc + pPile->cbSubItem * --pPile->pBlockFirst->cItems,%@NL@%
  17397.                 pSrc, pPile->cbSubItem);%@NL@%
  17398.     }%@NL@%
  17399.     SemLeave();%@NL@%
  17400.     return(TRUE);%@NL@%
  17401. }%@NL@%
  17402.     %@NL@%
  17403. %@NL@%
  17404. %@AB@%/***************************** Semaphore Functions *************************\%@NL@%
  17405. %@AB@%* SemEnter() and SemLeave() are macros.%@NL@%
  17406. %@AB@%*%@NL@%
  17407. %@AB@%* History:      1/1/89  Created         sanfords%@NL@%
  17408. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17409. void SemInit()%@NL@%
  17410. {%@NL@%
  17411.     PBYTE pSem;%@NL@%
  17412.     SHORT c;%@NL@%
  17413. %@NL@%
  17414.     pSem = (PBYTE)&FSRSemDmg;%@NL@%
  17415.     c = 0;%@NL@%
  17416.     while (c++ < sizeof(DOSFSRSEM)) {%@NL@%
  17417.         *pSem++ = 0;%@NL@%
  17418.     }%@NL@%
  17419.     FSRSemDmg.cb = sizeof(DOSFSRSEM);%@NL@%
  17420. }%@NL@%
  17421. %@NL@%
  17422. %@AI@%#ifdef %@AE@%DEBUG %@NL@%
  17423. void SemCheckIn()%@NL@%
  17424. {                                                                %@NL@%
  17425.     PIDINFO pi;%@NL@%
  17426.     BOOL fin;%@NL@%
  17427. %@NL@%
  17428.     DosGetPID(&pi);%@NL@%
  17429.     fin = (FSRSemDmg.cUsage > 0) &&%@NL@%
  17430.             (FSRSemDmg.pid == pi.pid) &&%@NL@%
  17431.             ((FSRSemDmg.tid == pi.tid) || (FSRSemDmg.tid == -1));%@NL@%
  17432.     %@AB@%/*%@NL@%
  17433. %@AB@%     * !!! NOTE: during exitlists processing, semaphore TIDs are set to -1%@NL@%
  17434. %@AB@%     */%@AE@%%@NL@%
  17435.     AssertF(fin, "SemCheckIn - Out of Semaphore");%@NL@%
  17436.     if (!fin)%@NL@%
  17437.         SemEnter();%@NL@%
  17438. }%@NL@%
  17439. %@NL@%
  17440. void SemCheckOut()%@NL@%
  17441. {%@NL@%
  17442.     PIDINFO pi;%@NL@%
  17443.     BOOL fOut;%@NL@%
  17444. %@NL@%
  17445.     DosGetPID(&pi);%@NL@%
  17446.     fOut = FSRSemDmg.cUsage == 0 || FSRSemDmg.pid != pi.pid ||%@NL@%
  17447.                 FSRSemDmg.tid != pi.tid;%@NL@%
  17448.     AssertF(fOut, "SemCheckOut - In Semaphore");%@NL@%
  17449.     if (!fOut)%@NL@%
  17450.         while (FSRSemDmg.cUsage)%@NL@%
  17451.             SemLeave();%@NL@%
  17452.         %@NL@%
  17453. }%@NL@%
  17454. %@AI@%#endif %@AE@%%@NL@%
  17455. %@NL@%
  17456. %@NL@%
  17457. void SemEnter()%@NL@%
  17458. {%@NL@%
  17459.     DosFSRamSemRequest(&FSRSemDmg, SEM_INDEFINITE_WAIT);%@NL@%
  17460. }%@NL@%
  17461. %@NL@%
  17462. %@NL@%
  17463. void SemLeave()%@NL@%
  17464. {%@NL@%
  17465.     DosFSRamSemClear(&FSRSemDmg);%@NL@%
  17466. }%@NL@%
  17467. %@NL@%
  17468. %@NL@%
  17469. %@NL@%
  17470. void EXPENTRY ExlstAbort(usTermCode)%@NL@%
  17471. USHORT usTermCode;%@NL@%
  17472. {%@NL@%
  17473.     PAPPINFO pai;%@NL@%
  17474.     usTermCode;%@NL@%
  17475.     %@NL@%
  17476.     SemEnter();     %@AB@%/* get any other processes out of the semaphore */%@AE@%%@NL@%
  17477.     if (pai = GetCurrentAppInfo(FALSE)) {%@NL@%
  17478.         pai->cInCallback = 0;  %@AB@%/* so Unregister call will work */%@AE@%%@NL@%
  17479.         DdeUninitialize();%@NL@%
  17480.     } else {%@NL@%
  17481.         SemLeave();%@NL@%
  17482.         DosExitList(EXLST_REMOVE, (PFNEXITLIST)ExlstAbort);%@NL@%
  17483.     }%@NL@%
  17484.     DosExitList(EXLST_EXIT, 0);%@NL@%
  17485. }%@NL@%
  17486. %@NL@%
  17487. BOOL CopyHugeBlock(pSrc, pDst, cb)%@NL@%
  17488. PBYTE pSrc;%@NL@%
  17489. PBYTE pDst;%@NL@%
  17490. ULONG cb;%@NL@%
  17491. {%@NL@%
  17492.     ULONG cFirst;%@NL@%
  17493.     %@AB@%/*%@NL@%
  17494. %@AB@%     *  |____________|   |___________|   |____________|  |____________|%@NL@%
  17495. %@AB@%     *     ^src                                 ^%@NL@%
  17496. %@AB@%     *%@NL@%
  17497. %@AB@%     *  |____________|   |___________|   |____________|  |____________|%@NL@%
  17498. %@AB@%     *             ^dst                                   ^%@NL@%
  17499. %@AB@%     */%@AE@%%@NL@%
  17500.     cFirst = (ULONG)min((~(USHORT)pSrc), (~(USHORT)pDst)) + 1L;%@NL@%
  17501.     if (cb < cFirst) {%@NL@%
  17502.         CopyBlock(pSrc, pDst, (USHORT)cb);%@NL@%
  17503.         return(TRUE);%@NL@%
  17504.     }%@NL@%
  17505. %@NL@%
  17506.     goto copyit;%@NL@%
  17507.         %@NL@%
  17508.     %@AB@%/*%@NL@%
  17509. %@AB@%     * Now at least one of the pointers is on a segment boundry.%@NL@%
  17510. %@AB@%     */%@AE@%%@NL@%
  17511.     while (cb) {%@NL@%
  17512.         cFirst = min(0x10000 - ((USHORT)pSrc | (USHORT)pDst), cb);%@NL@%
  17513. copyit:%@NL@%
  17514.         if (HIUSHORT(cFirst)) {%@NL@%
  17515.             %@AB@%/*%@NL@%
  17516. %@AB@%             * special case where pSrc and pDst both are on segment%@NL@%
  17517. %@AB@%             * bounds.  Copy half at a time.%@NL@%
  17518. %@AB@%             */%@AE@%%@NL@%
  17519.             %@AB@%/*%@NL@%
  17520. %@AB@%             *  |___________|   |____________|  |____________|%@NL@%
  17521. %@AB@%             *  ^src                               ^%@NL@%
  17522. %@AB@%             *%@NL@%
  17523. %@AB@%             *  |___________|   |____________|  |____________|%@NL@%
  17524. %@AB@%             *  ^dst                               ^%@NL@%
  17525. %@AB@%             */%@AE@%%@NL@%
  17526.             cFirst >>= 1;%@NL@%
  17527.             CopyBlock(pSrc, pDst, (USHORT)cFirst);%@NL@%
  17528.             pSrc += cFirst;%@NL@%
  17529.             pDst += cFirst;%@NL@%
  17530.             cb -= cFirst;%@NL@%
  17531.         }%@NL@%
  17532.         CopyBlock(pSrc, pDst, (USHORT)cFirst);%@NL@%
  17533.         pSrc = HugeOffset(pSrc, cFirst);%@NL@%
  17534.         pDst = HugeOffset(pDst, cFirst);%@NL@%
  17535.         cb -= cFirst;%@NL@%
  17536.     %@AB@%/*%@NL@%
  17537. %@AB@%     *  |____________|   |___________|   |____________|  |____________|%@NL@%
  17538. %@AB@%     *           ^src                           ^%@NL@%
  17539. %@AB@%     *%@NL@%
  17540. %@AB@%     *  |____________|   |___________|   |____________|  |____________|%@NL@%
  17541. %@AB@%     *                   ^dst                             ^%@NL@%
  17542. %@AB@%     */%@AE@%%@NL@%
  17543.     }%@NL@%
  17544.     return(TRUE);%@NL@%
  17545. }%@NL@%
  17546. %@NL@%
  17547. %@NL@%
  17548. %@NL@%
  17549. %@NL@%
  17550. %@AB@%/***************************************************************************\%@NL@%
  17551. %@AB@%* Kills windows but avoids invalid window rips in debugger.%@NL@%
  17552. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17553. BOOL DestroyWindow(hwnd)%@NL@%
  17554. HWND hwnd;%@NL@%
  17555. {%@NL@%
  17556.     if (WinIsWindow(DMGHAB, hwnd))%@NL@%
  17557.         return(WinDestroyWindow(hwnd));%@NL@%
  17558.     return(TRUE);%@NL@%
  17559. }%@NL@%
  17560. %@NL@%
  17561. %@NL@%
  17562. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17563. %@AB@%* Returns hConv of the window passed in is one of the ddeml windows.%@NL@%
  17564. %@AB@%*%@NL@%
  17565. %@AB@%* History:%@NL@%
  17566. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  17567. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17568. HCONV IsDdeWindow(hwnd)%@NL@%
  17569. HWND hwnd;%@NL@%
  17570. {%@NL@%
  17571.     PAPPINFO pai;%@NL@%
  17572. %@NL@%
  17573.     pai = pAppInfoList;%@NL@%
  17574.     %@NL@%
  17575.     while (pai && WinIsChild(hwnd, pai->hwndDmg)) %@NL@%
  17576.         pai = pai->next;%@NL@%
  17577.         %@NL@%
  17578.     if (pai)%@NL@%
  17579.         return((HCONV)hwnd);%@NL@%
  17580.     else%@NL@%
  17581.         return(0L);%@NL@%
  17582. }%@NL@%
  17583. %@NL@%
  17584. %@NL@%
  17585. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17586. %@AB@%* This routine only frees a MYDDES segment if this process is not the owner.%@NL@%
  17587. %@AB@%*%@NL@%
  17588. %@AB@%* History:%@NL@%
  17589. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  17590. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17591. void FreeData(%@NL@%
  17592. PMYDDES pmyddes,%@NL@%
  17593. PAPPINFO pai)%@NL@%
  17594. {%@NL@%
  17595.     TID tid;%@NL@%
  17596.     if (!CheckSel(SELECTOROF(pmyddes)) ||%@NL@%
  17597.             (   pmyddes->offszItemName == sizeof(MYDDES) &&%@NL@%
  17598.                 pmyddes->magic == MYDDESMAGIC &&%@NL@%
  17599.                 pmyddes->fs & HDATA_APPOWNED &&%@NL@%
  17600.                 pmyddes->pai == pai) )%@NL@%
  17601.         return;%@NL@%
  17602. %@NL@%
  17603.     SemEnter();%@NL@%
  17604.     FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&pmyddes, FPI_DELETE);%@NL@%
  17605.     tid = pai->tid;%@NL@%
  17606.     do {%@NL@%
  17607.         if (FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&pmyddes, FPI_COUNT)) {%@NL@%
  17608.             SemLeave();%@NL@%
  17609.             return;%@NL@%
  17610.         }%@NL@%
  17611.         pai = pai->nextThread;%@NL@%
  17612.     } while (pai && pai->tid != tid);%@NL@%
  17613.     SemLeave();%@NL@%
  17614.     DosFreeSeg(SELECTOROF(pmyddes));%@NL@%
  17615. }%@NL@%
  17616. %@NL@%
  17617. %@NL@%
  17618. %@NL@%
  17619. %@AI@%#ifdef %@AE@%DEBUG %@NL@%
  17620. int APIENTRY DebugOutput(PCH);%@NL@%
  17621. void fAssert(f, pszComment, line, szfile)%@NL@%
  17622. BOOL f;%@NL@%
  17623. PSZ pszComment;%@NL@%
  17624. USHORT line;%@NL@%
  17625. PSZ szfile;%@NL@%
  17626. {%@NL@%
  17627.     char szT[90];%@NL@%
  17628.     PSZ psz, pszLast;%@NL@%
  17629. %@NL@%
  17630.     if (!f) {%@NL@%
  17631.         szT[0] = '\000';%@NL@%
  17632.         psz = szT;%@NL@%
  17633.         pszLast = &szT[89];%@NL@%
  17634.         psz = lstrcat(psz, "\n\rAssertion failure: ", pszLast);%@NL@%
  17635.         psz = lstrcat(psz, szfile, pszLast);%@NL@%
  17636.         psz = lstrcat(psz, ":", pszLast);%@NL@%
  17637.         psz = dtoa(psz, line, FALSE);%@NL@%
  17638.         psz = lstrcat(psz, " ", pszLast);%@NL@%
  17639.         psz = lstrcat(psz, pszComment, pszLast);%@NL@%
  17640.         psz = lstrcat(psz, "\n\r", pszLast);%@NL@%
  17641.         DebugOutput(szT);%@NL@%
  17642.         DebugBreak(); %@NL@%
  17643.     }%@NL@%
  17644. }%@NL@%
  17645. %@AI@%#endif %@AE@%%@NL@%
  17646. %@NL@%
  17647. %@NL@%
  17648. %@NL@%
  17649. HDMGDATA PutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd, pai)%@NL@%
  17650. PBYTE pSrc;%@NL@%
  17651. ULONG cb;%@NL@%
  17652. ULONG cbOff;%@NL@%
  17653. HSZ hszItem;%@NL@%
  17654. USHORT usFmt;%@NL@%
  17655. USHORT afCmd;%@NL@%
  17656. PAPPINFO pai;%@NL@%
  17657. {%@NL@%
  17658.     PMYDDES pmyddes;%@NL@%
  17659.     %@NL@%
  17660.     if ((pmyddes = (PMYDDES)AllocDDESel(0, usFmt, hszItem, cb + cbOff, pai))%@NL@%
  17661.             == NULL) {%@NL@%
  17662.         pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  17663.         return(0L);%@NL@%
  17664.     }%@NL@%
  17665.     pmyddes->fs = afCmd;%@NL@%
  17666.     %@NL@%
  17667.     if (afCmd & HDATA_APPFREEABLE) {%@NL@%
  17668.         if (!AddPileItem(pai->pHDataPile, (PBYTE)&pmyddes, CmpULONG)) {%@NL@%
  17669.             DosFreeSeg(SELECTOROF(pmyddes));%@NL@%
  17670.             pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  17671.             return(0L);%@NL@%
  17672.         } %@NL@%
  17673.     }%@NL@%
  17674.     if (pSrc)%@NL@%
  17675.         CopyHugeBlock(pSrc, HugeOffset(DDES_PABDATA(pmyddes), cbOff), cb);%@NL@%
  17676.     return(pmyddes);%@NL@%
  17677. }%@NL@%
  17678. %@NL@%
  17679. %@NL@%
  17680. %@AB@%/*%@NL@%
  17681. %@AB@% * This routine adds all HSZ/HAPP pairs it finds for the given pai matching%@NL@%
  17682. %@AB@% * hszApp to hDataAdd.%@NL@%
  17683. %@AB@% * poffAdd is the offset into the hDataAdd to start inserting HSZ/HAPP%@NL@%
  17684. %@AB@% * pairs.  It then truncates the list with a 0 HSZ and returns the offset%@NL@%
  17685. %@AB@% * to the terminator (ready to be called again to add more).%@NL@%
  17686. %@AB@% *%@NL@%
  17687. %@AB@% * returns 0L on error.%@NL@%
  17688. %@AB@% */%@AE@%%@NL@%
  17689. ULONG%@NL@%
  17690. QueryAppNames(%@NL@%
  17691. PAPPINFO pai,%@NL@%
  17692. HDMGDATA hDataAdd,%@NL@%
  17693. HSZ hszApp,%@NL@%
  17694. ULONG offAdd)%@NL@%
  17695. {%@NL@%
  17696.     USHORT chsz;%@NL@%
  17697.     PHSZ phsz, phszPile;%@NL@%
  17698.     PPILEB pBlock;%@NL@%
  17699. %@NL@%
  17700.     AssertF(sizeof(HSZ) == sizeof(HAPP), "Type size conflict");%@NL@%
  17701.         %@NL@%
  17702.     SemEnter();%@NL@%
  17703.     if (chsz = (USHORT)FindPileItem(pai->pAppNamePile,%@NL@%
  17704.             hszApp ? CmpULONG : NULL, (PBYTE)&hszApp, FPI_COUNT)) {%@NL@%
  17705.         %@AB@%/*%@NL@%
  17706. %@AB@%         * allocate for additions.%@NL@%
  17707. %@AB@%         */%@AE@%%@NL@%
  17708.         if (!DdeAddData(hDataAdd, NULL,%@NL@%
  17709.                 (chsz + 1L) * (sizeof(HSZ) + sizeof(HDMGDATA)), offAdd)) {%@NL@%
  17710.             offAdd = 0L;%@NL@%
  17711.             GetCurrentAppInfo(FALSE)->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  17712.             goto Exit;%@NL@%
  17713.         }%@NL@%
  17714.         %@NL@%
  17715.         phsz = DDES_PABDATA((PDDESTRUCT)hDataAdd) + offAdd;%@NL@%
  17716.         if (hszApp) {%@NL@%
  17717.             *phsz++ = hszApp;       %@AB@%/* only one per thread expected */%@AE@%%@NL@%
  17718.             *phsz++ = (HSZ)pai->hwndFrame;%@NL@%
  17719.         } else {%@NL@%
  17720.             pBlock = pai->pAppNamePile->pBlockFirst;%@NL@%
  17721.             while (pBlock) {%@NL@%
  17722.                 phszPile = (PHSZ)(pBlock + 1);%@NL@%
  17723.                 for (chsz = 0; chsz < pBlock->cItems; chsz++) {%@NL@%
  17724.                     *(phsz++) = *(phszPile++);%@NL@%
  17725.                     *(phsz++) = (HSZ)pai->hwndFrame;%@NL@%
  17726.                 }%@NL@%
  17727.                 pBlock = pBlock->next;%@NL@%
  17728.             }%@NL@%
  17729.         }%@NL@%
  17730.         *phsz = 0L;%@NL@%
  17731.         offAdd = phsz - DDES_PABDATA((PDDESTRUCT)hDataAdd);%@NL@%
  17732.     }%@NL@%
  17733. Exit:    %@NL@%
  17734.     SemLeave();%@NL@%
  17735.     return(offAdd);%@NL@%
  17736. }%@NL@%
  17737. %@NL@%
  17738. %@NL@%
  17739. %@NL@%
  17740. %@2@%%@AH@%DMGDDE.C%@AE@%%@EH@%%@NL@%
  17741. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGDDE.C%@AE@%%@NL@%
  17742. %@NL@%
  17743. %@AB@%/****************************** Module Header ******************************\%@NL@%
  17744. %@AB@%* Module Name: DMGDDE.C%@NL@%
  17745. %@AB@%*%@NL@%
  17746. %@AB@%* This module contains functions used for interfacing with DDE structures%@NL@%
  17747. %@AB@%* and such.%@NL@%
  17748. %@AB@%*%@NL@%
  17749. %@AB@%* Created:  12/23/88    sanfords%@NL@%
  17750. %@AB@%*%@NL@%
  17751. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  17752. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17753. %@AI@%#include %@AE@%"ddemlp.h" %@NL@%
  17754. %@NL@%
  17755. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17756. %@AB@%* timeout()%@NL@%
  17757. %@AB@%*%@NL@%
  17758. %@AB@%* This routine creates a timer for hwndTimeout.  It then runs a modal loop%@NL@%
  17759. %@AB@%* which will exit once the WM_TIMER message is received by hwndTimeout.%@NL@%
  17760. %@AB@%* hwndTimeout can be any window that doesn't use timers itself with TID_TIMEOUT%@NL@%
  17761. %@AB@%* or TID_ABORT since its window proc doesn't need to do%@NL@%
  17762. %@AB@%* anything for this to work.  Only the client and server windows use these%@NL@%
  17763. %@AB@%* so were cool.%@NL@%
  17764. %@AB@%* Only one timeout window is allowed per thread.  This is checked by the%@NL@%
  17765. %@AB@%* pai passed in.%@NL@%
  17766. %@AB@%*%@NL@%
  17767. %@AB@%* Returns fSuccess, ie TRUE if TID_TIMEOUT was received before TID_ABORT.%@NL@%
  17768. %@AB@%*%@NL@%
  17769. %@AB@%* PUBDOC START%@NL@%
  17770. %@AB@%* Synchronous client transaction modal loops:%@NL@%
  17771. %@AB@%*%@NL@%
  17772. %@AB@%* During Synchronous transactions, a client application will enter a modal%@NL@%
  17773. %@AB@%* loop while waiting for the server to respond to the request.  If an%@NL@%
  17774. %@AB@%* application wishes to filter messages to the modal loop, it may do so%@NL@%
  17775. %@AB@%* by setting a message filter tied to MSGF_DDE.  Applications should%@NL@%
  17776. %@AB@%* be aware however that the DDE modal loop processes private messages%@NL@%
  17777. %@AB@%* in the WM_USER range, WM_DDE messages, and WM_TIMER messages with timer IDs%@NL@%
  17778. %@AB@%* using the TID_ constants defined in ddeml.h.%@NL@%
  17779. %@AB@%* These messages must not be filtered by an application!!!%@NL@%
  17780. %@AB@%*%@NL@%
  17781. %@AB@%* PUBDOC END%@NL@%
  17782. %@AB@%*%@NL@%
  17783. %@AB@%* History:%@NL@%
  17784. %@AB@%*   Created     sanfords    12/19/88%@NL@%
  17785. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17786. BOOL timeout(pai, ulTimeout, hwndTimeout)%@NL@%
  17787. PAPPINFO pai;%@NL@%
  17788. ULONG ulTimeout;%@NL@%
  17789. HWND hwndTimeout;%@NL@%
  17790. {%@NL@%
  17791.     QMSG qmsg;%@NL@%
  17792. %@NL@%
  17793.     SemEnter();%@NL@%
  17794.     if (pai->hwndTimer) {%@NL@%
  17795.         pai->LastError = DMGERR_REENTRANCY;%@NL@%
  17796.         AssertF(FALSE, "Recursive timeout call");%@NL@%
  17797.         SemLeave();%@NL@%
  17798.         return(FALSE);%@NL@%
  17799.     }%@NL@%
  17800.     pai->hwndTimer = hwndTimeout;%@NL@%
  17801.     SemLeave();%@NL@%
  17802. %@NL@%
  17803.     WinStartTimer(DMGHAB, hwndTimeout, TID_TIMEOUT, (USHORT)ulTimeout);%@NL@%
  17804. %@NL@%
  17805.     WinGetMsg(DMGHAB, &qmsg, (HWND)NULL, 0, 0);%@NL@%
  17806. %@NL@%
  17807.     %@AB@%/*%@NL@%
  17808. %@AB@%     * stay in modal loop until a timeout happens.%@NL@%
  17809. %@AB@%     */%@AE@%%@NL@%
  17810.     while (qmsg.hwnd != hwndTimeout ||%@NL@%
  17811.             qmsg.msg != WM_TIMER ||%@NL@%
  17812.             (LOUSHORT(qmsg.mp1) != TID_TIMEOUT &&%@NL@%
  17813.             LOUSHORT(qmsg.mp1) != TID_ABORT)) {%@NL@%
  17814.             %@NL@%
  17815.         if (!WinCallMsgFilter(DMGHAB, &qmsg, MSGF_DDE))%@NL@%
  17816.             WinDispatchMsg(DMGHAB, &qmsg);%@NL@%
  17817.             %@NL@%
  17818.         WinGetMsg(DMGHAB, &qmsg, (HWND)NULL, 0, 0);%@NL@%
  17819.     }%@NL@%
  17820.     %@NL@%
  17821.     WinStopTimer(DMGHAB, hwndTimeout, TID_TIMEOUT);%@NL@%
  17822.     SemEnter();%@NL@%
  17823.     pai->hwndTimer = 0;%@NL@%
  17824.     SemLeave();%@NL@%
  17825.     %@AB@%/*%@NL@%
  17826. %@AB@%     * post a callback check incase we blocked callbacks due to being%@NL@%
  17827. %@AB@%     * in a timeout.%@NL@%
  17828. %@AB@%     */%@AE@%%@NL@%
  17829.     WinPostMsg(pai->hwndDmg, UM_CHECKCBQ, (MPARAM)pai, 0L);%@NL@%
  17830.     return(LOUSHORT(qmsg.mp1) == TID_TIMEOUT);%@NL@%
  17831. }%@NL@%
  17832. %@NL@%
  17833. %@NL@%
  17834. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17835. %@AB@%*%@NL@%
  17836. %@AB@%*  Based on pii, this sends an INITIATE message to either an exact%@NL@%
  17837. %@AB@%*  target window (hwndSend), a target frame window (hwndFrame) or to all%@NL@%
  17838. %@AB@%*  top level frames (both hwnds are NULL).  It fills in pci info as apropriate.%@NL@%
  17839. %@AB@%*  Note that pii->pCC must NOT be NULL and is assumed to be properly set.%@NL@%
  17840. %@AB@%*%@NL@%
  17841. %@AB@%*  Returns FALSE if SendDDEInit failed.%@NL@%
  17842. %@AB@%*  On success pci->ci.xad.state is CONVST_CONNECTED.%@NL@%
  17843. %@AB@%*%@NL@%
  17844. %@AB@%* History:%@NL@%
  17845. %@AB@%*   created 12/21/88        sanfords%@NL@%
  17846. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17847. BOOL ClientInitiate(hwnd, pii, pci)%@NL@%
  17848. HWND hwnd;%@NL@%
  17849. PINITINFO pii;%@NL@%
  17850. PCLIENTINFO pci;%@NL@%
  17851. {%@NL@%
  17852.     BOOL fRet = TRUE;%@NL@%
  17853. %@NL@%
  17854.     if (pii->pCC->cb < sizeof(CONVCONTEXT))%@NL@%
  17855.         return(FALSE);%@NL@%
  17856.         %@NL@%
  17857.     SemEnter();%@NL@%
  17858.     %@AB@%/*%@NL@%
  17859. %@AB@%     * we need to set this info BEFORE we do the synchronous initiate%@NL@%
  17860. %@AB@%     * so the INITIATEACK msg is done correctly.%@NL@%
  17861. %@AB@%     */%@AE@%%@NL@%
  17862.     pci->ci.xad.state = CONVST_INIT1;%@NL@%
  17863.     pci->ci.xad.LastError = DMGERR_NO_ERROR;%@NL@%
  17864.     pci->ci.hszServerApp = pii->hszAppName;%@NL@%
  17865.     pci->ci.hszTopic = pii->hszTopic;%@NL@%
  17866.     pci->ci.cc.cb = sizeof(CONVCONTEXT);%@NL@%
  17867.     CopyBlock((PBYTE)&pii->pCC->fsContext, (PBYTE)&pci->ci.cc.fsContext,%@NL@%
  17868.         sizeof(CONVCONTEXT) - sizeof(USHORT));%@NL@%
  17869.     pci->ci.hwndFrame = pii->hwndFrame;%@NL@%
  17870.     SemLeave();%@NL@%
  17871.     %@NL@%
  17872.     fRet = SendDDEInit(hwnd,%@NL@%
  17873.             WinIsWindow(DMGHAB, pii->hwndSend) ? pii->hwndSend : pii->hwndFrame,%@NL@%
  17874.             pci);%@NL@%
  17875.     SemEnter();%@NL@%
  17876.     %@AB@%/*%@NL@%
  17877. %@AB@%     * If we failed to initiate directly with the server, try the frame.%@NL@%
  17878. %@AB@%     */%@AE@%%@NL@%
  17879.     if (!fRet && WinIsWindow(DMGHAB, pii->hwndSend) &&%@NL@%
  17880.             WinIsWindow(DMGHAB, pii->hwndFrame)) {%@NL@%
  17881.         SemLeave();%@NL@%
  17882.         fRet = SendDDEInit(hwnd, pii->hwndFrame, pci);%@NL@%
  17883.         if (fRet) {%@NL@%
  17884.             %@AB@%/*%@NL@%
  17885. %@AB@%             * OK, client is locked in so he wont go away on a terminate%@NL@%
  17886. %@AB@%             * from a random window. If the new server is not the same%@NL@%
  17887. %@AB@%             * window as the origonal, send it a terminate so it can%@NL@%
  17888. %@AB@%             * go away nicely.%@NL@%
  17889. %@AB@%             */%@AE@%%@NL@%
  17890.             if (pii->hwndSend != pci->ci.hwndPartner) %@NL@%
  17891.                 WinSendMsg(pii->hwndSend, WM_DDE_TERMINATE, 0L, 0L);%@NL@%
  17892.         }%@NL@%
  17893.         SemEnter();%@NL@%
  17894.         %@NL@%
  17895.     }%@NL@%
  17896.     if (!fRet) %@NL@%
  17897.         pci->ci.xad.state = CONVST_NULL;%@NL@%
  17898.     else {%@NL@%
  17899.         %@AB@%/*%@NL@%
  17900. %@AB@%         * successful initiate means we want to keep these around awhile.%@NL@%
  17901. %@AB@%         * removed at window closing time.%@NL@%
  17902. %@AB@%         */%@AE@%%@NL@%
  17903.         IncHszCount(pci->ci.hszServerApp);%@NL@%
  17904.         IncHszCount(pci->ci.hszTopic);%@NL@%
  17905.     }%@NL@%
  17906.     SemLeave();%@NL@%
  17907.     return(fRet);%@NL@%
  17908. }%@NL@%
  17909. %@NL@%
  17910. %@NL@%
  17911. %@NL@%
  17912. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17913. %@AB@%* Allocates and sends a WM_DDE_INITIATE message to hwndTo.  Any failures%@NL@%
  17914. %@AB@%* cause FALSE to be returned.  If hwndTo is NULL, performs equivalent of%@NL@%
  17915. %@AB@%* WinDdeInitiate2().%@NL@%
  17916. %@AB@%*%@NL@%
  17917. %@AB@%* History:%@NL@%
  17918. %@AB@%*   created     12/22/88        sanfords%@NL@%
  17919. %@AB@%*   2/2/89  sanfords    added SEG_GETABLE during monitoring.%@NL@%
  17920. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  17921. BOOL SendDDEInit(hwndFrom, hwndTo, pci)%@NL@%
  17922. HWND hwndFrom;%@NL@%
  17923. HWND hwndTo;%@NL@%
  17924. PCLIENTINFO pci;%@NL@%
  17925. {%@NL@%
  17926.     PID pidTo;%@NL@%
  17927.     TID tid;%@NL@%
  17928.     SEL sel;%@NL@%
  17929.     PDDEINIT pddeinit;%@NL@%
  17930.     HENUM henum;%@NL@%
  17931.     ULONG ul;%@NL@%
  17932.     USHORT cchApp, cchTopic;%@NL@%
  17933.     PSZ pszApp, pszTopic;%@NL@%
  17934.     BOOL fEnumerating;  %@AB@%/* set if extra acks are ok */%@AE@%%@NL@%
  17935. %@NL@%
  17936.     SemCheckOut();%@NL@%
  17937. %@NL@%
  17938.     if (hwndTo == NULL) {%@NL@%
  17939.         %@AB@%/*%@NL@%
  17940. %@AB@%         * Call on self for all top level frame windows until we are connected.%@NL@%
  17941. %@AB@%         * (if enumerating, do em all anyway.)%@NL@%
  17942. %@AB@%         */%@AE@%%@NL@%
  17943.         fEnumerating = WinQueryWindow(hwndFrom, QW_PARENT, FALSE) !=%@NL@%
  17944.                 pci->ci.pai->hwndDmg;%@NL@%
  17945.         if (henum = WinBeginEnumWindows(HWND_DESKTOP)) {%@NL@%
  17946.             while ((hwndTo = WinGetNextWindow(henum)) &&%@NL@%
  17947.                     (fEnumerating || pci->ci.xad.state == CONVST_INIT1)) {%@NL@%
  17948.                 if (hwndTo != pci->ci.pai->hwndFrame &&%@NL@%
  17949.                         (ul = (ULONG)WinSendMsg(hwndTo, WM_QUERYFRAMEINFO, 0L, 0L)) &&%@NL@%
  17950.                         (ul & FI_FRAME))%@NL@%
  17951.                     SendDDEInit(hwndFrom, hwndTo, pci);%@NL@%
  17952.             }%@NL@%
  17953.             WinEndEnumWindows(henum);%@NL@%
  17954.         }%@NL@%
  17955.         return(TRUE);%@NL@%
  17956.     }%@NL@%
  17957.     %@NL@%
  17958.     if (WinQueryWindowProcess(hwndTo, &pidTo, &tid) == NULL)%@NL@%
  17959.         return(FALSE);%@NL@%
  17960. %@NL@%
  17961.     SemEnter();%@NL@%
  17962.     pszApp = pszFromHsz(pci->ci.hszServerApp, &cchApp);%@NL@%
  17963.     pszTopic = pszFromHsz(pci->ci.hszTopic, &cchTopic);%@NL@%
  17964.     if (DosAllocSeg(sizeof(DDEINIT) + sizeof(CONVCONTEXT) + cchApp + cchTopic,%@NL@%
  17965.                 &sel, SEG_GIVEABLE) != 0) {%@NL@%
  17966.         SemLeave();%@NL@%
  17967.         return(FALSE);%@NL@%
  17968.     }%@NL@%
  17969.     pddeinit = MAKEP(sel, 0);%@NL@%
  17970.     pddeinit->cb = sizeof(DDEINIT);%@NL@%
  17971.     pddeinit->offConvContext = sizeof(DDEINIT);%@NL@%
  17972.     pddeinit->pszAppName = (PSZ)pddeinit + sizeof(DDEINIT) + sizeof(CONVCONTEXT);%@NL@%
  17973.     pddeinit->pszTopic = pddeinit->pszAppName + cchApp;%@NL@%
  17974.     CopyBlock((PBYTE)&pci->ci.cc, (PBYTE)DDEI_PCONVCONTEXT(pddeinit), sizeof(CONVCONTEXT));%@NL@%
  17975.     CopyBlock((PBYTE)pszApp, (PBYTE)pddeinit->pszAppName, cchApp);%@NL@%
  17976.     CopyBlock((PBYTE)pszTopic, (PBYTE)pddeinit->pszTopic, cchTopic);%@NL@%
  17977.     FarFreeMem(hheapDmg, pszApp, cchApp);%@NL@%
  17978.     FarFreeMem(hheapDmg, pszTopic, cchTopic);%@NL@%
  17979.     SemLeave();%@NL@%
  17980. %@NL@%
  17981.     if (DosGiveSeg(sel, pidTo, &sel) != 0) {%@NL@%
  17982.         DosFreeSeg(sel);%@NL@%
  17983.         return(FALSE);%@NL@%
  17984.     }%@NL@%
  17985. %@NL@%
  17986.     WinSendMsg(hwndTo, WM_DDE_INITIATE, (MPARAM)hwndFrom, pddeinit);%@NL@%
  17987.     if (pidTo != pci->ci.pai->pid)%@NL@%
  17988.         DosFreeSeg(sel);%@NL@%
  17989.     return(TRUE);%@NL@%
  17990. }%@NL@%
  17991. %@NL@%
  17992. %@NL@%
  17993. %@NL@%
  17994. %@AB@%/***************************** Private Function ****************************\%@NL@%
  17995. %@AB@%*%@NL@%
  17996. %@AB@%*  Alocates and fills in a MYDDES. if pai == 0, the MYDDES is considered%@NL@%
  17997. %@AB@%* unowned.%@NL@%
  17998. %@AB@%*%@NL@%
  17999. %@AB@%* History:  created     1/4/89  sanfords%@NL@%
  18000. %@AB@%* 10/18/89  sanfords Added hack so that if usFmt==DDEFMT_TEXT and hszItem==0L,%@NL@%
  18001. %@AB@%*                    the data and item strings are one.%@NL@%
  18002. %@AB@%*                    (This allows for excel EXEC compatibility)%@NL@%
  18003. %@AB@%*   2/2/89  sanfords Added GETABLE during monitoring.%@NL@%
  18004. %@AB@%*  6/13/90  sanfords Altered to not expand hszItem at this point.%@NL@%
  18005. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18006. PDDESTRUCT AllocDDESel(fsStatus, usFmt, hszItem, cbData, pai)%@NL@%
  18007. USHORT fsStatus;%@NL@%
  18008. USHORT usFmt;%@NL@%
  18009. HSZ hszItem;%@NL@%
  18010. ULONG cbData;%@NL@%
  18011. PAPPINFO pai;%@NL@%
  18012. {%@NL@%
  18013.     PMYDDES pmyddes = NULL;%@NL@%
  18014.     ULONG cbTotal;%@NL@%
  18015.     ULONG cchItem;%@NL@%
  18016.     SEL sel;%@NL@%
  18017. %@NL@%
  18018.     SemEnter();%@NL@%
  18019.     cchItem = DdeGetHszString(hszItem, NULL, 0L) + 1L;%@NL@%
  18020. %@NL@%
  18021.     %@AB@%/*%@NL@%
  18022. %@AB@%     * This hack makes execs conform to EXCELs way.%@NL@%
  18023. %@AB@%     */%@AE@%%@NL@%
  18024.     if (!hszItem && usFmt == DDEFMT_TEXT)%@NL@%
  18025.         cchItem = 0L;%@NL@%
  18026. %@NL@%
  18027.     cbTotal = sizeof(MYDDES) + cchItem + cbData + 1;%@NL@%
  18028.     if (cbTotal <= 0xFFFF) {%@NL@%
  18029.         if (DosAllocSeg((USHORT)cbTotal, &sel, SEG_GIVEABLE) != 0)%@NL@%
  18030.             goto allocDdeExit;%@NL@%
  18031.     } else {%@NL@%
  18032.         if (DosAllocHuge((USHORT)(cbTotal >> 16), (USHORT)cbTotal, &sel,%@NL@%
  18033.                 0, SEG_GIVEABLE) != 0)%@NL@%
  18034.             goto allocDdeExit;%@NL@%
  18035.     }%@NL@%
  18036. %@NL@%
  18037.     pmyddes = MAKEP(sel, 0);%@NL@%
  18038.     pmyddes->cbData = cbData;%@NL@%
  18039.     pmyddes->fsStatus = fsStatus;%@NL@%
  18040.     pmyddes->usFormat = usFmt;%@NL@%
  18041.     pmyddes->offszItemName = sizeof(MYDDES);%@NL@%
  18042.     pmyddes->offabData = sizeof(MYDDES) + (USHORT)cchItem;%@NL@%
  18043.     pmyddes->ulRes1 = 0L;%@NL@%
  18044.     pmyddes->magic = MYDDESMAGIC;%@NL@%
  18045.     pmyddes->hszItem = hszItem;%@NL@%
  18046.     pmyddes->pai = pai;%@NL@%
  18047.     pmyddes->fs = 0;%@NL@%
  18048.     *DDES_PABDATA((PDDESTRUCT)pmyddes) = '\0'; %@AB@%/* in case data is never placed */%@AE@%%@NL@%
  18049.     *DDES_PSZITEMNAME((PDDESTRUCT)pmyddes) = '\0';  %@AB@%/* we expand this at post time if necessary */%@AE@%%@NL@%
  18050. %@NL@%
  18051. allocDdeExit:%@NL@%
  18052.     SemLeave();%@NL@%
  18053.     return((PDDESTRUCT)pmyddes);%@NL@%
  18054. }%@NL@%
  18055. %@NL@%
  18056. %@NL@%
  18057. %@NL@%
  18058. %@NL@%
  18059. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18060. %@AB@%* This routine returns the hwnd of a newly created and connected DDE%@NL@%
  18061. %@AB@%* client or NULL if failure.%@NL@%
  18062. %@AB@%*%@NL@%
  18063. %@AB@%* History:  created     1/6/89  sanfords%@NL@%
  18064. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18065. HCONV GetDDEClientWindow(hConvList, hwndFrame, hwndSend, hszApp, hszTopic, pCC)%@NL@%
  18066. HCONVLIST hConvList;%@NL@%
  18067. HWND hwndFrame;%@NL@%
  18068. HWND hwndSend;%@NL@%
  18069. HSZ hszApp;%@NL@%
  18070. HSZ hszTopic;%@NL@%
  18071. PCONVCONTEXT pCC;%@NL@%
  18072. {%@NL@%
  18073.     HCONV hConv;%@NL@%
  18074.     INITINFO ii;%@NL@%
  18075.     CONVCONTEXT cc;%@NL@%
  18076. %@NL@%
  18077.     SemCheckOut();%@NL@%
  18078.     %@NL@%
  18079.     hConv = WinCreateWindow(hConvList, SZCLIENTCLASS, "", 0L,%@NL@%
  18080.             0, 0, 0, 0, (HWND)NULL, HWND_TOP, WID_CLIENT, 0L, 0L);%@NL@%
  18081.             %@NL@%
  18082.     if (hConv == NULL)%@NL@%
  18083.         return(NULL);%@NL@%
  18084.         %@NL@%
  18085.     ii.hszTopic = hszTopic;%@NL@%
  18086.     ii.hszAppName = hszApp;%@NL@%
  18087.     ii.hwndSend = hwndSend;%@NL@%
  18088.     ii.hwndFrame = hwndFrame;%@NL@%
  18089.     if (pCC == NULL) {%@NL@%
  18090.         pCC = &cc;%@NL@%
  18091.         cc.cb = sizeof(CONVCONTEXT);%@NL@%
  18092.         cc.fsContext = 0;%@NL@%
  18093.         %@AB@%/*##LATER - may want to use process codepage instead */%@AE@%%@NL@%
  18094.         cc.usCodepage = syscc.codepage;%@NL@%
  18095.         cc.idCountry = syscc.country;%@NL@%
  18096.     }%@NL@%
  18097.     if (pCC->usCodepage == 0) %@NL@%
  18098.         pCC->usCodepage = syscc.codepage;%@NL@%
  18099.     if (pCC->idCountry == 0) %@NL@%
  18100.         pCC->idCountry = syscc.country;%@NL@%
  18101.         %@NL@%
  18102.     ii.pCC = pCC;%@NL@%
  18103.     WinSendMsg(hConv, UMCL_INITIATE, (MPARAM)&ii, 0L);%@NL@%
  18104.     %@NL@%
  18105.     if (!((USHORT)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_STATUS, 0L) &%@NL@%
  18106.             ST_CONNECTED)) {%@NL@%
  18107.         WinDestroyWindow(hConv);%@NL@%
  18108.         return(NULL);%@NL@%
  18109.     }%@NL@%
  18110.     return(hConv);%@NL@%
  18111. }%@NL@%
  18112. %@NL@%
  18113. %@NL@%
  18114. %@NL@%
  18115. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18116. %@AB@%* This routine institutes a callback directly if psi->fEnableCB is set%@NL@%
  18117. %@AB@%* and calls QReply to complete the transaction,%@NL@%
  18118. %@AB@%* otherwise it places the data into the queue for processing.%@NL@%
  18119. %@AB@%*%@NL@%
  18120. %@AB@%* Since hDmgData may be freed by the app at any time once the callback is%@NL@%
  18121. %@AB@%* issued, we cannot depend on it being there for QReply.  Therefore we%@NL@%
  18122. %@AB@%* save all the pertinant data in the queue along with it.%@NL@%
  18123. %@AB@%*%@NL@%
  18124. %@AB@%* Returns fSuccess.%@NL@%
  18125. %@AB@%*%@NL@%
  18126. %@AB@%* History:%@NL@%
  18127. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  18128. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18129. BOOL MakeCallback(pai, hConv, hszTopic, hszItem, usFmt, usType, hDmgData,%@NL@%
  18130.     msg, fsStatus, hConvClient)%@NL@%
  18131. PAPPINFO pai;%@NL@%
  18132. HCONV hConv;%@NL@%
  18133. HSZ hszTopic;%@NL@%
  18134. HSZ hszItem;%@NL@%
  18135. USHORT usFmt;%@NL@%
  18136. USHORT usType;%@NL@%
  18137. HDMGDATA hDmgData;%@NL@%
  18138. USHORT msg;%@NL@%
  18139. USHORT fsStatus;%@NL@%
  18140. HCONV hConvClient;%@NL@%
  18141. {%@NL@%
  18142.     PCBLI pcbli;%@NL@%
  18143. %@NL@%
  18144.     SemEnter();%@NL@%
  18145.     %@NL@%
  18146.     if (!(pcbli = (PCBLI)NewLstItem(pai->plstCB, ILST_LAST))) {%@NL@%
  18147.         pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  18148.         SemLeave();%@NL@%
  18149.         return(FALSE);%@NL@%
  18150.     }%@NL@%
  18151.     pcbli->hConv = hConv;%@NL@%
  18152.     pcbli->hszTopic = hszTopic;%@NL@%
  18153.     pcbli->hszItem = hszItem;%@NL@%
  18154.     pcbli->usFmt = usFmt;%@NL@%
  18155.     pcbli->usType = usType;%@NL@%
  18156.     pcbli->hDmgData = hDmgData;%@NL@%
  18157.     pcbli->msg = msg;%@NL@%
  18158.     pcbli->fsStatus = fsStatus;%@NL@%
  18159.     pcbli->hConvPartner = hConvClient;%@NL@%
  18160.     %@NL@%
  18161.     if (pai->fEnableCB && !pai->hwndTimer) {%@NL@%
  18162.         SemLeave();%@NL@%
  18163.         WinPostMsg(pai->hwndDmg, UM_CHECKCBQ, (MPARAM)pai, 0L);%@NL@%
  18164.     } else%@NL@%
  18165.         SemLeave();%@NL@%
  18166.     %@NL@%
  18167.     return(TRUE);%@NL@%
  18168. }%@NL@%
  18169. %@NL@%
  18170. %@NL@%
  18171. %@NL@%
  18172. %@AB@%/*************************************************************************\%@NL@%
  18173. %@AB@%* Attempts to post a DDE message to hwndTo.  Properly frees up pmyddes%@NL@%
  18174. %@AB@%* if afCmd has MDPM_FREEHDATA set.  We do not add pmyddes to the target%@NL@%
  18175. %@AB@%* thread list since we assume that will be done at the receiving end%@NL@%
  18176. %@AB@%* if necessary.%@NL@%
  18177. %@AB@%*%@NL@%
  18178. %@AB@%* Returns fSuccess.%@NL@%
  18179. %@AB@%*%@NL@%
  18180. %@AB@%* 6/12/90 sanfords  Created%@NL@%
  18181. %@AB@%* 6/13/90 sanfords  Made it convert hszItem to a string at this point%@NL@%
  18182. %@AB@%*                   only if hwndTo is not a local guy.%@NL@%
  18183. %@AB@%\*************************************************************************/%@AE@%%@NL@%
  18184. BOOL MyDdePostMsg(%@NL@%
  18185. HWND hwndTo,%@NL@%
  18186. HWND hwndFrom,%@NL@%
  18187. USHORT msg,%@NL@%
  18188. PMYDDES pmyddes,%@NL@%
  18189. PAPPINFO paiFrom,%@NL@%
  18190. USHORT afCmd)%@NL@%
  18191. {%@NL@%
  18192.     PID pid;%@NL@%
  18193.     TID tid;%@NL@%
  18194.     SEL selR;%@NL@%
  18195.     BOOL fRet;%@NL@%
  18196.     PFNWP pfnwpTo;%@NL@%
  18197. %@NL@%
  18198.     if (!WinQueryWindowProcess(hwndTo, &pid, &tid))%@NL@%
  18199.         return FALSE;%@NL@%
  18200. %@NL@%
  18201.     pfnwpTo = (PFNWP)WinQueryWindowPtr(hwndTo, QWP_PFNWP);%@NL@%
  18202.     if (cMonitor || (pfnwpTo != ServerWndProc && pfnwpTo != ClientWndProc)) {%@NL@%
  18203.         %@AB@%/*%@NL@%
  18204. %@AB@%         * its not local - expand hszItem if necessary - always%@NL@%
  18205. %@AB@%         * expand if a monitor is installed.%@NL@%
  18206. %@AB@%         */%@AE@%%@NL@%
  18207.         if (CheckSel(SELECTOROF(pmyddes)) >= sizeof(MYDDES) &&%@NL@%
  18208.                 pmyddes->magic == MYDDESMAGIC &&%@NL@%
  18209.                 pmyddes->hszItem &&%@NL@%
  18210.                 !(pmyddes->fs & HDATA_PSZITEMSET)) {%@NL@%
  18211.             pmyddes->fs |= HDATA_PSZITEMSET;%@NL@%
  18212.             QueryHszName(pmyddes->hszItem, DDES_PSZITEMNAME(pmyddes),%@NL@%
  18213.                     pmyddes->offabData - pmyddes->offszItemName);    %@NL@%
  18214.         }%@NL@%
  18215.     }%@NL@%
  18216.     %@AB@%/*%@NL@%
  18217. %@AB@%     * Don't try to share seg with ourselves.%@NL@%
  18218. %@AB@%     */%@AE@%%@NL@%
  18219.     if (paiFrom->pid != pid) {%@NL@%
  18220.         selR = SELECTOROF(pmyddes);%@NL@%
  18221.         if (DosGiveSeg(SELECTOROF(pmyddes), pid, &selR))%@NL@%
  18222.             return FALSE;%@NL@%
  18223.         if (afCmd & MDPM_FREEHDATA) %@NL@%
  18224.             FreeData(pmyddes, paiFrom);%@NL@%
  18225.     } else {%@NL@%
  18226.         %@AB@%/*%@NL@%
  18227. %@AB@%         * just remove hData from our thread list%@NL@%
  18228. %@AB@%         */%@AE@%%@NL@%
  18229.         if (afCmd & MDPM_FREEHDATA && !(pmyddes->fs & HDATA_APPOWNED))%@NL@%
  18230.             FindPileItem(paiFrom->pHDataPile, CmpULONG, (PBYTE)&pmyddes,%@NL@%
  18231.                     FPI_DELETE);%@NL@%
  18232.     }%@NL@%
  18233.     fRet = (BOOL)WinPostMsg(hwndTo, msg, (MPARAM)hwndFrom, (MPARAM)pmyddes);%@NL@%
  18234.     if (!fRet) {%@NL@%
  18235.         %@AB@%/*%@NL@%
  18236. %@AB@%         * make sure this is freed if it is supposed to be - this covers%@NL@%
  18237. %@AB@%         * the case where the target is of the same process and only%@NL@%
  18238. %@AB@%         * these two threads are registered.%@NL@%
  18239. %@AB@%         */%@AE@%%@NL@%
  18240.         %@NL@%
  18241.         tid = paiFrom->tid;%@NL@%
  18242.         do {%@NL@%
  18243.             if (FindPileItem(paiFrom->pHDataPile, CmpULONG, (PBYTE)&pmyddes,%@NL@%
  18244.                     FPI_COUNT))%@NL@%
  18245.                 return(FALSE);  %@AB@%/* there is another thread that has this */%@AE@%%@NL@%
  18246.             paiFrom = paiFrom->nextThread;%@NL@%
  18247.         } while (paiFrom->tid != tid);%@NL@%
  18248.         DosFreeSeg(SELECTOROF(pmyddes));%@NL@%
  18249.     }%@NL@%
  18250.     return(fRet);%@NL@%
  18251. }%@NL@%
  18252. %@NL@%
  18253. %@NL@%
  18254. %@2@%%@AH@%DMGHSZ.C%@AE@%%@EH@%%@NL@%
  18255. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGHSZ.C%@AE@%%@NL@%
  18256. %@NL@%
  18257. %@AB@%/****************************** Module Header ******************************\%@NL@%
  18258. %@AB@%* Module Name: DMGLATOM.C%@NL@%
  18259. %@AB@%*%@NL@%
  18260. %@AB@%* This module contains functions used for HSZ control.%@NL@%
  18261. %@AB@%*%@NL@%
  18262. %@AB@%* Created:  8/2/88    sanfords%@NL@%
  18263. %@AB@%* Added case preservation/insensitive   1/22/90       Sanfords%@NL@%
  18264. %@AB@%* 6/12/90 sanfords  Fixed HSZ local string allocation size errors.%@NL@%
  18265. %@AB@%*                   Added latom validation checks%@NL@%
  18266. %@AB@%*%@NL@%
  18267. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  18268. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18269. %@AI@%#include %@AE@%"ddemlp.h" %@NL@%
  18270. %@NL@%
  18271. %@NL@%
  18272. %@AB@%/*%@NL@%
  18273. %@AB@% * since the top 12 bits of any latom is always 0 (unless we have > 16%@NL@%
  18274. %@AB@% * atom tables!) we can encode any ulong into only 5 bytes.%@NL@%
  18275. %@AB@% */%@AE@%%@NL@%
  18276. %@AI@%#define %@AE@%ENCODEBYTES         5 %@NL@%
  18277. %@AI@%#define %@AE@%MAX_LATOMSTRSIZE    255 - ENCODEBYTES - 2 %@NL@%
  18278. char szT[MAX_LATOMSTRSIZE + 1 + ENCODEBYTES];  %@AB@%/* used for HSZ expansion */%@AE@%%@NL@%
  18279. %@NL@%
  18280. extern BOOL APIENTRY WinSetAtomTableOwner( HATOMTBL, PID );%@NL@%
  18281. %@NL@%
  18282. %@NL@%
  18283. %@AB@%/*********************** LATOM management functions *************************\%@NL@%
  18284. %@AB@%* An HSZ is a long atom which holds an encoded reference to two other long%@NL@%
  18285. %@AB@%* atoms.  One long atom is for the actual string, the other is for its%@NL@%
  18286. %@AB@%* uppercase version.  Two HSZs are ranked by their uppercase latoms.%@NL@%
  18287. %@AB@%* This makes HSZs case insensitive, case preserving.  An latom%@NL@%
  18288. %@AB@%* is an atom with an atom table index tacked onto the HIUSHORT part of %@NL@%
  18289. %@AB@%* of the latom.  Strings too long for the atom manager are split up and%@NL@%
  18290. %@AB@%* each piece is prepended with a coded string that represents the%@NL@%
  18291. %@AB@%* LATOM of the rest of the string.  LATOM strings thus may be of any length.%@NL@%
  18292. %@AB@%* (up to 64K in this version)%@NL@%
  18293. %@AB@%*%@NL@%
  18294. %@AB@%* History:%@NL@%
  18295. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  18296. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18297. %@NL@%
  18298. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18299. %@AB@%* Allocates space in the DDE manager heap for a string queried from the DDE%@NL@%
  18300. %@AB@%* manager latomtable.  The case sensitive string is returned.%@NL@%
  18301. %@AB@%*%@NL@%
  18302. %@AB@%* This function should be serialized.  Memory allocation or latom table failure%@NL@%
  18303. %@AB@%* results in a 0 return value.%@NL@%
  18304. %@AB@%*%@NL@%
  18305. %@AB@%* 0 latoms result in a NULL terminated empty string.%@NL@%
  18306. %@AB@%*%@NL@%
  18307. %@AB@%* Note that *pcch is set to the length of the string INCLUDING the null%@NL@%
  18308. %@AB@%* terminator.  This way a wild string has a cch=1.%@NL@%
  18309. %@AB@%*%@NL@%
  18310. %@AB@%* History:%@NL@%
  18311. %@AB@%*   created     12/22/88        sanfords%@NL@%
  18312. %@AB@%*   11/10/89    sanfords        modified to return '\0' on invalid atom.%@NL@%
  18313. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18314. PSZ pszFromHsz(hsz, pcch)%@NL@%
  18315. HSZ hsz;%@NL@%
  18316. USHORT FAR *pcch;%@NL@%
  18317. {%@NL@%
  18318.     PSZ psz;%@NL@%
  18319.     LATOM latom;%@NL@%
  18320.     char sz[ENCODEBYTES + 1];%@NL@%
  18321.     register USHORT cch;%@NL@%
  18322. %@NL@%
  18323.     SemCheckIn();%@NL@%
  18324. %@NL@%
  18325.     if (hsz == 0)%@NL@%
  18326.         cch = 1;%@NL@%
  18327.     else {%@NL@%
  18328.         QuerylatomName((LATOM)hsz, sz, ENCODEBYTES + 1);%@NL@%
  18329.         latom = Decode(sz);     %@AB@%/* take origonal case version */%@AE@%%@NL@%
  18330.         cch = QuerylatomLength(latom) + 1;%@NL@%
  18331.     }%@NL@%
  18332.      %@NL@%
  18333.     psz = (PSZ)FarAllocMem(hheapDmg, cch);%@NL@%
  18334.     if (psz == 0) {%@NL@%
  18335.         *pcch = '\000';%@NL@%
  18336.         return(0);%@NL@%
  18337.     }%@NL@%
  18338. %@NL@%
  18339.     if (hsz == 0) {%@NL@%
  18340.         *pcch = 1;%@NL@%
  18341.         *psz = '\0';%@NL@%
  18342.     } else {%@NL@%
  18343.         *pcch = cch;%@NL@%
  18344.         if (QuerylatomName(latom, psz, cch) == 0) {%@NL@%
  18345.             AssertF(FALSE, "pszFromHsz - bad latom");%@NL@%
  18346.             *psz = '\0';        %@AB@%/* invalid case - never expected */%@AE@%%@NL@%
  18347.         }%@NL@%
  18348.     }%@NL@%
  18349.     return(psz);%@NL@%
  18350. }%@NL@%
  18351. %@NL@%
  18352. %@NL@%
  18353. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18354. %@AB@%* HSZ GetHsz(psz, cc, cp, fAdd)%@NL@%
  18355. %@AB@%* PSZ psz;%@NL@%
  18356. %@AB@%* USHORT cc;%@NL@%
  18357. %@AB@%* USHORT cp;%@NL@%
  18358. %@AB@%* BOOL fAdd;%@NL@%
  18359. %@AB@%*%@NL@%
  18360. %@AB@%* The goal of this routine is to convert a psz to an hsz.  This uses the%@NL@%
  18361. %@AB@%* atom manager for its dirty work.  This call has the side effect of%@NL@%
  18362. %@AB@%* incrementing the use count for the hsz returned and its associated latoms%@NL@%
  18363. %@AB@%* if fAdd is set.%@NL@%
  18364. %@AB@%*%@NL@%
  18365. %@AB@%* if fAdd is FALSE, NULL is returned if the hsz doesn't exist.%@NL@%
  18366. %@AB@%*%@NL@%
  18367. %@AB@%* History:%@NL@%
  18368. %@AB@%*   created     12/23/88    sanfords%@NL@%
  18369. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18370. HSZ GetHsz(psz, cc, cp, fAdd)%@NL@%
  18371. PSZ psz;%@NL@%
  18372. USHORT cc;%@NL@%
  18373. USHORT cp;%@NL@%
  18374. BOOL fAdd;%@NL@%
  18375. {%@NL@%
  18376.     LATOM latom1, latom2;%@NL@%
  18377.     USHORT cb;%@NL@%
  18378.     PSZ pszT;%@NL@%
  18379.     BOOL fNew = FALSE;%@NL@%
  18380.     HSZ hsz;%@NL@%
  18381. %@NL@%
  18382.     %@AB@%/*%@NL@%
  18383. %@AB@%     * NULL or 0 length pszs are considered wild HSZs.%@NL@%
  18384. %@AB@%     */%@AE@%%@NL@%
  18385.     if (psz == NULL || *psz == '\0')%@NL@%
  18386.         return(0L);%@NL@%
  18387. %@NL@%
  18388.     SemEnter();%@NL@%
  18389.     %@NL@%
  18390.     if (!(latom1 = FindAddlatom(psz, fAdd))) {%@NL@%
  18391.         AssertF(!fAdd, "GetHsz - Atom Add failed");%@NL@%
  18392.         SemLeave();%@NL@%
  18393.         return(0L);%@NL@%
  18394.     }%@NL@%
  18395.         %@NL@%
  18396.     cb = lstrlen(psz) + 1;%@NL@%
  18397.         %@NL@%
  18398.     if (!(pszT = FarAllocMem(hheapDmg, max(cb, ENCODEBYTES * 2 + 1)))) {%@NL@%
  18399.         SemLeave();%@NL@%
  18400.         return(0L);%@NL@%
  18401.     }%@NL@%
  18402.     %@NL@%
  18403.     CopyBlock((PBYTE)psz, (PBYTE)pszT, cb);%@NL@%
  18404.     WinUpper(DMGHAB, cp ? cp : syscc.codepage, cc ? cc : syscc.country, pszT);%@NL@%
  18405.     latom2 = FindAddlatom(pszT, fAdd);%@NL@%
  18406. %@NL@%
  18407.     if (!latom2) {%@NL@%
  18408.         AssertF(!fAdd, "GetHsz - Atom Add(2) failed");%@NL@%
  18409.         hsz = 0;%@NL@%
  18410.     } else {%@NL@%
  18411.         *Encode(latom2, Encode(latom1, pszT)) = '\000';%@NL@%
  18412.         hsz = (HSZ)FindAddlatom(pszT, fAdd);%@NL@%
  18413.     }%@NL@%
  18414.     FarFreeMem(hheapDmg, pszT, max(cb, ENCODEBYTES * 2 + 1));%@NL@%
  18415.     SemLeave();%@NL@%
  18416.     return(hsz);%@NL@%
  18417. }%@NL@%
  18418. %@NL@%
  18419. %@NL@%
  18420. %@NL@%
  18421. %@AB@%/*%@NL@%
  18422. %@AB@% * Note that all three associated latoms are freed.%@NL@%
  18423. %@AB@% */%@AE@%%@NL@%
  18424. BOOL FreeHsz(hsz)%@NL@%
  18425. HSZ hsz;%@NL@%
  18426. {%@NL@%
  18427.     char sz[ENCODEBYTES * 2 + 1];%@NL@%
  18428. %@NL@%
  18429.     SemEnter();    %@NL@%
  18430.     if (hsz && QuerylatomName((LATOM)hsz, sz, ENCODEBYTES * 2 + 1)) {%@NL@%
  18431.         Freelatom(Decode((PBYTE)sz));%@NL@%
  18432.         Freelatom(Decode((PBYTE)&sz[ENCODEBYTES]));%@NL@%
  18433.         Freelatom((LATOM)hsz);%@NL@%
  18434.     }%@NL@%
  18435.     SemLeave();%@NL@%
  18436.     return(TRUE);%@NL@%
  18437. }%@NL@%
  18438.     %@NL@%
  18439. %@NL@%
  18440. %@NL@%
  18441. %@AB@%/*%@NL@%
  18442. %@AB@% * Note that all three associated latoms are incremented.  %@NL@%
  18443. %@AB@% */%@AE@%%@NL@%
  18444. BOOL IncHszCount(hsz)%@NL@%
  18445. HSZ hsz;%@NL@%
  18446. {%@NL@%
  18447.     char sz[ENCODEBYTES * 2 + 1];%@NL@%
  18448.     register BOOL fRet;%@NL@%
  18449. %@NL@%
  18450.     if (hsz == 0)%@NL@%
  18451.         return(TRUE);%@NL@%
  18452.         %@NL@%
  18453.     SemEnter();%@NL@%
  18454.     %@NL@%
  18455.     QuerylatomName((LATOM)hsz, sz, ENCODEBYTES * 2 + 1);%@NL@%
  18456.     fRet = InclatomCount(Decode((PBYTE)sz)) &&%@NL@%
  18457.                 InclatomCount(Decode((PBYTE)&sz[ENCODEBYTES])) &&%@NL@%
  18458.                 InclatomCount((LATOM)hsz);%@NL@%
  18459.     SemLeave();%@NL@%
  18460.     return(fRet);%@NL@%
  18461. }%@NL@%
  18462. %@NL@%
  18463. %@NL@%
  18464. %@NL@%
  18465. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18466. %@AB@%* This routine adds an atom table and returns its handle.  Returns fSuccess.%@NL@%
  18467. %@AB@%*%@NL@%
  18468. %@AB@%* Effects cAtbls, aAtbls, iAtblCurrent;%@NL@%
  18469. %@AB@%*%@NL@%
  18470. %@AB@%* History:%@NL@%
  18471. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  18472. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18473. BOOL AddAtomTable(fInit)%@NL@%
  18474. BOOL fInit;%@NL@%
  18475. {%@NL@%
  18476.     PHATOMTBL pat;%@NL@%
  18477. %@NL@%
  18478.     SemEnter();    %@NL@%
  18479. %@NL@%
  18480.     if (!(pat = (PHATOMTBL)FarAllocMem(hheapDmg,%@NL@%
  18481.             sizeof(HATOMTBL) * (cAtbls + 1)))) {%@NL@%
  18482.         SemLeave();%@NL@%
  18483.         return(FALSE);%@NL@%
  18484.     }%@NL@%
  18485.     %@NL@%
  18486.     if (!fInit) {%@NL@%
  18487.         CopyBlock((PBYTE)aAtbls, (PBYTE)pat, sizeof(HATOMTBL) * cAtbls);%@NL@%
  18488.         FarFreeMem(hheapDmg, aAtbls, sizeof(HATOMTBL) * cAtbls);%@NL@%
  18489.     }%@NL@%
  18490.     %@NL@%
  18491.     aAtbls = pat;%@NL@%
  18492. %@NL@%
  18493.     if (!(aAtbls[cAtbls] = WinCreateAtomTable(0, 0))) %@NL@%
  18494.         return(FALSE);%@NL@%
  18495.     %@AB@%/*%@NL@%
  18496. %@AB@%     * Share our atom tables with all processes...%@NL@%
  18497. %@AB@%     */%@AE@%%@NL@%
  18498.     if (!WinSetAtomTableOwner(aAtbls[cAtbls], NULL)) {%@NL@%
  18499.         AssertF(FALSE, "AddAtomTable - WinSetAtomTable failed");%@NL@%
  18500.         return(FALSE);%@NL@%
  18501.     }%@NL@%
  18502.     iAtblCurrent = cAtbls++;%@NL@%
  18503.     SemLeave();%@NL@%
  18504.     return(TRUE);%@NL@%
  18505. }%@NL@%
  18506. %@NL@%
  18507. %@NL@%
  18508. %@NL@%
  18509. USHORT QueryHszLength(hsz)%@NL@%
  18510. HSZ hsz;%@NL@%
  18511. {%@NL@%
  18512.     char sz[ENCODEBYTES + 1];%@NL@%
  18513.     USHORT us;%@NL@%
  18514. %@NL@%
  18515.     if (!hsz) %@NL@%
  18516.         return(0);%@NL@%
  18517.     SemEnter();%@NL@%
  18518.     QuerylatomName((LATOM)hsz, sz, ENCODEBYTES + 1);%@NL@%
  18519.     us = QuerylatomLength(Decode(sz));%@NL@%
  18520.     SemLeave();%@NL@%
  18521.     return(us);%@NL@%
  18522. }%@NL@%
  18523. %@NL@%
  18524. %@NL@%
  18525. %@NL@%
  18526. USHORT QueryHszName(hsz, psz, cchMax)%@NL@%
  18527. HSZ hsz;%@NL@%
  18528. PSZ psz;%@NL@%
  18529. USHORT cchMax;%@NL@%
  18530. {%@NL@%
  18531.     char sz[ENCODEBYTES + 1];%@NL@%
  18532.     register USHORT usRet;%@NL@%
  18533.     %@NL@%
  18534.     if (hsz == 0) {%@NL@%
  18535.         if (psz)%@NL@%
  18536.             *psz = '\000';%@NL@%
  18537.         return(1);%@NL@%
  18538.     } else {%@NL@%
  18539.         usRet = 0;%@NL@%
  18540.         SemEnter();%@NL@%
  18541.         if (QuerylatomName((LATOM)hsz, sz, ENCODEBYTES + 1))%@NL@%
  18542.             usRet = QuerylatomName(Decode(sz), psz, cchMax);%@NL@%
  18543.         SemLeave();%@NL@%
  18544.         return(usRet);%@NL@%
  18545.     }%@NL@%
  18546. }%@NL@%
  18547.      %@NL@%
  18548. %@NL@%
  18549. %@NL@%
  18550. %@AB@%/*%@NL@%
  18551. %@AB@% * returns 0 if ==, -1 if hsz1 < hsz2, 1 if hsz1 > hsz2, 2 on error%@NL@%
  18552. %@AB@% */%@AE@%%@NL@%
  18553. SHORT CmpHsz(hsz1, hsz2)%@NL@%
  18554. HSZ hsz1, hsz2;%@NL@%
  18555. {%@NL@%
  18556.     char sz[ENCODEBYTES * 2 + 1];%@NL@%
  18557.     LATOM latom;%@NL@%
  18558.     SHORT usRet;%@NL@%
  18559.     %@NL@%
  18560.     if (hsz1 == hsz2)%@NL@%
  18561.         return(0);%@NL@%
  18562.     if (!hsz1) %@NL@%
  18563.         return(-1);%@NL@%
  18564.     if (!hsz2)%@NL@%
  18565.         return(1);%@NL@%
  18566. %@NL@%
  18567.     usRet = 2;%@NL@%
  18568.     SemEnter();%@NL@%
  18569.     if (QuerylatomName((LATOM)hsz1, sz, ENCODEBYTES * 2 + 1)) {%@NL@%
  18570.         latom = Decode(&sz[ENCODEBYTES]);   %@AB@%/* use UPPERCASE form for comparison. */%@AE@%%@NL@%
  18571.         if (QuerylatomName((LATOM)hsz2, sz, ENCODEBYTES * 2 + 1)) {%@NL@%
  18572.             latom = latom - Decode(&sz[ENCODEBYTES]);%@NL@%
  18573.             usRet = latom == 0 ? 0 : (latom > 0 ? 1 : -1);%@NL@%
  18574.         }%@NL@%
  18575.     }%@NL@%
  18576.     SemLeave();%@NL@%
  18577.     return(usRet);%@NL@%
  18578. }%@NL@%
  18579. %@NL@%
  18580. %@NL@%
  18581.     %@NL@%
  18582. %@NL@%
  18583. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18584. %@AB@%* Returns the length of the latom given without NULL terminator.%@NL@%
  18585. %@AB@%* Wild LATOMs have a length of 0.%@NL@%
  18586. %@AB@%*%@NL@%
  18587. %@AB@%* History:%@NL@%
  18588. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  18589. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18590. USHORT QuerylatomLength(latom)%@NL@%
  18591. LATOM latom;%@NL@%
  18592. {%@NL@%
  18593.     USHORT cb;%@NL@%
  18594.     USHORT cbT = 0;%@NL@%
  18595.     BYTE ab[ENCODEBYTES + 1];%@NL@%
  18596. %@NL@%
  18597.     AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");%@NL@%
  18598.     if (latom == 0)%@NL@%
  18599.         return(0);%@NL@%
  18600.     SemCheckIn();%@NL@%
  18601.     while (TRUE) {%@NL@%
  18602.         if (!(cb = WinQueryAtomLength(aAtbls[HIUSHORT(latom)],%@NL@%
  18603.                 LOUSHORT(latom)))) {%@NL@%
  18604.             AssertF(cbT == 0, "QuerylatomLength - failed on continued latom");%@NL@%
  18605.             return(0);%@NL@%
  18606.         }%@NL@%
  18607.             %@NL@%
  18608.         cbT += cb;%@NL@%
  18609.         %@NL@%
  18610.         if (cb <= MAX_LATOMSTRSIZE) {%@NL@%
  18611.             return(cbT);%@NL@%
  18612.         }%@NL@%
  18613.             %@NL@%
  18614.         %@AB@%/*%@NL@%
  18615. %@AB@%         * it MUST be a huge latom.%@NL@%
  18616. %@AB@%         */%@AE@%%@NL@%
  18617.         if (!(WinQueryAtomName(aAtbls[HIUSHORT(latom)], LOUSHORT(latom),%@NL@%
  18618.                 (PSZ)ab, ENCODEBYTES + 1))) {%@NL@%
  18619.             AssertF(FALSE, "QuerylatomLength - Length but no name");%@NL@%
  18620.             return(0);%@NL@%
  18621.         }%@NL@%
  18622.             %@NL@%
  18623.         latom = Decode(ab);%@NL@%
  18624.         cbT -= ENCODEBYTES;%@NL@%
  18625.     }%@NL@%
  18626. }%@NL@%
  18627. %@NL@%
  18628. %@NL@%
  18629. %@NL@%
  18630. USHORT QuerylatomName(latom, psz, cchMax)%@NL@%
  18631. LATOM latom;%@NL@%
  18632. PSZ psz;%@NL@%
  18633. USHORT cchMax;%@NL@%
  18634. {%@NL@%
  18635.     USHORT cb;%@NL@%
  18636.     extern char szT[];%@NL@%
  18637. %@NL@%
  18638.     if (HIUSHORT(latom) >= cAtbls) {%@NL@%
  18639.         AssertF(FALSE, "Invalid latom");%@NL@%
  18640.         psz[0] = '\0';%@NL@%
  18641.         return(0);%@NL@%
  18642.     }%@NL@%
  18643.     %@NL@%
  18644.     AssertF(latom != 0, "QuerylatomName - 0 latom");%@NL@%
  18645.     SemCheckIn();%@NL@%
  18646.     cb = WinQueryAtomLength(aAtbls[HIUSHORT(latom)], LOUSHORT(latom));%@NL@%
  18647.     if (cb > MAX_LATOMSTRSIZE) {%@NL@%
  18648.         if (!WinQueryAtomName(aAtbls[HIUSHORT(latom)], LOUSHORT(latom), szT,%@NL@%
  18649.                 MAX_LATOMSTRSIZE + ENCODEBYTES + 1)) {%@NL@%
  18650.             AssertF(FALSE, "QuerylatomName - length but no name");%@NL@%
  18651.             return(0);%@NL@%
  18652.         }%@NL@%
  18653.         CopyBlock(szT + ENCODEBYTES, psz, min(MAX_LATOMSTRSIZE, cchMax));%@NL@%
  18654.         latom = Decode((PBYTE)szT);%@NL@%
  18655.         cb = MAX_LATOMSTRSIZE + QuerylatomName(latom, psz + MAX_LATOMSTRSIZE,%@NL@%
  18656.                 cchMax > MAX_LATOMSTRSIZE ? cchMax - MAX_LATOMSTRSIZE : 0);%@NL@%
  18657.         %@NL@%
  18658.     } else {%@NL@%
  18659.         WinQueryAtomName(aAtbls[HIUSHORT(latom)], LOUSHORT(latom), psz, cchMax);%@NL@%
  18660.     }%@NL@%
  18661.     psz[cchMax - 1] = '\0';     %@AB@%/* add NULL terminator */%@AE@%%@NL@%
  18662.     return(min(cb, cchMax - 1));%@NL@%
  18663. }%@NL@%
  18664. %@NL@%
  18665. %@NL@%
  18666. %@NL@%
  18667. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18668. %@AB@%* This uses globals szT, aAtbls, cAtbls, and iAtblCurrent to add or%@NL@%
  18669. %@AB@%* find the latom for psz depending on fAdd.%@NL@%
  18670. %@AB@%*%@NL@%
  18671. %@AB@%* History:%@NL@%
  18672. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  18673. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18674. LATOM FindAddlatom(psz, fAdd)%@NL@%
  18675. PSZ psz;%@NL@%
  18676. BOOL fAdd;%@NL@%
  18677. {%@NL@%
  18678.     LATOM latom;%@NL@%
  18679. %@NL@%
  18680.     AssertF(psz != NULL, "FindAddlatom - NULL psz");%@NL@%
  18681.     AssertF(*psz != '\0', "FindAddlatom - NULL psz string");%@NL@%
  18682.     SemCheckIn();%@NL@%
  18683.     if (lstrlen(psz) > MAX_LATOMSTRSIZE) {%@NL@%
  18684.         latom = FindAddlatom(psz + MAX_LATOMSTRSIZE, fAdd);%@NL@%
  18685.         CopyBlock((PBYTE)psz, Encode((ULONG)latom, szT),%@NL@%
  18686.                 (ULONG)MAX_LATOMSTRSIZE - ENCODEBYTES + 1);%@NL@%
  18687.         szT[MAX_LATOMSTRSIZE + ENCODEBYTES] = '\0';%@NL@%
  18688.         latom = FindAddlatomHelper(szT, fAdd);%@NL@%
  18689.         return(latom);%@NL@%
  18690.     } else {%@NL@%
  18691.         return(FindAddlatomHelper(psz, fAdd));%@NL@%
  18692.     }%@NL@%
  18693. }%@NL@%
  18694. %@NL@%
  18695. %@NL@%
  18696. %@NL@%
  18697. %@NL@%
  18698. LATOM FindAddlatomHelper(psz, fAdd)%@NL@%
  18699. PSZ psz;%@NL@%
  18700. BOOL fAdd;%@NL@%
  18701. {%@NL@%
  18702.     int i;%@NL@%
  18703.     ATOM atom;%@NL@%
  18704.     ATOM (APIENTRY *lpfn)(HATOMTBL, PSZ);%@NL@%
  18705.     %@NL@%
  18706.     SemCheckIn();%@NL@%
  18707.     if (fAdd) {%@NL@%
  18708.         AssertF(++cAtoms, "Possible atom count overflow");%@NL@%
  18709.         lpfn = WinAddAtom;%@NL@%
  18710.     } else %@NL@%
  18711.         lpfn = WinFindAtom;%@NL@%
  18712. %@NL@%
  18713.     if (!(atom = (*lpfn)(aAtbls[i = iAtblCurrent], psz))) {%@NL@%
  18714.         %@AB@%/*%@NL@%
  18715. %@AB@%         * Must be full/not found, try all the existing tables%@NL@%
  18716. %@AB@%         */%@AE@%%@NL@%
  18717.         for (i = 0; i < cAtbls; i++) {%@NL@%
  18718.             if (i != iAtblCurrent) {%@NL@%
  18719.                 if (atom = (*lpfn)(aAtbls[i], psz)) {%@NL@%
  18720.                     if (fAdd)%@NL@%
  18721.                         iAtblCurrent = i;%@NL@%
  18722.                     break;%@NL@%
  18723.                 }%@NL@%
  18724.             }%@NL@%
  18725.         }%@NL@%
  18726.          %@NL@%
  18727.         if (!atom) {%@NL@%
  18728.             if (fAdd) {%@NL@%
  18729.                 %@AB@%/*%@NL@%
  18730. %@AB@%                 * they're all full, make another table.%@NL@%
  18731. %@AB@%                 */%@AE@%%@NL@%
  18732.                 if (!AddAtomTable(FALSE)) {%@NL@%
  18733.                     return(0L);%@NL@%
  18734.                 }%@NL@%
  18735.                 if (!(atom = (*lpfn)(aAtbls[iAtblCurrent], psz))) {%@NL@%
  18736.                     return(0L); %@NL@%
  18737.                 }%@NL@%
  18738.             } else {%@NL@%
  18739.                 return(0L);%@NL@%
  18740.             }%@NL@%
  18741.         }%@NL@%
  18742.     }%@NL@%
  18743.     return((LATOM)MAKEP(i, atom));%@NL@%
  18744. }%@NL@%
  18745. %@NL@%
  18746. %@NL@%
  18747.     %@NL@%
  18748.     %@NL@%
  18749. %@NL@%
  18750. BOOL InclatomCount(latom)%@NL@%
  18751. LATOM latom;%@NL@%
  18752. {%@NL@%
  18753.     AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");%@NL@%
  18754.     AssertF(latom != 0, "InclatomCount - 0 latom");%@NL@%
  18755.     SemCheckIn();%@NL@%
  18756.     AssertF(++cAtoms, "Possible atom count overflow");%@NL@%
  18757.     return(WinAddAtom(aAtbls[HIUSHORT(latom)], MAKEP(0XFFFF, LOUSHORT(latom))));%@NL@%
  18758. }%@NL@%
  18759. %@NL@%
  18760. %@NL@%
  18761. %@NL@%
  18762. BOOL Freelatom(latom)%@NL@%
  18763. LATOM latom;%@NL@%
  18764. {%@NL@%
  18765.     AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");%@NL@%
  18766.     AssertF(latom != 0, "Freelatom - 0 latom");%@NL@%
  18767.     AssertF(WinQueryAtomUsage(aAtbls[HIUSHORT(latom)], LOUSHORT(latom)),%@NL@%
  18768.             "Freelatom - Freeing Non-existing atom");%@NL@%
  18769.     SemCheckIn();%@NL@%
  18770.         %@NL@%
  18771.     if (WinDeleteAtom(aAtbls[HIUSHORT(latom)], LOUSHORT(latom))) {%@NL@%
  18772.         AssertF(FALSE, "Freelatom - WinDeleteAtom failed");%@NL@%
  18773.         return(FALSE);%@NL@%
  18774.     }%@NL@%
  18775.     AssertF(--cAtoms >= 0, "Freelatom - negative atom count");%@NL@%
  18776.     return(TRUE);%@NL@%
  18777. }%@NL@%
  18778. %@NL@%
  18779. %@NL@%
  18780. %@NL@%
  18781. %@NL@%
  18782. %@AI@%#ifdef %@AE@%DEBUG %@NL@%
  18783. BASEVAL '0'     %@AB@%/* more readable for debugging */%@AE@%%@NL@%
  18784. %@AI@%#else %@AE@%%@NL@%
  18785. BASEVAL 1       %@AB@%/* less likely to conflict with a string */%@AE@%%@NL@%
  18786. %@AI@%#endif %@AE@%%@NL@%
  18787. %@NL@%
  18788. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18789. %@AB@%* Converts an latom into a ENCODEBYTES character string apropriate for%@NL@%
  18790. %@AB@%* atomization. (NULL terminator must be added)%@NL@%
  18791. %@AB@%*%@NL@%
  18792. %@AB@%* History:%@NL@%
  18793. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  18794. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18795. PBYTE Encode(latom, pb)%@NL@%
  18796. ULONG latom;%@NL@%
  18797. PBYTE pb;%@NL@%
  18798. {%@NL@%
  18799.     int i;%@NL@%
  18800. %@NL@%
  18801.     %@NL@%
  18802.     AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");%@NL@%
  18803.     for (i = 0; i < ENCODEBYTES; i++) {%@NL@%
  18804.         *pb++ = ((BYTE)latom & 0x0F) + BASEVAL;%@NL@%
  18805.         latom >>= 4;%@NL@%
  18806.     }%@NL@%
  18807.     return(pb);%@NL@%
  18808. }%@NL@%
  18809. %@NL@%
  18810. %@NL@%
  18811. %@NL@%
  18812. %@AB@%/***************************** Private Function ****************************\%@NL@%
  18813. %@AB@%* This takes a pointer to a buffer of 8 bytes which is a coded LATOM and%@NL@%
  18814. %@AB@%* returns the LATOM.%@NL@%
  18815. %@AB@%*%@NL@%
  18816. %@AB@%* History:%@NL@%
  18817. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  18818. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18819. LATOM Decode(pb)%@NL@%
  18820. PBYTE pb;%@NL@%
  18821. {%@NL@%
  18822.     ULONG ul = 0;%@NL@%
  18823.     int i;%@NL@%
  18824. %@NL@%
  18825.     for (i = ENCODEBYTES - 1; i >= 0; i--) {%@NL@%
  18826.         ul <<= 4;%@NL@%
  18827.         ul += (ULONG)(pb[i] - BASEVAL);%@NL@%
  18828.     }%@NL@%
  18829.     return((LATOM)ul);%@NL@%
  18830. }%@NL@%
  18831. %@NL@%
  18832. %@NL@%
  18833. %@AB@%/*%@NL@%
  18834. %@AB@% * This routine extracts the hszItem out of an existing hData handle.%@NL@%
  18835. %@AB@% * local conversations can use the hsz directly out of the handle while%@NL@%
  18836. %@AB@% * non-dll conversations will have to generate the hsz from the string.%@NL@%
  18837. %@AB@% */%@AE@%%@NL@%
  18838. HSZ GetHszItem(%@NL@%
  18839. PMYDDES pmyddes,%@NL@%
  18840. PCONVCONTEXT pCC,%@NL@%
  18841. BOOL fAdd)%@NL@%
  18842. {%@NL@%
  18843.     if (CheckSel(SELECTOROF(pmyddes)) >= sizeof(MYDDES) &&%@NL@%
  18844.             pmyddes->magic == MYDDESMAGIC) {%@NL@%
  18845.         if (fAdd) %@NL@%
  18846.             IncHszCount(pmyddes->hszItem);%@NL@%
  18847.         return(pmyddes->hszItem);%@NL@%
  18848.     } else {%@NL@%
  18849.         return(GetHsz(DDES_PSZITEMNAME(pmyddes), pCC->idCountry,%@NL@%
  18850.                 pCC->usCodepage, fAdd));%@NL@%
  18851.     }%@NL@%
  18852. }%@NL@%
  18853. %@NL@%
  18854. %@NL@%
  18855. %@2@%%@AH@%DMGMON.C%@AE@%%@EH@%%@NL@%
  18856. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGMON.C%@AE@%%@NL@%
  18857. %@NL@%
  18858. %@AB@%/****************************** Module Header ******************************\%@NL@%
  18859. %@AB@%* Module Name: DMGMON.C%@NL@%
  18860. %@AB@%*%@NL@%
  18861. %@AB@%* This module contains functions used for DDE monitor control.%@NL@%
  18862. %@AB@%*%@NL@%
  18863. %@AB@%* Created:  8/2/88    sanfords%@NL@%
  18864. %@AB@%*%@NL@%
  18865. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  18866. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  18867. %@AI@%#include %@AE@%"ddemlp.h" %@NL@%
  18868. %@AI@%#define %@AE@%MSGF_DDEPOSTMSG     3 %@NL@%
  18869. %@NL@%
  18870. %@AI@%#define %@AE@%freeMonStr(psz) MyFreeMem(hheapDmg, (NPBYTE)(USHORT)psz, MAX_MONITORSTR + 1) %@NL@%
  18871. %@NL@%
  18872. %@NL@%
  18873. BOOL EXPENTRY DdeSendHookProc(hab, psmh, fInterTask)%@NL@%
  18874. HAB hab;%@NL@%
  18875. PSMHSTRUCT psmh;%@NL@%
  18876. BOOL fInterTask;%@NL@%
  18877. {%@NL@%
  18878.     PSZ psz;%@NL@%
  18879.     PSZ pszSave;%@NL@%
  18880.     PSZ pszLast;%@NL@%
  18881. %@NL@%
  18882.     UNUSED hab;%@NL@%
  18883.     UNUSED fInterTask;%@NL@%
  18884.     %@NL@%
  18885.     if (psmh->msg == WM_DDE_INITIATE || psmh->msg == WM_DDE_INITIATEACK) {%@NL@%
  18886.         if (allocMonStr(&pszSave, &pszLast)) {%@NL@%
  18887.             psz = timestamp(pszSave, pszLast);%@NL@%
  18888.             psz = lstrcat(psz, " ", pszLast);%@NL@%
  18889.             psz = ltoa((ULONG)psmh->mp1, psz, pszLast);%@NL@%
  18890.             psz = lstrcat(psz, " -> ", pszLast);%@NL@%
  18891.             psz = ltoa((ULONG)psmh->hwnd, psz, pszLast);%@NL@%
  18892.             psz = lstrcat(psz, "\n\r", pszLast);%@NL@%
  18893.             psz = ddeMsgToPsz(psmh->msg, psz, pszLast);%@NL@%
  18894.             psz = pddesToPsz(psmh->msg, (PDDESTRUCT)psmh->mp2, psz, pszLast);%@NL@%
  18895.             psz = lstrcat(psz, ")\n\r", pszLast);%@NL@%
  18896.             MonitorBroadcast(pszSave);%@NL@%
  18897.             freeMonStr(pszSave);%@NL@%
  18898.         }%@NL@%
  18899.     }%@NL@%
  18900.     return(FALSE);%@NL@%
  18901. }%@NL@%
  18902. %@NL@%
  18903. %@NL@%
  18904. %@NL@%
  18905. %@NL@%
  18906. BOOL EXPENTRY DdePostHookProc(hab, pqmsg, fs)%@NL@%
  18907. HAB hab;%@NL@%
  18908. PQMSG pqmsg;%@NL@%
  18909. USHORT fs;%@NL@%
  18910. {%@NL@%
  18911.     PSZ psz;%@NL@%
  18912.     PSZ pszSave;%@NL@%
  18913.     PSZ pszLast;%@NL@%
  18914. %@NL@%
  18915.     UNUSED hab;%@NL@%
  18916. %@NL@%
  18917.     if (fs && pqmsg->msg >= WM_DDE_FIRST && pqmsg->msg <= WM_DDE_LAST) {%@NL@%
  18918.         pszLast = psz + MAX_MONITORSTR;  %@NL@%
  18919.         if (allocMonStr(&pszSave, &pszLast)) {%@NL@%
  18920.             psz = timestamp(pszSave, pszLast);%@NL@%
  18921.             psz = lstrcat(psz, " ", pszLast);%@NL@%
  18922.             psz = ltoa((ULONG)pqmsg->mp1, psz, pszLast);%@NL@%
  18923.             psz = lstrcat(psz, " -> ", pszLast);%@NL@%
  18924.             psz = ltoa((ULONG)pqmsg->hwnd, psz, pszLast);%@NL@%
  18925.             psz = lstrcat(psz, "\n\r", pszLast);%@NL@%
  18926.             psz = ddeMsgToPsz(pqmsg->msg, psz, pszLast);%@NL@%
  18927.             psz = pddesToPsz(pqmsg->msg, (PDDESTRUCT)pqmsg->mp2, psz, pszLast);%@NL@%
  18928.             psz = lstrcat(psz, ")\n\r", pszLast);%@NL@%
  18929.             MonitorBroadcast(pszSave);%@NL@%
  18930.             freeMonStr(pszSave);%@NL@%
  18931.         }%@NL@%
  18932.     }%@NL@%
  18933.     return(FALSE);%@NL@%
  18934. }%@NL@%
  18935. %@NL@%
  18936. %@AB@%/*%@NL@%
  18937. %@AB@% * This guy sends a UM_MONITOR to all the monitor windows (up to MAX_MONITOR)%@NL@%
  18938. %@AB@% * The cheap restriction is due to needing to not be in the semaphore%@NL@%
  18939. %@AB@% * while the monitor is in control yet needing to keep access to pai in%@NL@%
  18940. %@AB@% * the semaphore.%@NL@%
  18941. %@AB@% */%@AE@%%@NL@%
  18942. void MonitorBroadcast(psz)%@NL@%
  18943. PSZ psz;%@NL@%
  18944. {%@NL@%
  18945.     HWND hwnd[MAX_MONITORS];%@NL@%
  18946.     PAPPINFO pai;%@NL@%
  18947.     register USHORT i = 0;%@NL@%
  18948. %@NL@%
  18949.     SemCheckOut();%@NL@%
  18950.     SemEnter();%@NL@%
  18951.     pai = pAppInfoList;%@NL@%
  18952.     while (pai && i < cMonitor && i < MAX_MONITORS) {%@NL@%
  18953.         if (pai->hwndMonitor) {%@NL@%
  18954.             hwnd[i] = pai->hwndMonitor;%@NL@%
  18955.             i++;%@NL@%
  18956.         }%@NL@%
  18957.         pai = pai->next;%@NL@%
  18958.     }%@NL@%
  18959.     SemLeave();%@NL@%
  18960.     %@NL@%
  18961.     for (i = 0; i < cMonitor; i++)%@NL@%
  18962.         WinSendMsg(hwnd[i], UM_MONITOR, (MPARAM)psz, 0L);%@NL@%
  18963. }%@NL@%
  18964. %@NL@%
  18965. %@NL@%
  18966. %@AB@%/*%@NL@%
  18967. %@AB@% * We need to allocate the string buffer so that recursive calls will work.%@NL@%
  18968. %@AB@% * We also need to do this because the DLL DS is shared between all potential%@NL@%
  18969. %@AB@% * monitor processes.%@NL@%
  18970. %@AB@% *%@NL@%
  18971. %@AB@% * This also initializes the psz for us with a null terminator and checks%@NL@%
  18972. %@AB@% * cMonitor for us.  If this fails, no monitor action is done.%@NL@%
  18973. %@AB@% *%@NL@%
  18974. %@AB@% * ppsz will contain a pointer to the begining of the allocated buffer.%@NL@%
  18975. %@AB@% * ppszLast will contain a pointer to the end of the allocated buffer.%@NL@%
  18976. %@AB@% */%@AE@%%@NL@%
  18977. BOOL allocMonStr(ppsz, ppszLast)%@NL@%
  18978. PSZ far *ppsz;%@NL@%
  18979. PSZ far *ppszLast;%@NL@%
  18980. {%@NL@%
  18981.     SemEnter();%@NL@%
  18982.     if (cMonitor == 0 ||%@NL@%
  18983.             ((*ppsz = FarAllocMem(hheapDmg, MAX_MONITORSTR + 1)) == NULL)) {%@NL@%
  18984.         SemLeave();%@NL@%
  18985.         return(FALSE);%@NL@%
  18986.     }%@NL@%
  18987.     *ppszLast = *ppsz + MAX_MONITORSTR;%@NL@%
  18988.     **ppsz = '\0';%@NL@%
  18989.     SemLeave();%@NL@%
  18990.     return(TRUE);%@NL@%
  18991. }%@NL@%
  18992. %@NL@%
  18993. %@NL@%
  18994. %@NL@%
  18995. MRESULT EXPENTRY MonitorWndProc(hwnd, msg, mp1, mp2)%@NL@%
  18996. HWND hwnd;%@NL@%
  18997. USHORT msg;%@NL@%
  18998. register MPARAM mp1;%@NL@%
  18999. MPARAM mp2;%@NL@%
  19000. {%@NL@%
  19001.     PAPPINFO pai;%@NL@%
  19002.     HDMGDATA hDmgData;%@NL@%
  19003. %@NL@%
  19004.     pai = GetCurrentAppInfo(FALSE);%@NL@%
  19005. %@NL@%
  19006.     switch (msg) {%@NL@%
  19007.     case WM_CREATE:%@NL@%
  19008.         mp1  = (PSZ)"\n\rMonitor Created\n\r\n\r";%@NL@%
  19009.         goto MonOut;%@NL@%
  19010.         break;%@NL@%
  19011. %@NL@%
  19012.     case WM_DESTROY:%@NL@%
  19013.         mp1 = (PSZ)"\n\r\n\rMonitor Destroyed\n\r";%@NL@%
  19014.         %@AB@%/* fall through */%@AE@%%@NL@%
  19015. %@NL@%
  19016.     case UM_MONITOR:%@NL@%
  19017.         %@AB@%/*%@NL@%
  19018. %@AB@%         * mp1 = psz to print%@NL@%
  19019. %@AB@%         */%@AE@%%@NL@%
  19020. MonOut:%@NL@%
  19021.         hDmgData = DdePutData((PSZ)mp1, (ULONG)(lstrlen(mp1) + 1),%@NL@%
  19022.                 0L, (HSZ)0L, DDEFMT_TEXT, 0);%@NL@%
  19023.         pai->cInCallback++;%@NL@%
  19024.         DoCallback(pai, 0, 0, 0, DDEFMT_TEXT, XTYP_MONITOR, hDmgData);%@NL@%
  19025.         if (pai->cInCallback > 0)   %@AB@%/* test incase exitlist processing messed things up */%@AE@%%@NL@%
  19026.             pai->cInCallback--;%@NL@%
  19027.         break;%@NL@%
  19028. %@NL@%
  19029.     default:%@NL@%
  19030.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  19031.         break;%@NL@%
  19032.     }%@NL@%
  19033. %@NL@%
  19034.     return(0);%@NL@%
  19035. }%@NL@%
  19036. %@NL@%
  19037. %@NL@%
  19038. %@NL@%
  19039. %@NL@%
  19040. %@2@%%@AH@%DMGQ.C%@AE@%%@EH@%%@NL@%
  19041. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGQ.C%@AE@%%@NL@%
  19042. %@NL@%
  19043. %@AB@%/****************************** Module Header ******************************\%@NL@%
  19044. %@AB@%* Module Name: DMGQ.C%@NL@%
  19045. %@AB@%*%@NL@%
  19046. %@AB@%* DDE Manager queue control functions.%@NL@%
  19047. %@AB@%*%@NL@%
  19048. %@AB@%* Created: 9/1/89 Sanford Staab%@NL@%
  19049. %@AB@%*%@NL@%
  19050. %@AB@%* This is a general queue manager - yes another one!%@NL@%
  19051. %@AB@%* Queues are each allocated within their own segment and have a%@NL@%
  19052. %@AB@%* QST structure associated with that heap.  Each queue item%@NL@%
  19053. %@AB@%* is allocated within the heap segment.  The offset of the items%@NL@%
  19054. %@AB@%* address combined with an instance count is used as the item ID.%@NL@%
  19055. %@AB@%* This is both unique and allows for instant location of an item.%@NL@%
  19056. %@AB@%* New items are added to the head of the queue which is a doubly linked%@NL@%
  19057. %@AB@%* list.  The next links point to more recent entries, the prev pointers%@NL@%
  19058. %@AB@%* to older entries.  The next of the head is the tail.  The prev of the%@NL@%
  19059. %@AB@%* tail is the head.  All pointers are far.%@NL@%
  19060. %@AB@%* Queue Data may be of any structure type that begins identical to%@NL@%
  19061. %@AB@%* a QUEUEITEM structure.  Functions that require an cbItem perameter%@NL@%
  19062. %@AB@%* should be given the size of the specialized queue item structure.%@NL@%
  19063. %@AB@%*%@NL@%
  19064. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  19065. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19066. %@NL@%
  19067. %@AI@%#include %@AE@%"ddemlp.h" %@NL@%
  19068. %@NL@%
  19069. %@NL@%
  19070. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19071. %@AB@%*%@NL@%
  19072. %@AB@%* Creates a Queue for items of cbItem.%@NL@%
  19073. %@AB@%* Returns NULL on error.%@NL@%
  19074. %@AB@%*%@NL@%
  19075. %@AB@%*%@NL@%
  19076. %@AB@%* History:%@NL@%
  19077. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  19078. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19079. PQST CreateQ(cbItem)%@NL@%
  19080. USHORT cbItem;%@NL@%
  19081. {%@NL@%
  19082.     QST cq;%@NL@%
  19083.     PQST pQ;%@NL@%
  19084.     %@NL@%
  19085.     cq.cItems = 0;%@NL@%
  19086.     cq.instLast = 0;%@NL@%
  19087.     cq.cbItem = cbItem;%@NL@%
  19088.     cq.pqiHead = NULL;%@NL@%
  19089.     if (!(cq.hheap = MyCreateHeap(0, sizeof(QST) + cbItem << 3,%@NL@%
  19090.             cbItem << 3, cbItem, cbItem, HEAPFLAGS)))%@NL@%
  19091.         return(NULL);%@NL@%
  19092.     if (!(pQ = (PQST)FarAllocMem(cq.hheap, sizeof(QST)))) {%@NL@%
  19093.         MyDestroyHeap(cq.hheap);%@NL@%
  19094.         return(0);%@NL@%
  19095.     }%@NL@%
  19096.     *pQ = cq;%@NL@%
  19097.     return(pQ);%@NL@%
  19098. }%@NL@%
  19099. %@NL@%
  19100. %@NL@%
  19101. %@NL@%
  19102. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19103. %@AB@%*%@NL@%
  19104. %@AB@%*%@NL@%
  19105. %@AB@%* History:%@NL@%
  19106. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  19107. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19108. BOOL DestroyQ(pQ)%@NL@%
  19109. PQST pQ;%@NL@%
  19110. {%@NL@%
  19111.     if (pQ)%@NL@%
  19112.         MyDestroyHeap(pQ->hheap);%@NL@%
  19113.     return(TRUE);%@NL@%
  19114. }%@NL@%
  19115. %@NL@%
  19116. %@NL@%
  19117. %@NL@%
  19118. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19119. %@AB@%*%@NL@%
  19120. %@AB@%* returns a long pointer to the queue item data created.  The new item%@NL@%
  19121. %@AB@%* is added to the head of the queue.  The queue's cbItem specified at%@NL@%
  19122. %@AB@%* creation is used for allocation.%@NL@%
  19123. %@AB@%*%@NL@%
  19124. %@AB@%*%@NL@%
  19125. %@AB@%* History:%@NL@%
  19126. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  19127. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19128. PQUEUEITEM Addqi(pQ)%@NL@%
  19129. PQST pQ;%@NL@%
  19130. {%@NL@%
  19131.     PQUEUEITEM pqi;%@NL@%
  19132. %@NL@%
  19133.     if ((pqi = (PQUEUEITEM)FarAllocMem(pQ->hheap, pQ->cbItem)) == NULL) {%@NL@%
  19134.         if (pQ->cItems == 0)%@NL@%
  19135.             return(0);%@NL@%
  19136.         %@AB@%/*%@NL@%
  19137. %@AB@%         * remove the oldest item to make room for the new.%@NL@%
  19138. %@AB@%         */%@AE@%%@NL@%
  19139.         pqi = pQ->pqiHead->next;%@NL@%
  19140.         SemEnter();%@NL@%
  19141.         pqi->prev->next = pqi->next;%@NL@%
  19142.         pqi->next->prev = pqi->prev;%@NL@%
  19143.         SemLeave();%@NL@%
  19144.     }%@NL@%
  19145. %@NL@%
  19146.     SemEnter();%@NL@%
  19147.     if (pQ->cItems == 0) {%@NL@%
  19148.         pQ->pqiHead = pqi->prev = pqi->next = pqi;%@NL@%
  19149.     } else {%@NL@%
  19150.         pqi->prev = pQ->pqiHead;%@NL@%
  19151.         pqi->next = pQ->pqiHead->next;%@NL@%
  19152.         pQ->pqiHead->next->prev = pqi;%@NL@%
  19153.         pQ->pqiHead->next = pqi;%@NL@%
  19154.         pQ->pqiHead = pqi;%@NL@%
  19155.     }%@NL@%
  19156.     SemLeave();%@NL@%
  19157.     pQ->cItems++;%@NL@%
  19158.     pqi->inst = ++pQ->instLast;%@NL@%
  19159.     return(pqi);%@NL@%
  19160. }%@NL@%
  19161. %@NL@%
  19162. %@NL@%
  19163. %@NL@%
  19164. %@NL@%
  19165. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19166. %@AB@%*%@NL@%
  19167. %@AB@%*  The id given is an external LONG id, not an item instance number.%@NL@%
  19168. %@AB@%*  If id is QID_NEWEST, the head item is deleted.%@NL@%
  19169. %@AB@%*  If id is QID_OLDEST, the tail item is deleted.%@NL@%
  19170. %@AB@%*%@NL@%
  19171. %@AB@%*%@NL@%
  19172. %@AB@%* History:%@NL@%
  19173. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  19174. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19175. void Deleteqi(pQ, id)%@NL@%
  19176. PQST pQ;%@NL@%
  19177. ULONG id;%@NL@%
  19178. {%@NL@%
  19179.     PQUEUEITEM pqi;%@NL@%
  19180. %@NL@%
  19181.     SemEnter();%@NL@%
  19182.     pqi = Findqi(pQ, id);%@NL@%
  19183.     if (pqi == NULL) {%@NL@%
  19184.         SemLeave();%@NL@%
  19185.         return;%@NL@%
  19186.     }%@NL@%
  19187.     pqi->prev->next = pqi->next;%@NL@%
  19188.     pqi->next->prev = pqi->prev;%@NL@%
  19189.     if (pqi == pQ->pqiHead)%@NL@%
  19190.         pQ->pqiHead = pqi->prev;%@NL@%
  19191.     if (!(--pQ->cItems))%@NL@%
  19192.         pQ->pqiHead = NULL;%@NL@%
  19193.     FarFreeMem(pQ->hheap, pqi, pQ->cbItem);%@NL@%
  19194.     SemLeave();%@NL@%
  19195. }%@NL@%
  19196. %@NL@%
  19197. %@NL@%
  19198. %@NL@%
  19199. %@NL@%
  19200. %@NL@%
  19201. %@NL@%
  19202. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19203. %@AB@%*%@NL@%
  19204. %@AB@%*  The id given is an external LONG id, not an item instance number.%@NL@%
  19205. %@AB@%*%@NL@%
  19206. %@AB@%*  if id == QID_NEWEST, returns the head queue data item.%@NL@%
  19207. %@AB@%*  if id == QID_OLDEST, returns the tail queue data item.%@NL@%
  19208. %@AB@%*  if the id is not found or the queue is empty, NULL is returned.%@NL@%
  19209. %@AB@%*  if found, pqi is returned.%@NL@%
  19210. %@AB@%*%@NL@%
  19211. %@AB@%*%@NL@%
  19212. %@AB@%* History:%@NL@%
  19213. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  19214. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19215. PQUEUEITEM Findqi(pQ, id)%@NL@%
  19216. PQST pQ;%@NL@%
  19217. ULONG id;%@NL@%
  19218. {%@NL@%
  19219.     PQUEUEITEM pqi;%@NL@%
  19220. %@NL@%
  19221.     SemCheckIn();%@NL@%
  19222.     if (pQ == NULL || pQ->pqiHead == NULL)%@NL@%
  19223.         return(NULL);%@NL@%
  19224.         %@NL@%
  19225.     if (id == QID_OLDEST) %@NL@%
  19226.         return(pQ->pqiHead->next);%@NL@%
  19227.         %@NL@%
  19228.     if (id == QID_NEWEST) %@NL@%
  19229.         return(pQ->pqiHead);%@NL@%
  19230.         %@NL@%
  19231.     if (id) {%@NL@%
  19232.         pqi = PFROMID(pQ, id);%@NL@%
  19233.         if (pqi->inst == HIUSHORT(id)) {%@NL@%
  19234.             return(pqi);%@NL@%
  19235.         }%@NL@%
  19236.         return(NULL);%@NL@%
  19237.     }%@NL@%
  19238. }%@NL@%
  19239. %@NL@%
  19240. %@NL@%
  19241. %@2@%%@AH@%DMGSTR.C%@AE@%%@EH@%%@NL@%
  19242. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGSTR.C%@AE@%%@NL@%
  19243. %@NL@%
  19244. %@AB@%/****************************** Module Header ******************************\%@NL@%
  19245. %@AB@%* Module Name: DMGSTR.C%@NL@%
  19246. %@AB@%*%@NL@%
  19247. %@AB@%* DDE manager string handling routines%@NL@%
  19248. %@AB@%*%@NL@%
  19249. %@AB@%* Created: 1/31/88 Sanford Staab%@NL@%
  19250. %@AB@%*%@NL@%
  19251. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  19252. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19253. %@AI@%#include %@AE@%"ddemlp.h" %@NL@%
  19254. %@AI@%#include %@AE@%"ctype.h" %@NL@%
  19255. %@NL@%
  19256. %@NL@%
  19257. %@NL@%
  19258. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19259. %@AB@%*%@NL@%
  19260. %@AB@%* returns string length not counting null terminator.%@NL@%
  19261. %@AB@%*%@NL@%
  19262. %@AB@%* History:  1/1/89  created     sanfords%@NL@%
  19263. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19264. int lstrlen(psz)%@NL@%
  19265. PSZ psz;%@NL@%
  19266. {%@NL@%
  19267.     int c = 0;%@NL@%
  19268. %@NL@%
  19269.     while (*psz != 0) {%@NL@%
  19270.         psz++;%@NL@%
  19271.         c++;%@NL@%
  19272.     }%@NL@%
  19273.     return(c);%@NL@%
  19274. }%@NL@%
  19275. %@NL@%
  19276. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  19277. %@AB@%* Concatonates psz1 and psz2 into psz1.%@NL@%
  19278. %@AB@%* returns psz pointing to end of concatonated string.%@NL@%
  19279. %@AB@%* pszLast marks point at which copying must stop.  This makes this operation%@NL@%
  19280. %@AB@%* safe for limited buffer sizes.%@NL@%
  19281. %@AB@%*%@NL@%
  19282. %@AB@%* History:  1/1/89  created sanfords%@NL@%
  19283. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19284. PSZ lstrcat(psz1, psz2, pszLast)%@NL@%
  19285. PSZ psz1, psz2, pszLast;%@NL@%
  19286. {%@NL@%
  19287.     psz1 += lstrlen(psz1);%@NL@%
  19288.     while (*psz2 != '\0' && psz1 < pszLast) {%@NL@%
  19289.         *psz1++ = *psz2++;%@NL@%
  19290.     }%@NL@%
  19291.     *psz1 = '\0';%@NL@%
  19292.     return(psz1);%@NL@%
  19293. }%@NL@%
  19294. %@NL@%
  19295. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19296. %@AB@%* DESCRIPTION: ASCII dependent converter of DDE structure data to a string.%@NL@%
  19297. %@AB@%* returns psz pointing to end of copy.%@NL@%
  19298. %@AB@%* During monitoring we allocate segments as gettable so we can monitor them.%@NL@%
  19299. %@AB@%*%@NL@%
  19300. %@AB@%* History:      Created 1/31/89         sanfords%@NL@%
  19301. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19302. PSZ pddesToPsz(msg, pddes, psz, pszLast)%@NL@%
  19303. USHORT msg;%@NL@%
  19304. PDDESTRUCT pddes;%@NL@%
  19305. PSZ psz;%@NL@%
  19306. PSZ pszLast;%@NL@%
  19307. {%@NL@%
  19308.     USHORT cb;%@NL@%
  19309.     PBYTE pData;%@NL@%
  19310. %@AI@%#define %@AE@%pDdeInit ((PDDEINIT)pddes) %@NL@%
  19311. %@NL@%
  19312.     *psz = '\0';%@NL@%
  19313.     switch (msg) {%@NL@%
  19314.     case WM_DDE_REQUEST:%@NL@%
  19315.     case WM_DDE_ACK:%@NL@%
  19316.     case WM_DDE_DATA:%@NL@%
  19317.     case WM_DDE_ADVISE:%@NL@%
  19318.     case WM_DDE_UNADVISE:%@NL@%
  19319.     case WM_DDE_POKE:%@NL@%
  19320.     case WM_DDE_EXECUTE:%@NL@%
  19321.         psz = lstrcat(psz, "S:", pszLast);%@NL@%
  19322.         psz = Status(pddes->fsStatus, psz, pszLast);%@NL@%
  19323.         psz = lstrcat(psz, " F:", pszLast);%@NL@%
  19324.         psz = Format(pddes->usFormat, psz, pszLast);%@NL@%
  19325.         psz = lstrcat(psz, " I:", pszLast);%@NL@%
  19326.         psz = lstrcat(psz, DDES_PSZITEMNAME(pddes), pszLast);%@NL@%
  19327.         if (pddes->cbData)%@NL@%
  19328.             psz = lstrcat(psz, "\n\r  Data:", pszLast);%@NL@%
  19329.         pData = DDES_PABDATA(pddes);%@NL@%
  19330. %@NL@%
  19331.         for (cb = 0; (ULONG)cb < pddes->cbData && psz < pszLast; cb++, pData++) {%@NL@%
  19332.             %@AB@%/*%@NL@%
  19333. %@AB@%             * new line every 64 chars%@NL@%
  19334. %@AB@%             */%@AE@%%@NL@%
  19335.             if ((cb & 0x3F) == 0) {%@NL@%
  19336.                 *psz = '\0';%@NL@%
  19337.                 psz = lstrcat(psz, "\n\r    ", pszLast);%@NL@%
  19338.             }%@NL@%
  19339.             if (*pData > 0x20)%@NL@%
  19340.                 *psz = *pData;%@NL@%
  19341.             else%@NL@%
  19342.                 *psz = '.';%@NL@%
  19343.                 %@NL@%
  19344.             *psz++ = *psz & 0x7f;%@NL@%
  19345.         }%@NL@%
  19346.         CopyBlock("\n\r", pszLast - 3, 3L);%@NL@%
  19347.         break;%@NL@%
  19348. %@NL@%
  19349.     case WM_DDE_INITIATEACK:%@NL@%
  19350.     case WM_DDE_INITIATE:%@NL@%
  19351.         if (CheckSel(SELECTOROF(pDdeInit))) {%@NL@%
  19352.             psz = lstrcat(psz, "A:", pszLast);%@NL@%
  19353.             psz = lstrcat(psz, pDdeInit->pszAppName, pszLast);%@NL@%
  19354.             psz = lstrcat(psz, " T:", pszLast);%@NL@%
  19355.             psz = lstrcat(psz, pDdeInit->pszTopic, pszLast);%@NL@%
  19356.         }%@NL@%
  19357.         break;%@NL@%
  19358. %@NL@%
  19359.     case WM_DDE_TERMINATE:%@NL@%
  19360.         break;%@NL@%
  19361.     }%@NL@%
  19362.     *psz = '\0';%@NL@%
  19363.     return(psz);%@NL@%
  19364.     %@NL@%
  19365. %@AI@%#undef %@AE@%pDdeInit %@NL@%
  19366. %@NL@%
  19367. }%@NL@%
  19368. %@NL@%
  19369. %@NL@%
  19370. PSZ Status(fs, psz, pszLast)%@NL@%
  19371. USHORT fs;%@NL@%
  19372. PSZ psz;%@NL@%
  19373. PSZ pszLast;%@NL@%
  19374. {%@NL@%
  19375.     if (fs & DDE_FACK) {%@NL@%
  19376.         psz = lstrcat(psz, "ACK ", pszLast);%@NL@%
  19377.     }%@NL@%
  19378.     if (fs & DDE_FBUSY) {%@NL@%
  19379.         psz = lstrcat(psz, "BUSY ", pszLast);%@NL@%
  19380.     }%@NL@%
  19381.     if (fs & DDE_FNODATA) {%@NL@%
  19382.         psz = lstrcat(psz, "NODATA ", pszLast);%@NL@%
  19383.     }%@NL@%
  19384.     if (fs & DDE_FACKREQ) {%@NL@%
  19385.         psz = lstrcat(psz, "ACKREQ ", pszLast);%@NL@%
  19386.     }%@NL@%
  19387.     if (fs & DDE_FRESPONSE) {%@NL@%
  19388.         psz = lstrcat(psz, "RESPONSE ", pszLast);%@NL@%
  19389.     }%@NL@%
  19390.     if (fs & DDE_NOTPROCESSED) {%@NL@%
  19391.         psz = lstrcat(psz, "NOTPROCESSED ", pszLast);%@NL@%
  19392.     }%@NL@%
  19393.     if (fs & DDE_FAPPSTATUS) {%@NL@%
  19394.         psz = lstrcat(psz, "APPSTAT=", pszLast);%@NL@%
  19395.         psz = itoa(fs & DDE_FAPPSTATUS, psz, pszLast);%@NL@%
  19396.         *psz++ = ' ';%@NL@%
  19397.         *psz++ = '\0';%@NL@%
  19398.     }%@NL@%
  19399.     if (fs & DDE_FRESERVED) {%@NL@%
  19400.         psz = lstrcat(psz, "RESERVED=", pszLast);%@NL@%
  19401.         psz = itoa(fs & DDE_FRESERVED, psz, pszLast);%@NL@%
  19402.     }%@NL@%
  19403.     return(psz);%@NL@%
  19404. }%@NL@%
  19405. %@NL@%
  19406. %@NL@%
  19407. PSZ Format(fmt, psz, pszLast)%@NL@%
  19408. USHORT fmt;%@NL@%
  19409. PSZ psz;%@NL@%
  19410. PSZ pszLast;%@NL@%
  19411. {%@NL@%
  19412.     if (fmt > 0xbfff) {%@NL@%
  19413.         *psz++ = '"';%@NL@%
  19414.         psz += WinQueryAtomName(WinQuerySystemAtomTable(), fmt, psz, pszLast - psz);%@NL@%
  19415.         *psz++ = '"';%@NL@%
  19416.         *psz = '\0';%@NL@%
  19417.     } else if (fmt == DDEFMT_TEXT) {%@NL@%
  19418.         psz = lstrcat(psz, "TEXT", pszLast);%@NL@%
  19419.     } else {%@NL@%
  19420.         psz = itoa(fmt, psz, pszLast);%@NL@%
  19421.     }%@NL@%
  19422.     return(psz);%@NL@%
  19423. }%@NL@%
  19424. %@NL@%
  19425. %@NL@%
  19426. %@NL@%
  19427. %@NL@%
  19428. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19429. %@AB@%* DESCRIPTION: puts an apropriate string for a DDE message into psz. pszLast%@NL@%
  19430. %@AB@%* specifies the last spot to copy.  Returns a psz pointing to the end of%@NL@%
  19431. %@AB@%* the copyed data.%@NL@%
  19432. %@AB@%*%@NL@%
  19433. %@AB@%* History:      Created 1/31/89         sanfords%@NL@%
  19434. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19435. PSZ ddeMsgToPsz(msg, psz, pszLast)%@NL@%
  19436. USHORT msg;%@NL@%
  19437. PSZ psz;%@NL@%
  19438. PSZ pszLast;%@NL@%
  19439. {%@NL@%
  19440.     psz = lstrcat(psz, " ", pszLast);%@NL@%
  19441.     if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST) {%@NL@%
  19442.         psz = itoa(msg, psz, pszLast);%@NL@%
  19443.     } else {%@NL@%
  19444.         WinLoadString(DMGHAB, hmodDmg, msg, pszLast - psz + 1, psz);%@NL@%
  19445.         psz += lstrlen(psz);%@NL@%
  19446.     }%@NL@%
  19447.     return(lstrcat(psz, "(", pszLast));%@NL@%
  19448. }%@NL@%
  19449. %@NL@%
  19450. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19451. %@AB@%* DESCRIPTION:%@NL@%
  19452. %@AB@%*   fills psz with a hex string "0xdddd" and returns psz pointing to the 0%@NL@%
  19453. %@AB@%*   terminator at the end.  copying will never go beyond pszLast.%@NL@%
  19454. %@AB@%*%@NL@%
  19455. %@AB@%* History:      Created 1/31/89        sanfords%@NL@%
  19456. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19457. PSZ itoa(us, psz, pszLast)%@NL@%
  19458. USHORT us;%@NL@%
  19459. PSZ psz;%@NL@%
  19460. PSZ pszLast;%@NL@%
  19461. {%@NL@%
  19462.     if (psz > pszLast - 7)%@NL@%
  19463.         return(psz);%@NL@%
  19464.     *psz++ = '0';%@NL@%
  19465.     *psz++ = 'x';%@NL@%
  19466.     return(stoa(psz, us));%@NL@%
  19467. }%@NL@%
  19468. %@NL@%
  19469. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19470. %@AB@%* DESCRIPTION:%@NL@%
  19471. %@AB@%*   fills psz with a hex string "0xdddddddd" and returns psz pointing to the 0%@NL@%
  19472. %@AB@%*   terminator at the end.  copying will never go beyond pszLast.%@NL@%
  19473. %@AB@%*%@NL@%
  19474. %@AB@%* History:      Created 1/31/89        sanfords%@NL@%
  19475. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19476. PSZ ltoa(ul, psz, pszLast)%@NL@%
  19477. ULONG ul;%@NL@%
  19478. PSZ psz;%@NL@%
  19479. PSZ pszLast;%@NL@%
  19480. {%@NL@%
  19481.     if (psz > pszLast - 11)%@NL@%
  19482.         return(psz);%@NL@%
  19483.     *psz++ = '0';%@NL@%
  19484.     *psz++ = 'x';%@NL@%
  19485.     psz = stoa(psz, HIUSHORT(ul));%@NL@%
  19486.     return(stoa(psz, LOUSHORT(ul)));%@NL@%
  19487. }%@NL@%
  19488. %@NL@%
  19489. %@NL@%
  19490. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19491. %@AB@%* DESCRIPTION:%@NL@%
  19492. %@AB@%*   fills psz with a hex string "dddd" and returns psz pointing to the 0%@NL@%
  19493. %@AB@%*   terminator at the end.%@NL@%
  19494. %@AB@%*%@NL@%
  19495. %@AB@%* History:      Created 1/31/89        sanfords%@NL@%
  19496. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19497. PSZ stoa(psz, us)%@NL@%
  19498. PSZ psz;%@NL@%
  19499. USHORT us;%@NL@%
  19500. {%@NL@%
  19501.     static char dtoa[] = "0123456789abcdef";%@NL@%
  19502. %@NL@%
  19503.     *psz++ = dtoa[(us & 0xf000) >> 12];%@NL@%
  19504.     *psz++ = dtoa[(us & 0xf00) >> 8];%@NL@%
  19505.     *psz++ = dtoa[(us & 0xf0) >> 4];%@NL@%
  19506.     *psz++ = dtoa[us & 0xf];%@NL@%
  19507.     *psz = '\0';%@NL@%
  19508.     return(psz);%@NL@%
  19509. }%@NL@%
  19510. %@NL@%
  19511. %@NL@%
  19512. %@AB@%/*%@NL@%
  19513. %@AB@% * Decimal to ascii%@NL@%
  19514. %@AB@% */%@AE@%%@NL@%
  19515. PSZ dtoa(psz, us, fRecurse)%@NL@%
  19516. PSZ psz;%@NL@%
  19517. USHORT us;%@NL@%
  19518. BOOL fRecurse;%@NL@%
  19519. {%@NL@%
  19520.     if (us > 9) {%@NL@%
  19521.         psz = dtoa(psz, us / 10, TRUE);%@NL@%
  19522.         *psz++ = (UCHAR)(us % 10) + '0';%@NL@%
  19523.     } else if (us > 0)%@NL@%
  19524.         *psz++ = (UCHAR)us + '0';%@NL@%
  19525.     else if (!fRecurse)%@NL@%
  19526.         *psz++ = '0';%@NL@%
  19527.     *psz = '\000';%@NL@%
  19528.     return(psz);%@NL@%
  19529. }%@NL@%
  19530.    %@NL@%
  19531. %@NL@%
  19532. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19533. %@AB@%* DESCRIPTION:%@NL@%
  19534. %@AB@%*   fills psz with a hex time stamp and returns psz pointing to the 0%@NL@%
  19535. %@AB@%*   terminator at the end.%@NL@%
  19536. %@AB@%*%@NL@%
  19537. %@AB@%* History:      Created 5/9/89        sanfords%@NL@%
  19538. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19539. PSZ timestamp(psz, pszLast)%@NL@%
  19540. PSZ psz;%@NL@%
  19541. PSZ pszLast;%@NL@%
  19542. {%@NL@%
  19543.     DATETIME dt;%@NL@%
  19544.     static USHORT prevTime = 0;%@NL@%
  19545.     USHORT Time;%@NL@%
  19546. %@NL@%
  19547.     DosGetDateTime(&dt);%@NL@%
  19548.     Time = MAKESHORT(dt.hundredths, dt.seconds);%@NL@%
  19549.     psz = lstrcat(psz, "----------- dTime=", pszLast);%@NL@%
  19550.     psz = itoa(Time - prevTime, psz, pszLast);%@NL@%
  19551.     psz = lstrcat(psz, " ", pszLast);%@NL@%
  19552.     prevTime = Time;%@NL@%
  19553.     return(psz + lstrlen(psz));%@NL@%
  19554. }%@NL@%
  19555. %@NL@%
  19556. %@NL@%
  19557. %@2@%%@AH@%DMGSTRT.ASM%@AE@%%@EH@%%@NL@%
  19558. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGSTRT.ASM%@AE@%%@NL@%
  19559. %@NL@%
  19560. %@AB@%;  DDE manager library initialization routine%@AE@%%@NL@%
  19561. %@NL@%
  19562. .286p%@NL@%
  19563. %@NL@%
  19564. ?WIN=1      %@AB@%; Use Windows prolog/epilog%@AE@%%@NL@%
  19565. ?PLM=1      %@AB@%; Use PLM calling convention%@AE@%%@NL@%
  19566. DOS5=1%@NL@%
  19567. .xlist%@NL@%
  19568. include cmacros.inc%@NL@%
  19569. .list%@NL@%
  19570. %@NL@%
  19571. sBegin  DATA%@NL@%
  19572. %@NL@%
  19573. assumes DS,DATA%@NL@%
  19574. %@NL@%
  19575. externW hmodDmg%@NL@%
  19576. externW usHugeShift%@NL@%
  19577. %@NL@%
  19578. sEnd    DATA%@NL@%
  19579. %@NL@%
  19580. sBegin  CODE%@NL@%
  19581. assumes cs,CODE%@NL@%
  19582. assumes ds,DATA%@NL@%
  19583. %@NL@%
  19584. externNP        SemInit%@NL@%
  19585. %@NL@%
  19586. %@AB@%;%@AE@%%@NL@%
  19587. %@AB@%; Registers set up by DosLoadModule...%@AE@%%@NL@%
  19588. %@AB@%;%@AE@%%@NL@%
  19589. %@AB@%;   SI = heap size%@AE@%%@NL@%
  19590. %@AB@%;   DI = module ID%@AE@%%@NL@%
  19591. %@AB@%;   DS = library's automatic data segment%@AE@%%@NL@%
  19592. %@AB@%;%@AE@%%@NL@%
  19593. cProc   LoadProc,<FAR,PUBLIC>%@NL@%
  19594. cBegin  LoadProc%@NL@%
  19595. %@AB@%;       int     3%@AE@%%@NL@%
  19596.         mov     hmodDmg, di%@NL@%
  19597.         call    SemInit%@NL@%
  19598. cEnd    LoadProc%@NL@%
  19599. %@NL@%
  19600. %@AB@%;%@AE@%%@NL@%
  19601. %@AB@%; FillBlock(PBYTE pDst, USHORT cb, BYTE b)%@AE@%%@NL@%
  19602. %@AB@%;%@AE@%%@NL@%
  19603. cProc        FillBlock,<PUBLIC, NEAR>,<DI, DS>%@NL@%
  19604. ParmD        pDst%@NL@%
  19605. ParmW        cb%@NL@%
  19606. ParmW        b%@NL@%
  19607. cBegin%@NL@%
  19608.         les        di,pDst%@NL@%
  19609.         mov        cx,cb%@NL@%
  19610.         mov        ax,b%@NL@%
  19611.         cld%@NL@%
  19612.         rep        stosb%@NL@%
  19613. cEnd%@NL@%
  19614. %@NL@%
  19615. %@AB@%;%@AE@%%@NL@%
  19616. %@AB@%; CopyBlock(pbSrc, pbDst, cb)%@AE@%%@NL@%
  19617. %@AB@%;%@AE@%%@NL@%
  19618. LabelNP <PUBLIC, CopyBlock>%@NL@%
  19619.         mov     bx,sp%@NL@%
  19620.         push    si%@NL@%
  19621.         push    di%@NL@%
  19622.         mov     dx,ds               %@AB@%; preserve DS%@AE@%%@NL@%
  19623. %@NL@%
  19624.         mov     cx,ss:[bx+2]%@NL@%
  19625.         jcxz    copydone           %@AB@%; all done if crc   == 0%@AE@%%@NL@%
  19626.         les     di,ss:[bx+2+2]%@NL@%
  19627.         lds     si,ss:[bx+2+2+4]%@NL@%
  19628.         cmp     si,di%@NL@%
  19629.         jae     copyok%@NL@%
  19630.         mov     ax,cx%@NL@%
  19631.         dec     ax%@NL@%
  19632.         add     si,ax%@NL@%
  19633.         add     di,ax%@NL@%
  19634.         std%@NL@%
  19635.         rep     movsb%@NL@%
  19636.         cld%@NL@%
  19637.         jmp     short copydone%@NL@%
  19638. copyok:%@NL@%
  19639.         cld%@NL@%
  19640.         rep     movsb%@NL@%
  19641. copydone:%@NL@%
  19642. %@NL@%
  19643.         mov     ds,dx%@NL@%
  19644.         pop     di%@NL@%
  19645.         pop     si%@NL@%
  19646.         ret     10%@NL@%
  19647. %@NL@%
  19648. %@NL@%
  19649. cProc HugeOffset,<NEAR, PUBLIC>%@NL@%
  19650. parmD   pSrc%@NL@%
  19651. parmD   cb%@NL@%
  19652. cBegin%@NL@%
  19653.         mov     dx, SEG_cb%@NL@%
  19654.         mov     ax, OFF_pSrc%@NL@%
  19655.         add     ax, OFF_cb%@NL@%
  19656.         adc     dx, 0%@NL@%
  19657.         mov     cx, usHugeShift%@NL@%
  19658.         shl     dx, cl%@NL@%
  19659.         add     dx, SEG_pSrc%@NL@%
  19660. cEnd%@NL@%
  19661. %@NL@%
  19662. %@NL@%
  19663. LabelFP <PUBLIC, DdeDebugBreak>%@NL@%
  19664.         int     3%@NL@%
  19665.         retf    0%@NL@%
  19666. %@NL@%
  19667. %@AB@%;%@AE@%%@NL@%
  19668. %@AB@%; Returns segment size or 0 on error.%@AE@%%@NL@%
  19669. %@AB@%;%@AE@%%@NL@%
  19670. LabelNP <PUBLIC, CheckSel>%@NL@%
  19671. %@AB@%;    parmW   Selector    ; selector to validate%@AE@%%@NL@%
  19672. cBegin  nogen%@NL@%
  19673.         mov     bx,sp               %@AB@%; BX = selector to validate%@AE@%%@NL@%
  19674.         mov     bx,ss:[bx].2%@NL@%
  19675.         lar     ax,bx               %@AB@%; See if valid selector%@AE@%%@NL@%
  19676.         jnz     invalid_selector%@NL@%
  19677. %@NL@%
  19678.         lsl     ax,bx%@NL@%
  19679.         or      ax,ax               %@AB@%; zero sized?%@AE@%%@NL@%
  19680.         jnz     valid_selector      %@AB@%; nope, ok.%@AE@%%@NL@%
  19681. %@NL@%
  19682. invalid_selector:%@NL@%
  19683.         xor     ax,ax               %@AB@%; Return zero just to be nice%@AE@%%@NL@%
  19684. %@NL@%
  19685. valid_selector:%@NL@%
  19686.         ret     2%@NL@%
  19687. %@NL@%
  19688. cEnd    nogen%@NL@%
  19689. %@NL@%
  19690. sEnd    CODE%@NL@%
  19691. end     LoadProc%@NL@%
  19692. %@NL@%
  19693. %@NL@%
  19694. %@2@%%@AH@%DMGWNDP.C%@AE@%%@EH@%%@NL@%
  19695. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGWNDP.C%@AE@%%@NL@%
  19696. %@NL@%
  19697. %@AB@%/****************************** Module Header ******************************\%@NL@%
  19698. %@AB@%*%@NL@%
  19699. %@AB@%* Module Name: DMGWNDP.C%@NL@%
  19700. %@AB@%*%@NL@%
  19701. %@AB@%* This module contains all the window procs for the DDE manager.%@NL@%
  19702. %@AB@%*%@NL@%
  19703. %@AB@%* Created: 12/23/88 sanfords%@NL@%
  19704. %@AB@%*%@NL@%
  19705. %@AB@%* Copyright (c) 1988, 1989  Microsoft Corporation%@NL@%
  19706. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19707. %@NL@%
  19708. %@AI@%#include %@AE@%"ddemlp.h" %@NL@%
  19709. %@NL@%
  19710. %@NL@%
  19711. ULONG defid = QID_SYNC;%@NL@%
  19712. XFERINFO defXferInfo = {%@NL@%
  19713.         &defid,%@NL@%
  19714.         1L,%@NL@%
  19715.         XTYP_INIT,%@NL@%
  19716.         DDEFMT_TEXT,%@NL@%
  19717.         0L,%@NL@%
  19718.         0L,%@NL@%
  19719.         0L,%@NL@%
  19720.         NULL%@NL@%
  19721. };%@NL@%
  19722. %@NL@%
  19723. void InitAck(HWND hwnd, PCLIENTINFO pci, HWND hwndServer, PDDEINIT pddei);%@NL@%
  19724. MRESULT ClientXferReq(PXFERINFO pXferInfo, PCLIENTINFO pci, HWND hwnd);%@NL@%
  19725. USHORT SendClientReq(PXADATA pXad, HWND hwndServer, HWND hwnd, PAPPINFO pai);%@NL@%
  19726. void DoClientDDEmsg(PCLIENTINFO pci, HWND hwnd, USHORT msg, HWND hwndFrom,%@NL@%
  19727.         PDDESTRUCT pddes);%@NL@%
  19728. BOOL fExpectedMsg(PXADATA pXad, PDDESTRUCT pddes, USHORT msg, PCLIENTINFO pci);%@NL@%
  19729. BOOL AdvanceXaction(HWND hwnd, PCLIENTINFO pci, PXADATA pXad,%@NL@%
  19730.         PDDESTRUCT pddes, USHORT msg, PUSHORT pErr);%@NL@%
  19731. MRESULT ClientXferRespond(PCLIENTINFO pci, PXADATA pXad, PUSHORT pErr);%@NL@%
  19732. void FrameInitConv(HWND hwndClient, PDDEINIT pddei);%@NL@%
  19733. %@NL@%
  19734. %@AB@%/*%@NL@%
  19735. %@AB@% * ----------------CLIENT SECTION------------------%@NL@%
  19736. %@AB@% *%@NL@%
  19737. %@AB@% * Each client conversation has associated with it a window and a queue.%@NL@%
  19738. %@AB@% * A conversation has one synchronous transaction and may have many%@NL@%
  19739. %@AB@% * asynchronous transactions.  A transaction is differientiated by its%@NL@%
  19740. %@AB@% * state and other pertinant data.  A transaction may be synchronous,%@NL@%
  19741. %@AB@% * asynchronous, (initiated by DdeClientXfer()), or it may be external,%@NL@%
  19742. %@AB@% * (initiated by an advise loop.)%@NL@%
  19743. %@AB@% *%@NL@%
  19744. %@AB@% * A transaction is active if it is in the middle of tranfer, otherwise%@NL@%
  19745. %@AB@% * it is shutdown.  A shutdown transaction is either successful or%@NL@%
  19746. %@AB@% * failed.  When an asynchronous transaction shuts down, the client%@NL@%
  19747. %@AB@% * is notified via the callback function. (XTYP_XFERCOMPLETE)%@NL@%
  19748. %@AB@% *%@NL@%
  19749. %@AB@% * The synchronous transaction, when active, is in a timeout loop which%@NL@%
  19750. %@AB@% * can shut-down the transaction at the end of a predefined time period.%@NL@%
  19751. %@AB@% * Shutdown synchronous transactions imediately transfer their information%@NL@%
  19752. %@AB@% * to the client application by returning to DdeClientXfer().%@NL@%
  19753. %@AB@% *%@NL@%
  19754. %@AB@% * asynchronous transactions remain in the client queue until removed%@NL@%
  19755. %@AB@% * by the client application via DdeCheckQueue().  %@NL@%
  19756. %@AB@% *%@NL@%
  19757. %@AB@% * external transactions take place when the client is in an advise%@NL@%
  19758. %@AB@% * data loop.  These transactions pass through the callback function to%@NL@%
  19759. %@AB@% * the client to be accepted.(XTYP_ADVDATA)%@NL@%
  19760. %@AB@% */%@AE@%%@NL@%
  19761. %@NL@%
  19762. %@NL@%
  19763. %@AB@%/***************************** Private Function ****************************\%@NL@%
  19764. %@AB@%* MRESULT EXPENTRY ClientWndProc(hwnd, msg, mp1, mp2);%@NL@%
  19765. %@AB@%*%@NL@%
  19766. %@AB@%*   This window controls a single DDE conversation from the CLIENT side.%@NL@%
  19767. %@AB@%*   If closed, it will automaticly abort any conversationn in progress.%@NL@%
  19768. %@AB@%*   It maintains an internal list of any extra WM_DDEINITIATEACK messages%@NL@%
  19769. %@AB@%*   it receives so that it can be queried later about this information.%@NL@%
  19770. %@AB@%*   Any extra WM_DDEINITIATEACK messages comming in will be immediately%@NL@%
  19771. %@AB@%*   terminated.%@NL@%
  19772. %@AB@%*   It also maintains an internal list of all items which currently are%@NL@%
  19773. %@AB@%*   in active ADVISE loops.%@NL@%
  19774. %@AB@%*%@NL@%
  19775. %@AB@%* History:%@NL@%
  19776. %@AB@%*   Created     12/16/88    Sanfords%@NL@%
  19777. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  19778. MRESULT EXPENTRY ClientWndProc(hwnd, msg, mp1, mp2)%@NL@%
  19779. HWND hwnd;%@NL@%
  19780. USHORT msg;%@NL@%
  19781. MPARAM mp1;%@NL@%
  19782. MPARAM mp2;%@NL@%
  19783. {%@NL@%
  19784.     register PCLIENTINFO pci;%@NL@%
  19785.     PAPPINFO pai;%@NL@%
  19786.     MRESULT mrData;%@NL@%
  19787.     PDDESTRUCT pddes;%@NL@%
  19788. %@NL@%
  19789.     pci = (PCLIENTINFO)WinQueryWindowULong(hwnd, QWL_USER);%@NL@%
  19790. %@NL@%
  19791.     switch (msg) {%@NL@%
  19792.     case WM_CREATE:%@NL@%
  19793.         %@AB@%/*%@NL@%
  19794. %@AB@%         * allocate and initialize the client window info.%@NL@%
  19795. %@AB@%         */%@AE@%%@NL@%
  19796.         pai = GetCurrentAppInfo(FALSE);%@NL@%
  19797.         SemEnter();%@NL@%
  19798.         pci = (PCLIENTINFO)FarAllocMem(pai->hheapApp, sizeof(CLIENTINFO));%@NL@%
  19799.         SemLeave();%@NL@%
  19800.         if (pci == NULL) {%@NL@%
  19801.             pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  19802.             return(1);          %@AB@%/* aboart creation - low memory */%@AE@%%@NL@%
  19803.         }%@NL@%
  19804.         WinSetWindowULong(hwnd, QWL_USER, (ULONG)pci);%@NL@%
  19805.         pci->ci.pai = pai;%@NL@%
  19806.         pci->ci.xad.state = CONVST_NULL;%@NL@%
  19807.         pci->ci.xad.pXferInfo = &defXferInfo;%@NL@%
  19808.         pci->ci.fs = 0;%@NL@%
  19809.         pci->ci.hwndPartner = NULL;%@NL@%
  19810.         pci->ci.hszServerApp = NULL;%@NL@%
  19811.         pci->ci.hszTopic = NULL;%@NL@%
  19812.         pci->pQ = NULL;    %@AB@%/* don't create until we need one */%@AE@%%@NL@%
  19813.         if (!(pci->ci.pAdviseList = CreateLst(pai->hheapApp, sizeof(ADVLI)))) {%@NL@%
  19814.             FarFreeMem(pai->hheapApp, (PBYTE)pci, sizeof(CLIENTINFO));%@NL@%
  19815.             pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  19816.             return(1);          %@AB@%/* aboart creation - low memory */%@AE@%%@NL@%
  19817.         }%@NL@%
  19818.         break;%@NL@%
  19819. %@NL@%
  19820.     case UMCL_INITIATE:%@NL@%
  19821.         if (pci->ci.xad.state == CONVST_NULL) {%@NL@%
  19822.             return(ClientInitiate(hwnd, (PINITINFO)mp1, pci));%@NL@%
  19823.         }%@NL@%
  19824.         break;%@NL@%
  19825. %@NL@%
  19826.     case WM_DDE_INITIATEACK:%@NL@%
  19827.         InitAck(hwnd, pci, mp1, mp2);%@NL@%
  19828.         DosFreeSeg(SELECTOROF(mp2));%@NL@%
  19829.         return(1);%@NL@%
  19830.         break;%@NL@%
  19831. %@NL@%
  19832.     case WM_DESTROY:%@NL@%
  19833.         SemCheckOut();%@NL@%
  19834.         if (pci->ci.fs & ST_CONNECTED) {%@NL@%
  19835.             %@AB@%/*%@NL@%
  19836. %@AB@%             * stop any advises in progress%@NL@%
  19837. %@AB@%             */%@AE@%%@NL@%
  19838.             if (pci->ci.fs & ST_ADVISE) {%@NL@%
  19839.                 pddes = AllocDDESel(0, 0, 0, 0L, NULL);%@NL@%
  19840.                 MyDdePostMsg(pci->ci.hwndPartner, hwnd, WM_DDE_UNADVISE,%@NL@%
  19841.                         (PMYDDES)pddes, pci->ci.pai, MDPM_FREEHDATA);%@NL@%
  19842.             }%@NL@%
  19843.             WinSendMsg(hwnd, UMCL_TERMINATE, 0L, 0L);%@NL@%
  19844.             %@AB@%/*%@NL@%
  19845. %@AB@%             * decrement the use counts on hszs we are done with.%@NL@%
  19846. %@AB@%             */%@AE@%%@NL@%
  19847.             FreeHsz(pci->ci.hszServerApp);%@NL@%
  19848.             FreeHsz(pci->ci.hszTopic);%@NL@%
  19849.         }%@NL@%
  19850.         %@NL@%
  19851.         DestroyLst(pci->ci.pAdviseList);%@NL@%
  19852.         %@NL@%
  19853.         SemEnter();%@NL@%
  19854.         DestroyQ(pci->pQ);%@NL@%
  19855.         FarFreeMem(pci->ci.pai->hheapApp, (PBYTE)pci, sizeof(CLIENTINFO));%@NL@%
  19856.         SemLeave();%@NL@%
  19857.         break;%@NL@%
  19858. %@NL@%
  19859.     case UMCL_TERMINATE:%@NL@%
  19860.         %@AB@%/*%@NL@%
  19861. %@AB@%         * terminates any conversation in progress%@NL@%
  19862. %@AB@%         */%@AE@%%@NL@%
  19863.         if (pci->ci.fs & ST_CONNECTED) {%@NL@%
  19864.             pci->ci.fs = pci->ci.fs & ~ST_CONNECTED;%@NL@%
  19865.             pci->ci.xad.state = CONVST_TERMINATED;%@NL@%
  19866.             if (WinIsWindow(DMGHAB, pci->ci.hwndPartner))%@NL@%
  19867.                 WinDdePostMsg(pci->ci.hwndPartner, hwnd, WM_DDE_TERMINATE, 0L, FALSE);%@NL@%
  19868.         }%@NL@%
  19869.         break;%@NL@%
  19870. %@NL@%
  19871.     case UMCL_XFER:%@NL@%
  19872.         if (!(pci->ci.fs & ST_CONNECTED)) {%@NL@%
  19873.             pci->ci.pai->LastError = DMGERR_NO_CONV_ESTABLISHED;%@NL@%
  19874.             return(0);%@NL@%
  19875.         }%@NL@%
  19876.         return(ClientXferReq((PXFERINFO)mp1, pci, hwnd));%@NL@%
  19877.         break;%@NL@%
  19878. %@NL@%
  19879.     case WM_DDE_DATA:%@NL@%
  19880.     case WM_DDE_ACK:%@NL@%
  19881.         DoClientDDEmsg(pci, hwnd, msg, (HWND)mp1, (PDDESTRUCT)mp2);%@NL@%
  19882.         break;%@NL@%
  19883. %@NL@%
  19884.     case WM_DDE_TERMINATE:%@NL@%
  19885.         SemCheckOut();%@NL@%
  19886.         %@AB@%/*%@NL@%
  19887. %@AB@%         * only respond if this is for us.%@NL@%
  19888. %@AB@%         */%@AE@%%@NL@%
  19889.         if ((HWND)mp1 != pci->ci.hwndPartner) {%@NL@%
  19890.            DosFreeSeg(SELECTOROF(mp2));%@NL@%
  19891.            break;%@NL@%
  19892.         }%@NL@%
  19893.         WinSendMsg(hwnd, UMCL_TERMINATE, 0L, 0L);%@NL@%
  19894.         DosFreeSeg(SELECTOROF(mp2));%@NL@%
  19895.         break;%@NL@%
  19896. %@NL@%
  19897.     case UM_QUERY:%@NL@%
  19898.         %@AB@%/*%@NL@%
  19899. %@AB@%         * LOUSHORT(mp1) = info index.%@NL@%
  19900. %@AB@%         * mp2 = pData.     If pData==0, return data else copy into pData.%@NL@%
  19901. %@AB@%         */%@AE@%%@NL@%
  19902.         switch (LOUSHORT(mp1)) {%@NL@%
  19903.         case Q_STATUS:%@NL@%
  19904.              mrData = (MRESULT)pci->ci.fs;%@NL@%
  19905.              break;%@NL@%
  19906. %@NL@%
  19907.         case Q_CLIENT:%@NL@%
  19908.              mrData = TRUE;%@NL@%
  19909.              break;%@NL@%
  19910. %@NL@%
  19911.         case Q_APPINFO:%@NL@%
  19912.              mrData = pci->ci.pai;%@NL@%
  19913.              break;%@NL@%
  19914. %@NL@%
  19915.         case Q_APPNAME:%@NL@%
  19916.              mrData = *(PHSZ)PTOPPILEITEM(pci->ci.pai->pAppNamePile);%@NL@%
  19917.              break;%@NL@%
  19918.              %@NL@%
  19919.         case Q_ALL:%@NL@%
  19920.              mrData = (MRESULT)(CLIENTINFO FAR *)pci;%@NL@%
  19921.              break;%@NL@%
  19922.         }%@NL@%
  19923.         if (mp2 == 0)%@NL@%
  19924.             return(mrData);%@NL@%
  19925.         else%@NL@%
  19926.             *(MRESULT FAR *)mp2 = mrData;%@NL@%
  19927.         return(1);%@NL@%
  19928.         break;%@NL@%
  19929. %@NL@%
  19930.     default:%@NL@%
  19931.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  19932.         break;%@NL@%
  19933.     }%@NL@%
  19934.     return(0);%@NL@%
  19935. }%@NL@%
  19936. %@NL@%
  19937. %@NL@%
  19938. %@NL@%
  19939. %@AB@%/*%@NL@%
  19940. %@AB@% * Client response to a WM_DDE_INITIATEACK message when expected.%@NL@%
  19941. %@AB@% */%@AE@%%@NL@%
  19942. void InitAck(hwnd, pci, hwndServer, pddei)%@NL@%
  19943. HWND hwnd;%@NL@%
  19944. PCLIENTINFO pci;%@NL@%
  19945. HWND hwndServer;%@NL@%
  19946. PDDEINIT pddei;%@NL@%
  19947. {%@NL@%
  19948.     SemCheckOut();%@NL@%
  19949.     %@NL@%
  19950.     if (pci->ci.fs & ST_CONNECTED) {%@NL@%
  19951.         %@AB@%/*%@NL@%
  19952. %@AB@%         * extra server - spawn another client window.  (we assume we%@NL@%
  19953. %@AB@%         * will only get extras if enumerating.)%@NL@%
  19954. %@AB@%         */%@AE@%%@NL@%
  19955.         AssertF(WinQueryWindow(hwnd, QW_PARENT, FALSE) != pci->ci.pai->hwndDmg,%@NL@%
  19956.             "Improper client spawn")%@NL@%
  19957.         if (hwndServer != pci->ci.hwndPartner) {%@NL@%
  19958.             WinSendMsg(hwndServer, WM_DDE_TERMINATE, hwnd, 0L);%@NL@%
  19959.             GetDDEClientWindow(WinQueryWindow(hwnd, QW_PARENT, FALSE),%@NL@%
  19960.                     hwndServer, hwndServer, pci->ci.hszServerApp,%@NL@%
  19961.                     pci->ci.hszTopic, &pci->ci.cc);%@NL@%
  19962.         }%@NL@%
  19963.         return;%@NL@%
  19964.     }%@NL@%
  19965. %@NL@%
  19966.     if (pci->ci.xad.state != CONVST_INIT1) %@NL@%
  19967.         return;%@NL@%
  19968.         %@NL@%
  19969.     %@AB@%/*%@NL@%
  19970. %@AB@%     * first one back... lock in!%@NL@%
  19971. %@AB@%     */%@AE@%%@NL@%
  19972.     pci->ci.hwndPartner = hwndServer;%@NL@%
  19973.     pci->ci.xad.state = CONVST_CONNECTED;%@NL@%
  19974.     pci->ci.fs |= ST_CONNECTED;%@NL@%
  19975.     if (WinQueryWindowPtr(hwndServer, QWP_PFNWP) == ServerWndProc) %@NL@%
  19976.         pci->ci.fs |= ST_INTRADLL;%@NL@%
  19977.     %@NL@%
  19978.     %@AB@%/*%@NL@%
  19979. %@AB@%     * If the connection was made using a wild app name, we want to%@NL@%
  19980. %@AB@%     * hack in an apropriate name so QueryConvInfo can give the app%@NL@%
  19981. %@AB@%     * something useful to refer to this guy as.%@NL@%
  19982. %@AB@%     *%@NL@%
  19983. %@AB@%     * - the protocol is little help here.%@NL@%
  19984. %@AB@%     */%@AE@%%@NL@%
  19985.     if (pci->ci.hszServerApp == 0) {%@NL@%
  19986.         if (WinQueryWindowPtr(hwndServer, QWP_PFNWP) == ServerWndProc) {%@NL@%
  19987.             %@AB@%/*%@NL@%
  19988. %@AB@%             * one of ours! simple.%@NL@%
  19989. %@AB@%             */%@AE@%%@NL@%
  19990.             pci->ci.hszServerApp = (PAPPINFO)WinSendMsg(pci->ci.hwndPartner,%@NL@%
  19991.                     UM_QUERY, (MPARAM)Q_APPNAME, 0L);%@NL@%
  19992.         } else {%@NL@%
  19993.             %@AB@%/*%@NL@%
  19994. %@AB@%             * Try the psz in pddei.  Maybe the server set it properly%@NL@%
  19995. %@AB@%             * before returning it.%@NL@%
  19996. %@AB@%             */%@AE@%%@NL@%
  19997.             if (!(pci->ci.hszServerApp =%@NL@%
  19998.                     GetHsz(PSZAPP(pddei), pci->ci.cc.idCountry,%@NL@%
  19999.                             pci->ci.cc.usCodepage, TRUE))) {%@NL@%
  20000.                         %@NL@%
  20001.                 PSZ pszT;%@NL@%
  20002.                 USHORT cb;%@NL@%
  20003.                 %@NL@%
  20004.                 %@AB@%/*%@NL@%
  20005. %@AB@%                 * WORST CASE:%@NL@%
  20006. %@AB@%                 * Until a better way is found, we set the hszServerApp to%@NL@%
  20007. %@AB@%                 * the title of the frame window.%@NL@%
  20008. %@AB@%                 */%@AE@%%@NL@%
  20009.                 if (pszT = FarAllocMem(pci->ci.pai->hheapApp,%@NL@%
  20010.                         cb = WinQueryWindowTextLength(pci->ci.hwndFrame) + 1)) {%@NL@%
  20011.                     WinQueryWindowText(pci->ci.hwndFrame, cb, (PSZ)pszT);%@NL@%
  20012.                     pci->ci.hszServerApp = GetHsz(pszT, pci->ci.cc.idCountry,%@NL@%
  20013.                             pci->ci.cc.usCodepage, TRUE);%@NL@%
  20014.                     FarFreeMem(pci->ci.pai->hheapApp, (PBYTE)pszT, cb);%@NL@%
  20015.                 }%@NL@%
  20016.             }%@NL@%
  20017.         }%@NL@%
  20018.     }%@NL@%
  20019.     %@AB@%/*%@NL@%
  20020. %@AB@%     * Now what if the topic was wild?%@NL@%
  20021. %@AB@%     */%@AE@%%@NL@%
  20022.     if (pci->ci.hszTopic == 0) {%@NL@%
  20023.         if (WinQueryWindowPtr(hwndServer, QWP_PFNWP) == ServerWndProc) {%@NL@%
  20024.             %@AB@%/*%@NL@%
  20025. %@AB@%             * one of ours! simple.%@NL@%
  20026. %@AB@%             */%@AE@%%@NL@%
  20027.             pci->ci.hszTopic = (PAPPINFO)WinSendMsg(pci->ci.hwndPartner,%@NL@%
  20028.                     UM_QUERY, (MPARAM)Q_TOPIC, 0L);%@NL@%
  20029.         } else {%@NL@%
  20030.             %@AB@%/*%@NL@%
  20031. %@AB@%             * Try the psz in pddei.  Maybe the server set it properly%@NL@%
  20032. %@AB@%             * before returning it.  If this doesn't work were out of%@NL@%
  20033. %@AB@%             * luck, keep it wild.%@NL@%
  20034. %@AB@%             */%@AE@%%@NL@%
  20035.             pci->ci.hszServerApp = GetHsz(PSZAPP(pddei), pci->ci.cc.idCountry,%@NL@%
  20036.                     pci->ci.cc.usCodepage, TRUE);%@NL@%
  20037.         }                %@NL@%
  20038.     }%@NL@%
  20039. }%@NL@%
  20040. %@NL@%
  20041. %@NL@%
  20042. %@NL@%
  20043. %@AB@%/***************************** Private Function ****************************\%@NL@%
  20044. %@AB@%* Processes a client transfer request issued by one of the ClientXfer%@NL@%
  20045. %@AB@%* functions.  This may be synchronous or asynchronous.%@NL@%
  20046. %@AB@%*%@NL@%
  20047. %@AB@%* History:%@NL@%
  20048. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  20049. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  20050. MRESULT ClientXferReq(pXferInfo, pci, hwnd)%@NL@%
  20051. PXFERINFO pXferInfo;%@NL@%
  20052. PCLIENTINFO pci;%@NL@%
  20053. HWND hwnd;%@NL@%
  20054. {%@NL@%
  20055.     PCQDATA pcqd;%@NL@%
  20056.     MRESULT retVal;%@NL@%
  20057. %@NL@%
  20058.     if (pXferInfo->ulTimeout == TIMEOUT_ASYNC) {%@NL@%
  20059.         %@AB@%/*%@NL@%
  20060. %@AB@%         * add a client queue item to track this transaction and return%@NL@%
  20061. %@AB@%         * the ID.%@NL@%
  20062. %@AB@%         */%@AE@%%@NL@%
  20063.         if (pci->pQ == NULL)%@NL@%
  20064.             pci->pQ = CreateQ(sizeof(CQDATA));%@NL@%
  20065.         if (pci->pQ == NULL) {%@NL@%
  20066.             pci->ci.pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  20067.             return(0);%@NL@%
  20068.         }%@NL@%
  20069.         pcqd = (PCQDATA)Addqi(pci->pQ);%@NL@%
  20070.         if (pcqd == NULL) {%@NL@%
  20071.             pci->ci.pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  20072.             return(0);%@NL@%
  20073.         }%@NL@%
  20074.         CopyBlock((PBYTE)pXferInfo, (PBYTE)&pcqd->XferInfo, sizeof(XFERINFO));%@NL@%
  20075.         pcqd->xad.state = CONVST_CONNECTED;%@NL@%
  20076.         pcqd->xad.pddes = 0;%@NL@%
  20077.         pcqd->xad.LastError = DMGERR_NO_ERROR;%@NL@%
  20078.         pcqd->xad.pXferInfo = &pcqd->XferInfo;%@NL@%
  20079.         %@AB@%/*%@NL@%
  20080. %@AB@%         * Get transaction started - if it fails, quit now.%@NL@%
  20081. %@AB@%         */%@AE@%%@NL@%
  20082.         if ((pcqd->xad.LastError = SendClientReq(&pcqd->xad,%@NL@%
  20083.                 pci->ci.hwndPartner, hwnd, pci->ci.pai)) == DMGERR_SERVER_DIED) {%@NL@%
  20084.             pci->ci.fs = pci->ci.fs & ~ST_CONNECTED;%@NL@%
  20085.             Deleteqi(pci->pQ, MAKEID(pcqd));%@NL@%
  20086.             pci->ci.pai->LastError = DMGERR_SERVER_DIED;%@NL@%
  20087.             return(0);%@NL@%
  20088.         }%@NL@%
  20089.         return((MRESULT)MAKEID(pcqd));%@NL@%
  20090.     }%@NL@%
  20091.     %@NL@%
  20092.     %@AB@%/*%@NL@%
  20093. %@AB@%     * if not quiesent, yet synchronous, tell him were busy.%@NL@%
  20094. %@AB@%     * (this case could happen on a recursive call.)%@NL@%
  20095. %@AB@%     */%@AE@%%@NL@%
  20096.     if (pci->ci.xad.state != CONVST_CONNECTED) {%@NL@%
  20097.         pci->ci.pai->LastError = DMGERR_BUSY;%@NL@%
  20098.         return(0);%@NL@%
  20099.     }%@NL@%
  20100.     %@AB@%/*%@NL@%
  20101. %@AB@%     * Set this so messages comming in during the conversation know whats up%@NL@%
  20102. %@AB@%     */%@AE@%%@NL@%
  20103.     pci->ci.xad.pXferInfo = pXferInfo;%@NL@%
  20104.     %@NL@%
  20105.     if ((pci->ci.pai->LastError = SendClientReq(&pci->ci.xad,%@NL@%
  20106.             pci->ci.hwndPartner, hwnd, pci->ci.pai)) == DMGERR_SERVER_DIED) {%@NL@%
  20107.         pci->ci.fs = pci->ci.fs & ~ST_CONNECTED;%@NL@%
  20108.     }%@NL@%
  20109.     %@NL@%
  20110.     if (pci->ci.pai->LastError != DMGERR_NO_ERROR)%@NL@%
  20111.         return(0);%@NL@%
  20112.     %@AB@%/*%@NL@%
  20113. %@AB@%     *  reset the LastError here so we know if we had problems while%@NL@%
  20114. %@AB@%     *  in the modal loop.%@NL@%
  20115. %@AB@%     */%@AE@%%@NL@%
  20116.     pci->ci.pai->LastError = DMGERR_NO_ERROR;%@NL@%
  20117.     %@AB@%/*%@NL@%
  20118. %@AB@%     * timeout - modal loop.%@NL@%
  20119. %@AB@%     */%@AE@%%@NL@%
  20120.     if (!timeout(pci->ci.pai, pXferInfo->ulTimeout, hwnd)) {%@NL@%
  20121.         %@AB@%/*%@NL@%
  20122. %@AB@%         * reentrency or client has unregistered%@NL@%
  20123. %@AB@%         */%@AE@%%@NL@%
  20124.         return(0);%@NL@%
  20125.     }%@NL@%
  20126.     %@AB@%/*%@NL@%
  20127. %@AB@%     * check results - lasterror already set by timeout().%@NL@%
  20128. %@AB@%     * Synchronous conversation must be reset to quiesent by the time we%@NL@%
  20129. %@AB@%     * give up.%@NL@%
  20130. %@AB@%     */%@AE@%%@NL@%
  20131.     if (pci->ci.xad.state == CONVST_INCOMPLETE) {%@NL@%
  20132.         pci->ci.xad.state = CONVST_CONNECTED;%@NL@%
  20133.         return(0);%@NL@%
  20134.     }%@NL@%
  20135. %@NL@%
  20136.     retVal = ClientXferRespond(pci, &pci->ci.xad, &pci->ci.pai->LastError);%@NL@%
  20137.     if (pci->ci.xad.state == CONVST_INCOMPLETE) %@NL@%
  20138.         pci->ci.xad.state = CONVST_CONNECTED;%@NL@%
  20139.         %@NL@%
  20140.     return(retVal);%@NL@%
  20141. }%@NL@%
  20142. %@NL@%
  20143. %@NL@%
  20144. %@NL@%
  20145.      %@NL@%
  20146. %@AB@%/***************************** Private Function ****************************\%@NL@%
  20147. %@AB@%* This routine sends the apropriate initiation messages for starting a%@NL@%
  20148. %@AB@%* client request according to the transaction data given.%@NL@%
  20149. %@AB@%*%@NL@%
  20150. %@AB@%* History:%@NL@%
  20151. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  20152. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  20153. USHORT SendClientReq(pXad, hwndServer, hwnd, pai)     %@NL@%
  20154. PXADATA pXad;%@NL@%
  20155. HWND hwndServer;%@NL@%
  20156. HWND hwnd;%@NL@%
  20157. PAPPINFO pai;%@NL@%
  20158. {%@NL@%
  20159.     USHORT fsStatus = 0;%@NL@%
  20160.     USHORT msg;%@NL@%
  20161.     BOOL fCopy;%@NL@%
  20162.     PDDESTRUCT pddes;%@NL@%
  20163.     %@NL@%
  20164.     switch (pXad->pXferInfo->usType) {%@NL@%
  20165.     case XTYP_REQUEST:%@NL@%
  20166.         msg = WM_DDE_REQUEST;%@NL@%
  20167.         pXad->state = CONVST_REQSENT;%@NL@%
  20168.         fCopy = FALSE;%@NL@%
  20169.         break;%@NL@%
  20170. %@NL@%
  20171.     case XTYP_POKE:%@NL@%
  20172.         msg = WM_DDE_POKE;%@NL@%
  20173.         pXad->state = CONVST_POKESENT;%@NL@%
  20174.         fCopy = TRUE;%@NL@%
  20175.         break;%@NL@%
  20176. %@NL@%
  20177.     case XTYP_EXEC:%@NL@%
  20178.         msg = WM_DDE_EXECUTE;%@NL@%
  20179.         pXad->state = CONVST_EXECSENT;%@NL@%
  20180.         fCopy = TRUE;%@NL@%
  20181.         break;%@NL@%
  20182. %@NL@%
  20183.     case XTYP_ADVSTART:%@NL@%
  20184.     case XTYP_ADVSTART | XTYPF_NODATA:%@NL@%
  20185.     case XTYP_ADVSTART | XTYPF_ACKREQ:%@NL@%
  20186.     case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:%@NL@%
  20187.         fsStatus = pXad->pXferInfo->usType & (DDE_FACKREQ | DDE_FNODATA);%@NL@%
  20188.         msg = WM_DDE_ADVISE;%@NL@%
  20189.         pXad->state = CONVST_ADVSENT;%@NL@%
  20190.         fCopy = FALSE;%@NL@%
  20191.         break;%@NL@%
  20192. %@NL@%
  20193.     case XTYP_ADVSTOP:%@NL@%
  20194.         msg = WM_DDE_UNADVISE;%@NL@%
  20195.         pXad->state = CONVST_UNADVSENT;%@NL@%
  20196.         fCopy = FALSE;%@NL@%
  20197.         break;%@NL@%
  20198. %@NL@%
  20199.     default:%@NL@%
  20200.         return(DMGERR_INVALIDPARAMETER);%@NL@%
  20201.         break;%@NL@%
  20202.     }%@NL@%
  20203.     %@NL@%
  20204.     %@AB@%/*%@NL@%
  20205. %@AB@%     * Send transfer%@NL@%
  20206. %@AB@%     */%@AE@%%@NL@%
  20207.     if ((pddes = AllocDDESel(fsStatus, pXad->pXferInfo->usFmt,%@NL@%
  20208.             pXad->pXferInfo->hszItem, fCopy ? pXad->pXferInfo->cb : 0, NULL))%@NL@%
  20209.             == 0) {%@NL@%
  20210.         pXad->state = CONVST_CONNECTED;%@NL@%
  20211.         return(DMGERR_MEMORY_ERROR);%@NL@%
  20212.     }%@NL@%
  20213. %@NL@%
  20214.     if (fCopy)%@NL@%
  20215.         CopyHugeBlock((PBYTE)pXad->pXferInfo->pData, DDES_PABDATA(pddes),%@NL@%
  20216.                 pXad->pXferInfo->cb);%@NL@%
  20217. %@NL@%
  20218.     if (WinIsWindow(DMGHAB, hwndServer)) {%@NL@%
  20219.         if (!MyDdePostMsg(hwndServer, hwnd, msg, (PMYDDES)pddes, pai, MDPM_FREEHDATA)) {%@NL@%
  20220.             pXad->state = CONVST_CONNECTED;%@NL@%
  20221.             return(DMGERR_POSTMSG_FAILED);%@NL@%
  20222.         }%@NL@%
  20223.     } else {%@NL@%
  20224.         %@AB@%/*%@NL@%
  20225. %@AB@%         * We lost the server, we are TERMINATED arnold!%@NL@%
  20226. %@AB@%         */%@AE@%%@NL@%
  20227.         pXad->state = CONVST_TERMINATED;%@NL@%
  20228.         FreeData((PMYDDES)pddes, pai);%@NL@%
  20229.         return(DMGERR_SERVER_DIED);%@NL@%
  20230.     }%@NL@%
  20231.     return(DMGERR_NO_ERROR);%@NL@%
  20232. }%@NL@%
  20233. %@NL@%
  20234. %@NL@%
  20235. %@NL@%
  20236. %@NL@%
  20237. %@NL@%
  20238. %@AB@%/***************************** Private Function ****************************\%@NL@%
  20239. %@AB@%* This handles client window processing of WM_DDE_ACK and WM_DDE_DATA msgs.%@NL@%
  20240. %@AB@%* On exit pddes is freed.%@NL@%
  20241. %@AB@%*%@NL@%
  20242. %@AB@%* History:%@NL@%
  20243. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  20244. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  20245. void DoClientDDEmsg(pci, hwnd, msg, hwndFrom, pddes)%@NL@%
  20246. PCLIENTINFO pci;%@NL@%
  20247. HWND hwnd;%@NL@%
  20248. USHORT msg;%@NL@%
  20249. HWND hwndFrom;%@NL@%
  20250. PDDESTRUCT pddes;%@NL@%
  20251. {%@NL@%
  20252.     PCQDATA pqd;%@NL@%
  20253.     int i;%@NL@%
  20254.     HSZ hszItem;%@NL@%
  20255.     PADVLI pAdviseItem;%@NL@%
  20256.     %@NL@%
  20257.     %@AB@%/*%@NL@%
  20258. %@AB@%     * make sure its for us.%@NL@%
  20259. %@AB@%     */%@AE@%%@NL@%
  20260.     if (hwndFrom != pci->ci.hwndPartner || !(pci->ci.fs & ST_CONNECTED)) {%@NL@%
  20261.         FreeData((PMYDDES)pddes, pci->ci.pai);%@NL@%
  20262.         return;%@NL@%
  20263.     }%@NL@%
  20264.     %@AB@%/*%@NL@%
  20265. %@AB@%     * Check if it fits the synchronous transaction data%@NL@%
  20266. %@AB@%     */%@AE@%%@NL@%
  20267.     if (fExpectedMsg(&pci->ci.xad, pddes, msg, pci)) {%@NL@%
  20268.         if (AdvanceXaction(hwnd, pci, &pci->ci.xad, pddes, msg,%@NL@%
  20269.                 &pci->ci.pai->LastError))%@NL@%
  20270.             WinPostMsg(hwnd, WM_TIMER, (MPARAM)TID_TIMEOUT, 0L);%@NL@%
  20271.         return;%@NL@%
  20272.     }%@NL@%
  20273.      %@NL@%
  20274.     %@AB@%/*%@NL@%
  20275. %@AB@%     * See if it fits any asynchronous transaction data - if any exist%@NL@%
  20276. %@AB@%     */%@AE@%%@NL@%
  20277.     if (pci->pQ != NULL && pci->pQ->pqiHead != NULL) {%@NL@%
  20278.         SemEnter();%@NL@%
  20279.         pqd = (PCQDATA)pci->pQ->pqiHead;%@NL@%
  20280.         %@AB@%/*%@NL@%
  20281. %@AB@%         * cycle from oldest to newest.%@NL@%
  20282. %@AB@%         */%@AE@%%@NL@%
  20283.         for (i = pci->pQ->cItems; i; i--) {%@NL@%
  20284.             pqd = (PCQDATA)pqd->next;%@NL@%
  20285.             if (!fExpectedMsg(&pqd->xad, pddes, msg, pci))%@NL@%
  20286.                 continue;%@NL@%
  20287.             if (AdvanceXaction(hwnd, pci, &pqd->xad, pddes, msg,%@NL@%
  20288.                     &pqd->xad.LastError)) {%@NL@%
  20289.                 ClientXferRespond(pci, &pqd->xad, &pqd->xad.LastError);%@NL@%
  20290.                 SemLeave();%@NL@%
  20291.                 MakeCallback(pci->ci.pai, hwnd, (HSZ)0L, (HSZ)0L, 0,%@NL@%
  20292.                         XTYP_XFERCOMPLETE, (HDMGDATA)MAKEID(pqd),%@NL@%
  20293.                         0, 0, hwndFrom);%@NL@%
  20294.                 return;%@NL@%
  20295.             }%@NL@%
  20296.             SemLeave();%@NL@%
  20297.             return;%@NL@%
  20298.         }%@NL@%
  20299.         SemLeave();%@NL@%
  20300.     }%@NL@%
  20301.     %@AB@%/*%@NL@%
  20302. %@AB@%     * It doesn't fit anything, check for an advise data message.%@NL@%
  20303. %@AB@%     */%@AE@%%@NL@%
  20304.     if (msg == WM_DDE_DATA) {%@NL@%
  20305.         hszItem = GetHszItem((PMYDDES)pddes, &pci->ci.cc, TRUE);%@NL@%
  20306.         if (pAdviseItem = (PADVLI)FindAdvList(pci->ci.pAdviseList, hszItem,%@NL@%
  20307.                 pddes->usFormat)) {%@NL@%
  20308.             MakeCallback(pci->ci.pai, (HCONV)hwnd, pci->ci.hszTopic,%@NL@%
  20309.                 hszItem, pddes->usFormat, XTYP_ADVDATA, pddes, msg,%@NL@%
  20310.                 pddes->fsStatus, pci->ci.hwndPartner);%@NL@%
  20311.         } else {%@NL@%
  20312.             FreeHsz(hszItem);%@NL@%
  20313.         }%@NL@%
  20314.         return;%@NL@%
  20315.     }%@NL@%
  20316.     %@AB@%/*%@NL@%
  20317. %@AB@%     * throw it away%@NL@%
  20318. %@AB@%     */%@AE@%%@NL@%
  20319.     FreeData((PMYDDES)pddes, pci->ci.pai);%@NL@%
  20320.     return;%@NL@%
  20321. }%@NL@%
  20322. %@NL@%
  20323. %@NL@%
  20324. %@NL@%
  20325. %@AB@%/***************************** Private Function ****************************\%@NL@%
  20326. %@AB@%* This routine matches a conversation transaction with a DDE message.  If%@NL@%
  20327. %@AB@%* the state, usType, format, itemname dde structure data and the message%@NL@%
  20328. %@AB@%* received all agree, TRUE is returned.%@NL@%
  20329. %@AB@%*%@NL@%
  20330. %@AB@%* History:%@NL@%
  20331. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  20332. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  20333. BOOL fExpectedMsg(pXad, pddes, msg, pci)%@NL@%
  20334. PXADATA pXad;%@NL@%
  20335. PDDESTRUCT pddes;%@NL@%
  20336. USHORT msg;%@NL@%
  20337. PCLIENTINFO pci;%@NL@%
  20338. {%@NL@%
  20339.     HSZ hsz = 0;%@NL@%
  20340.     BOOL fRet = FALSE;%@NL@%
  20341.     %@NL@%
  20342.     if (!(pXad->state > CONVST_INIT1 &&%@NL@%
  20343.             pddes->usFormat == pXad->pXferInfo->usFmt &&%@NL@%
  20344.             (hsz = GetHszItem((PMYDDES)pddes, &pci->ci.cc, TRUE)) ==%@NL@%
  20345.             pXad->pXferInfo->hszItem)) {%@NL@%
  20346.         goto Exit;%@NL@%
  20347.     }%@NL@%
  20348.     switch (pXad->state) {%@NL@%
  20349.     case CONVST_REQSENT:%@NL@%
  20350.         if (msg == WM_DDE_DATA && !(pddes->fsStatus & DDE_FRESPONSE))%@NL@%
  20351.             %@AB@%/*%@NL@%
  20352. %@AB@%             * Not data in response to a request!%@NL@%
  20353. %@AB@%             */%@AE@%%@NL@%
  20354.             break;%@NL@%
  20355.         fRet = (msg == WM_DDE_ACK || msg == WM_DDE_DATA);%@NL@%
  20356.         break;%@NL@%
  20357.         %@NL@%
  20358.     case CONVST_POKESENT:%@NL@%
  20359.     case CONVST_EXECSENT:%@NL@%
  20360.     case CONVST_ADVSENT:%@NL@%
  20361.     case CONVST_UNADVSENT:%@NL@%
  20362.         fRet = (msg == WM_DDE_ACK);%@NL@%
  20363.         break;%@NL@%
  20364.     }%@NL@%
  20365.     %@NL@%
  20366. Exit:    %@NL@%
  20367.     FreeHsz(hsz);%@NL@%
  20368.     return(fRet);%@NL@%
  20369. }%@NL@%
  20370. %@NL@%
  20371. %@NL@%
  20372. %@NL@%
  20373. %@AB@%/***************************** Private Function ****************************\%@NL@%
  20374. %@AB@%* This function assumes that msg is an apropriate message for the transaction%@NL@%
  20375. %@AB@%* referenced by pXad.  It acts on msg as apropriate.  pddes is the DDESTRUCT%@NL@%
  20376. %@AB@%* associated with msg.%@NL@%
  20377. %@AB@%*%@NL@%
  20378. %@AB@%* Returns fSuccess ie: transaction is ready to close up.%@NL@%
  20379. %@AB@%*%@NL@%
  20380. %@AB@%* History:%@NL@%
  20381. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  20382. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  20383. BOOL AdvanceXaction(hwnd, pci, pXad, pddes, msg, pErr)%@NL@%
  20384. HWND hwnd;%@NL@%
  20385. PCLIENTINFO pci;%@NL@%
  20386. PXADATA pXad;%@NL@%
  20387. PDDESTRUCT pddes;%@NL@%
  20388. USHORT msg;%@NL@%
  20389. PUSHORT pErr;%@NL@%
  20390. {%@NL@%
  20391.     switch (msg) {%@NL@%
  20392.     case WM_DDE_ACK:%@NL@%
  20393.         switch (pXad->state) {%@NL@%
  20394.         case CONVST_ADVSENT:%@NL@%
  20395.         case CONVST_EXECSENT:%@NL@%
  20396.         case CONVST_POKESENT:%@NL@%
  20397.         case CONVST_REQSENT:%@NL@%
  20398.         case CONVST_UNADVSENT:%@NL@%
  20399.             if (pddes->fsStatus & DDE_FACK) {%@NL@%
  20400.                 %@AB@%/*%@NL@%
  20401. %@AB@%                 * handle successes%@NL@%
  20402. %@AB@%                 */%@AE@%%@NL@%
  20403.                 switch (pXad->state) {%@NL@%
  20404.                 case CONVST_POKESENT:%@NL@%
  20405.                     pXad->state = CONVST_POKEACKRCVD;%@NL@%
  20406.                     break;%@NL@%
  20407. %@NL@%
  20408.                 case CONVST_EXECSENT:%@NL@%
  20409.                     pXad->state = CONVST_EXECACKRCVD;%@NL@%
  20410.                     break;%@NL@%
  20411. %@NL@%
  20412.                 case CONVST_ADVSENT:%@NL@%
  20413.                     pXad->state = CONVST_ADVACKRCVD;%@NL@%
  20414.                     break;%@NL@%
  20415. %@NL@%
  20416.                 case CONVST_UNADVSENT:%@NL@%
  20417.                     pXad->state = CONVST_UNADVACKRCVD;%@NL@%
  20418.                     break;%@NL@%
  20419. %@NL@%
  20420.                 case CONVST_REQSENT:%@NL@%
  20421.                     %@AB@%/*%@NL@%
  20422. %@AB@%                     * requests are not expected to send a +ACK.  only%@NL@%
  20423. %@AB@%                     * -ACK or data.  We ignore a +ACK to a request.%@NL@%
  20424. %@AB@%                     */%@AE@%%@NL@%
  20425.                     FreeData((PMYDDES)pddes, pci->ci.pai);%@NL@%
  20426.                     return(FALSE);%@NL@%
  20427.                 }%@NL@%
  20428.             } else {%@NL@%
  20429.                 %@AB@%/*%@NL@%
  20430. %@AB@%                 * handle the expected ACK failures.%@NL@%
  20431. %@AB@%                 */%@AE@%%@NL@%
  20432.                 *pErr = DMGERR_NOTPROCESSED;%@NL@%
  20433.                 if (pddes->fsStatus & DDE_FBUSY)%@NL@%
  20434.                     *pErr = DMGERR_BUSY;%@NL@%
  20435.                 pXad->state = CONVST_INCOMPLETE;%@NL@%
  20436.             }%@NL@%
  20437.         }%@NL@%
  20438.         FreeData((PMYDDES)pddes, pci->ci.pai);%@NL@%
  20439.         return(TRUE);%@NL@%
  20440.         break;%@NL@%
  20441. %@NL@%
  20442.     case WM_DDE_DATA:%@NL@%
  20443.         switch (pXad->state) {%@NL@%
  20444.         case CONVST_REQSENT:%@NL@%
  20445.             %@AB@%/*%@NL@%
  20446. %@AB@%             * send an ack if requested - we dare not return the given%@NL@%
  20447. %@AB@%             * pddes because it may be a data item sent to several%@NL@%
  20448. %@AB@%             * clients and we would mess up the fsStatus word for%@NL@%
  20449. %@AB@%             * all processes involved.%@NL@%
  20450. %@AB@%             */%@AE@%%@NL@%
  20451.             if (pddes->fsStatus & DDE_FACKREQ) {%@NL@%
  20452.                 MyDdePostMsg(pci->ci.hwndPartner, hwnd, WM_DDE_ACK,%@NL@%
  20453.                         (PMYDDES)AllocDDESel(DDE_FACK, pddes->usFormat,%@NL@%
  20454.                         pXad->pXferInfo->hszItem, 0L, NULL),%@NL@%
  20455.                         pci->ci.pai, MDPM_FREEHDATA);%@NL@%
  20456.             }%@NL@%
  20457.             pXad->state = CONVST_DATARCVD;%@NL@%
  20458.             %@AB@%/*%@NL@%
  20459. %@AB@%             * We do NOT free the selector here yet because it will be %@NL@%
  20460. %@AB@%             * given to the client via pXad->pddes.%@NL@%
  20461. %@AB@%             */%@AE@%%@NL@%
  20462.             pXad->pddes = pddes;%@NL@%
  20463.             return(TRUE);%@NL@%
  20464.             break;%@NL@%
  20465.         }%@NL@%
  20466.     }%@NL@%
  20467.     return(FALSE);%@NL@%
  20468. }%@NL@%
  20469. %@NL@%
  20470. %@NL@%
  20471.     %@NL@%
  20472. %@AB@%/***************************** Private Function ****************************\%@NL@%
  20473. %@AB@%* This function assumes that a client transfer request has been completed -%@NL@%
  20474. %@AB@%* or should be completed by the time this is called.%@NL@%
  20475. %@AB@%*%@NL@%
  20476. %@AB@%* pci contains general client info%@NL@%
  20477. %@AB@%* pXad contains the transaction info%@NL@%
  20478. %@AB@%* pErr points to where to place the LastError code.%@NL@%
  20479. %@AB@%*%@NL@%
  20480. %@AB@%* Returns 0 on failure%@NL@%
  20481. %@AB@%* Returns TRUE or a Data Selector on success.%@NL@%
  20482. %@AB@%* On failure, the conversation is left in a CONVST_INCOMPLETE state.%@NL@%
  20483. %@AB@%* On success, the conversation is left in a CONVST_CONNECTED state.%@NL@%
  20484. %@AB@%*%@NL@%
  20485. %@AB@%* History:%@NL@%
  20486. %@AB@%*   Created     9/1/89    Sanfords%@NL@%
  20487. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  20488. MRESULT ClientXferRespond(pci, pXad, pErr)%@NL@%
  20489. PCLIENTINFO pci;%@NL@%
  20490. PXADATA pXad;%@NL@%
  20491. PUSHORT pErr;%@NL@%
  20492. {%@NL@%
  20493.     if (pXad->state == CONVST_INCOMPLETE) %@NL@%
  20494.         return(0);%@NL@%
  20495.         %@NL@%
  20496.     switch (pXad->pXferInfo->usType) {%@NL@%
  20497.     case XTYP_REQUEST:%@NL@%
  20498.         if (pXad->state != CONVST_DATARCVD) {%@NL@%
  20499.             if (*pErr == DMGERR_NO_ERROR)%@NL@%
  20500.                 *pErr = DMGERR_DATAACKTIMEOUT;%@NL@%
  20501.             goto failexit;%@NL@%
  20502.         }%@NL@%
  20503.         pXad->state = CONVST_CONNECTED;%@NL@%
  20504.         return(pXad->pddes);%@NL@%
  20505.         break;%@NL@%
  20506. %@NL@%
  20507.     case XTYP_POKE:%@NL@%
  20508.         if (pXad->state != CONVST_POKEACKRCVD) {%@NL@%
  20509.             if (*pErr == DMGERR_NO_ERROR)%@NL@%
  20510.                 *pErr = DMGERR_POKEACKTIMEOUT;%@NL@%
  20511.             goto failexit;%@NL@%
  20512.         }%@NL@%
  20513.         pXad->state = CONVST_CONNECTED;%@NL@%
  20514.         return(TRUE);%@NL@%
  20515.         break;%@NL@%
  20516. %@NL@%
  20517.     case XTYP_EXEC:%@NL@%
  20518.         if (pXad->state != CONVST_EXECACKRCVD) {%@NL@%
  20519.             if (*pErr == DMGERR_NO_ERROR)%@NL@%
  20520.                 *pErr = DMGERR_EXECACKTIMEOUT;%@NL@%
  20521.             goto failexit;%@NL@%
  20522.         }%@NL@%
  20523.         pXad->state = CONVST_CONNECTED;%@NL@%
  20524.         return(TRUE);%@NL@%
  20525.         break;%@NL@%
  20526. %@NL@%
  20527.     case XTYP_ADVSTART:%@NL@%
  20528.     case XTYP_ADVSTART | XTYPF_NODATA:%@NL@%
  20529.     case XTYP_ADVSTART | XTYPF_ACKREQ:%@NL@%
  20530.     case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:%@NL@%
  20531.         if (pXad->state != CONVST_ADVACKRCVD) {%@NL@%
  20532.             if (*pErr == DMGERR_NO_ERROR)%@NL@%
  20533.                 *pErr = DMGERR_ADVACKTIMEOUT;%@NL@%
  20534.             goto failexit;%@NL@%
  20535.         }%@NL@%
  20536.         if (!AddAdvList(pci->ci.pAdviseList, pXad->pXferInfo->hszItem,%@NL@%
  20537.                 pXad->pXferInfo->usType & (DDE_FACKREQ | DDE_FNODATA),%@NL@%
  20538.                 pXad->pXferInfo->usFmt)) {%@NL@%
  20539.             pXad->state = CONVST_INCOMPLETE;%@NL@%
  20540.             pci->ci.pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  20541.             return(FALSE);%@NL@%
  20542.         } else {%@NL@%
  20543.             pXad->state = CONVST_CONNECTED;%@NL@%
  20544.             pci->ci.fs |= ST_ADVISE;%@NL@%
  20545.             return(TRUE);%@NL@%
  20546.         }%@NL@%
  20547.         break;%@NL@%
  20548. %@NL@%
  20549.     case XTYP_ADVSTOP:%@NL@%
  20550.         if (pXad->state != CONVST_UNADVACKRCVD) {%@NL@%
  20551.             if (*pErr == DMGERR_NO_ERROR)%@NL@%
  20552.                 *pErr = DMGERR_UNADVACKTIMEOUT;%@NL@%
  20553.             goto failexit;%@NL@%
  20554.         }%@NL@%
  20555.         if (!DeleteAdvList(pci->ci.pAdviseList, pXad->pXferInfo->hszItem,%@NL@%
  20556.                 pXad->pXferInfo->usFmt))%@NL@%
  20557.             pci->ci.fs &= ~ST_ADVISE;%@NL@%
  20558.         pXad->state = CONVST_CONNECTED;%@NL@%
  20559.         return(TRUE);%@NL@%
  20560.         break;%@NL@%
  20561. %@NL@%
  20562.     }%@NL@%
  20563.     %@NL@%
  20564. failexit:%@NL@%
  20565.     pXad->state = CONVST_INCOMPLETE;%@NL@%
  20566.     return(0);%@NL@%
  20567. }%@NL@%
  20568. %@NL@%
  20569. %@NL@%
  20570. %@NL@%
  20571. %@NL@%
  20572. %@NL@%
  20573. %@NL@%
  20574. %@AB@%/*%@NL@%
  20575. %@AB@% * ----------------------------SERVER SECTION--------------------------------%@NL@%
  20576. %@AB@% */%@AE@%%@NL@%
  20577. %@NL@%
  20578. %@NL@%
  20579. %@NL@%
  20580. %@AB@%/***************************** Public  Function ****************************\%@NL@%
  20581. %@AB@%* MRESULT EXPENTRY ServerWndProc(hwnd, msg, mp1, mp2)%@NL@%
  20582. %@AB@%* HWND hwnd;%@NL@%
  20583. %@AB@%* USHORT msg;%@NL@%
  20584. %@AB@%* MPARAM mp1;%@NL@%
  20585. %@AB@%* MPARAM mp2;%@NL@%
  20586. %@AB@%*%@NL@%
  20587. %@AB@%* DESCRIPTION:%@NL@%
  20588. %@AB@%*   This processes DDE conversations from the server end.%@NL@%
  20589. %@AB@%*   It stores internal information and acts much like a state machine.%@NL@%
  20590. %@AB@%*   If closed, it will automaticly abort any conversation in progress.%@NL@%
  20591. %@AB@%*   It also maintains an internal list of all items which currently are%@NL@%
  20592. %@AB@%*   in active ADVISE loops.%@NL@%
  20593. %@AB@%* PUBDOC START%@NL@%
  20594. %@AB@%*   These server windows have the feature that a conversation can be%@NL@%
  20595. %@AB@%*   re-initiated with them by a client.  The Client merely terminates%@NL@%
  20596. %@AB@%*   the conversation and then re-initiates by using a SendMsg to this%@NL@%
  20597. %@AB@%*   window.  This allows a client to change the topic of the conversation%@NL@%
  20598. %@AB@%*   or to pass the conversation on to another client window without%@NL@%
  20599. %@AB@%*   loosing the server it initiated with.   This is quite useful for%@NL@%
  20600. %@AB@%*   wild initiates.%@NL@%
  20601. %@AB@%* PUBDOC END%@NL@%
  20602. %@AB@%*%@NL@%
  20603. %@AB@%* History:%@NL@%
  20604. %@AB@%* 10/18/89 sanfords Added hack to make hszItem==0L when offszItem==offabData.%@NL@%
  20605. %@AB@%* 1/4/89   sanfords created %@NL@%
  20606. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  20607. MRESULT EXPENTRY ServerWndProc(hwnd, msg, mp1, mp2)%@NL@%
  20608. HWND hwnd;%@NL@%
  20609. USHORT msg;%@NL@%
  20610. MPARAM mp1;%@NL@%
  20611. MPARAM mp2;%@NL@%
  20612. {%@NL@%
  20613. %@AI@%#define %@AE@%PDDES ((PDDESTRUCT)mp2)     %@NL@%
  20614.     register PSERVERINFO psi;%@NL@%
  20615.     MPARAM mrData;%@NL@%
  20616.     PADVLI pAdviseItem;%@NL@%
  20617.     PSZ pszApp, pszTopic;%@NL@%
  20618.     HSZ hsz;%@NL@%
  20619.     USHORT cchApp, cchTopic;%@NL@%
  20620.     USHORT usType;%@NL@%
  20621.     HDMGDATA hDmgData = 0L;%@NL@%
  20622.     BOOL fResult;%@NL@%
  20623.     %@NL@%
  20624. %@NL@%
  20625.     psi = (PSERVERINFO)WinQueryWindowULong(hwnd, QWL_USER);%@NL@%
  20626. %@NL@%
  20627.     switch (msg) {%@NL@%
  20628.     case WM_DDE_REQUEST:%@NL@%
  20629.     case WM_DDE_ACK:%@NL@%
  20630.     case WM_DDE_ADVISE:%@NL@%
  20631.     case WM_DDE_UNADVISE:%@NL@%
  20632.     case WM_DDE_POKE:%@NL@%
  20633.     case WM_DDE_EXECUTE:%@NL@%
  20634.         %@AB@%/*%@NL@%
  20635. %@AB@%         * only respond if this is for us.%@NL@%
  20636. %@AB@%         */%@AE@%%@NL@%
  20637.         if ((HWND)mp1 != psi->ci.hwndPartner || !(psi->ci.fs & ST_CONNECTED)) {%@NL@%
  20638.             FreeData((PMYDDES)mp2, psi->ci.pai);%@NL@%
  20639.             return(0);%@NL@%
  20640.         }%@NL@%
  20641.     }%@NL@%
  20642. %@NL@%
  20643.     switch (msg) {%@NL@%
  20644.     case WM_CREATE: {%@NL@%
  20645.             PAPPINFO pai;%@NL@%
  20646.             %@NL@%
  20647.             %@AB@%/*%@NL@%
  20648. %@AB@%             * allocate and initialize the server window info.%@NL@%
  20649. %@AB@%             */%@AE@%%@NL@%
  20650.             pai = GetCurrentAppInfo(FALSE);%@NL@%
  20651.             SemEnter();%@NL@%
  20652. %@NL@%
  20653.             if (!(psi = (PSERVERINFO)FarAllocMem(pai->hheapApp, sizeof(SERVERINFO))))%@NL@%
  20654.                 goto LowMem;%@NL@%
  20655.             FillBlock((PBYTE)&psi->ci, sizeof(COMMONINFO), 0);%@NL@%
  20656.             if (!(psi->ci.pAdviseList = CreateLst(pai->hheapApp, sizeof(ADVLI)))) {%@NL@%
  20657.                 FarFreeMem(pai->hheapApp, (PBYTE)psi, sizeof(SERVERINFO));%@NL@%
  20658. LowMem:                        %@NL@%
  20659.                 pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  20660.                 SemLeave();%@NL@%
  20661.                 return(1);          %@AB@%/* abort creation - low memory */%@AE@%%@NL@%
  20662.             }%@NL@%
  20663.             SemLeave();%@NL@%
  20664.             psi->ci.pai = pai;%@NL@%
  20665.             psi->ci.xad.state = CONVST_NULL;%@NL@%
  20666.             WinSetWindowULong(hwnd, QWL_USER, (ULONG)psi);%@NL@%
  20667.         }%@NL@%
  20668.         break;%@NL@%
  20669. %@NL@%
  20670.     case UMSR_INITIATE:%@NL@%
  20671.         %@AB@%/*%@NL@%
  20672. %@AB@%         * This was sent by the subclassed frame of the server app.%@NL@%
  20673. %@AB@%         * The frame has already queried the server for permission%@NL@%
  20674. %@AB@%         * to create this window.%@NL@%
  20675. %@AB@%         *%@NL@%
  20676. %@AB@%         * If mp2 is NULL, this is a hot server window waiting for%@NL@%
  20677. %@AB@%         * a WM_DDE_INITIATE.%@NL@%
  20678. %@AB@%         */%@AE@%%@NL@%
  20679. %@AI@%#define %@AE@%pii ((PINITINFO)mp1)          %@NL@%
  20680.         IncHszCount(psi->ci.hszServerApp = pii->hszAppName);%@NL@%
  20681.         IncHszCount(psi->ci.hszTopic = pii->hszTopic);%@NL@%
  20682.         psi->ci.hwndPartner = (HWND)mp2;%@NL@%
  20683.         psi->ci.hwndFrame = FindFrame(psi->ci.hwndPartner);%@NL@%
  20684.         psi->ci.cc.fsContext = pii->pCC->fsContext;%@NL@%
  20685.         psi->ci.cc.idCountry = pii->pCC->idCountry;%@NL@%
  20686.         psi->ci.cc.usCodepage = pii->pCC->usCodepage;%@NL@%
  20687.         psi->ci.fs |= ST_CONNECTED;%@NL@%
  20688.         psi->ci.xad.state = CONVST_CONNECTED;%@NL@%
  20689.         %@NL@%
  20690.         SemEnter();%@NL@%
  20691.         pszApp = pszFromHsz(psi->ci.hszServerApp, &cchApp);%@NL@%
  20692.         pszTopic = pszFromHsz(psi->ci.hszTopic, &cchTopic);%@NL@%
  20693.         SemLeave();%@NL@%
  20694. %@NL@%
  20695.         if (mp2)%@NL@%
  20696.             WinDdeRespond((HWND)mp2, hwnd, pszApp, pszTopic);%@NL@%
  20697.         %@NL@%
  20698.         SemEnter();%@NL@%
  20699.         FarFreeMem(hheapDmg, (PBYTE)pszApp, cchApp);%@NL@%
  20700.         FarFreeMem(hheapDmg, (PBYTE)pszTopic, cchTopic);%@NL@%
  20701.         SemLeave();%@NL@%
  20702.         %@NL@%
  20703.         return(1);%@NL@%
  20704. %@AI@%#undef %@AE@%pii         %@NL@%
  20705.         break;%@NL@%
  20706. %@NL@%
  20707.     case WM_DDE_INITIATE:%@NL@%
  20708.         %@AB@%/*%@NL@%
  20709. %@AB@%         * This will happen when a client tries to re-initiate a conversation%@NL@%
  20710. %@AB@%         * with this server.  We allow about 10 seconds after termination%@NL@%
  20711. %@AB@%         * for another client to connect specifically with this window.%@NL@%
  20712. %@AB@%         * This allows a client to swap windows on its end of the conversation.%@NL@%
  20713. %@AB@%         */%@AE@%%@NL@%
  20714. %@NL@%
  20715.         if (psi->ci.xad.state == CONVST_TERMINATED &&%@NL@%
  20716.                 (psi->ci.hszServerApp == GetHsz(PSZAPP(mp2), psi->ci.cc.idCountry,%@NL@%
  20717.                         psi->ci.cc.usCodepage, FALSE))) {%@NL@%
  20718.                     %@NL@%
  20719.             WinStopTimer(DMGHAB, hwnd, TID_SELFDESTRUCT);%@NL@%
  20720.             hsz = psi->ci.hszTopic;%@NL@%
  20721.             psi->ci.hszTopic = GetHsz(PSZTOPIC(mp2), psi->ci.cc.idCountry,%@NL@%
  20722.                     psi->ci.cc.usCodepage, TRUE);%@NL@%
  20723.             FreeHsz(hsz);%@NL@%
  20724.             psi->ci.hwndPartner = (HWND)mp1;%@NL@%
  20725.             psi->ci.hwndFrame = FindFrame(psi->ci.hwndPartner);%@NL@%
  20726.             psi->ci.fs |= ST_CONNECTED;%@NL@%
  20727.             psi->ci.xad.state = CONVST_CONNECTED;%@NL@%
  20728.             if (WinQueryWindowPtr(psi->ci.hwndPartner, QWP_PFNWP) == ClientWndProc) %@NL@%
  20729.                 psi->ci.fs |= ST_INTRADLL;%@NL@%
  20730.             WinDdeRespond((HWND)mp1, hwnd, PSZAPP(mp2), PSZTOPIC(mp2));%@NL@%
  20731.             fResult = TRUE;%@NL@%
  20732.         } else%@NL@%
  20733.             fResult = FALSE;%@NL@%
  20734.             %@NL@%
  20735.         FreeData((PMYDDES)mp2, psi->ci.pai);%@NL@%
  20736.         return(fResult);%@NL@%
  20737.         break;%@NL@%
  20738. %@NL@%
  20739.     case WM_DDE_TERMINATE:%@NL@%
  20740.         %@AB@%/*%@NL@%
  20741. %@AB@%         * only respond if this is for us.%@NL@%
  20742. %@AB@%         */%@AE@%%@NL@%
  20743.         if ((HWND)mp1 != psi->ci.hwndPartner) %@NL@%
  20744.             break;%@NL@%
  20745.         %@AB@%/* fall through */%@AE@%%@NL@%
  20746. %@NL@%
  20747.     case UMSR_TERMINATE:%@NL@%
  20748.         %@AB@%/*%@NL@%
  20749. %@AB@%         * terminates any conversation in progress%@NL@%
  20750. %@AB@%         * Note that we keep around all the other conversation data so%@NL@%
  20751. %@AB@%         * a later re-connection is possible.%@NL@%
  20752. %@AB@%         */%@AE@%%@NL@%
  20753.         if (psi->ci.fs & ST_CONNECTED) {%@NL@%
  20754.             psi->ci.fs &= ~ST_CONNECTED;%@NL@%
  20755.             psi->ci.xad.state = CONVST_TERMINATED;%@NL@%
  20756.             if (WinIsWindow(DMGHAB, psi->ci.hwndPartner))%@NL@%
  20757.                 WinDdePostMsg(psi->ci.hwndPartner, hwnd, WM_DDE_TERMINATE, 0L, FALSE);%@NL@%
  20758.         }%@NL@%
  20759.         if (psi->ci.fs & ST_ADVISE) {%@NL@%
  20760.             FlushLst(psi->ci.pAdviseList);%@NL@%
  20761.             psi->ci.fs &= ~ST_ADVISE;%@NL@%
  20762.         }%@NL@%
  20763.         %@AB@%/*%@NL@%
  20764. %@AB@%         * Mr. Phelps, if this window isn't reconnected within 10 odd%@NL@%
  20765. %@AB@%         * seconds, it will self-destruct.  This gives the client time%@NL@%
  20766. %@AB@%         * to reconnect with another client window.  This often happens%@NL@%
  20767. %@AB@%         * with wild initiates.%@NL@%
  20768. %@AB@%         */%@AE@%%@NL@%
  20769.         WinStartTimer(DMGHAB, hwnd, TID_SELFDESTRUCT, 0xa000);%@NL@%
  20770.         break;%@NL@%
  20771. %@NL@%
  20772.     case WM_TIMER:%@NL@%
  20773.         if (LOUSHORT(mp1) == TID_SELFDESTRUCT && !(psi->ci.fs & ST_CONNECTED))%@NL@%
  20774.             DestroyWindow(hwnd);%@NL@%
  20775.         break;%@NL@%
  20776. %@NL@%
  20777.     case WM_DESTROY:%@NL@%
  20778.         SemCheckOut();%@NL@%
  20779.         %@AB@%/*%@NL@%
  20780. %@AB@%         * Send ourselves a terminate and free local data.%@NL@%
  20781. %@AB@%         */%@AE@%%@NL@%
  20782.         WinSendMsg(hwnd, UMSR_TERMINATE, 0L, 0L);%@NL@%
  20783.         MakeCallback(psi->ci.pai, hwnd, psi->ci.hszTopic, (HSZ)NULL, 0, XTYP_TERM,%@NL@%
  20784.                 0L, 0, 0, psi->ci.hwndPartner);%@NL@%
  20785.         SemEnter();%@NL@%
  20786.         DestroyLst(psi->ci.pAdviseList);%@NL@%
  20787.         FreeHsz(psi->ci.hszServerApp);%@NL@%
  20788.         FreeHsz(psi->ci.hszTopic);%@NL@%
  20789.         FarFreeMem(psi->ci.pai->hheapApp, (PBYTE)psi, sizeof(SERVERINFO));%@NL@%
  20790.         SemLeave();%@NL@%
  20791.         break;%@NL@%
  20792. %@NL@%
  20793.     case WM_DDE_REQUEST:%@NL@%
  20794.         usType = XTYP_REQUEST;%@NL@%
  20795.         goto Callback;%@NL@%
  20796.         %@NL@%
  20797.     case WM_DDE_EXECUTE:%@NL@%
  20798.         usType = XTYP_EXEC;%@NL@%
  20799.         hDmgData = mp2;%@NL@%
  20800.         goto Callback;%@NL@%
  20801.         %@NL@%
  20802.     case WM_DDE_POKE:%@NL@%
  20803.         usType = XTYP_POKE;%@NL@%
  20804.         hDmgData = mp2;%@NL@%
  20805.         goto Callback;%@NL@%
  20806.         %@NL@%
  20807.     case WM_DDE_ADVISE:%@NL@%
  20808.         usType = XTYP_ADVSTART; %@AB@%/* set ST_ADVISE AFTER app oks advise loop */%@AE@%%@NL@%
  20809.         goto Callback;%@NL@%
  20810.         %@NL@%
  20811.     case WM_DDE_UNADVISE:%@NL@%
  20812.         %@AB@%/*%@NL@%
  20813. %@AB@%         * Terminate the advise now, but notify the server in callback so%@NL@%
  20814. %@AB@%         * messages don't get out of order.%@NL@%
  20815. %@AB@%         */%@AE@%%@NL@%
  20816.         if (!DeleteAdvList(psi->ci.pAdviseList,%@NL@%
  20817.                 GetHszItem(mp2, &psi->ci.cc, FALSE),%@NL@%
  20818.                 PDDES->usFormat))%@NL@%
  20819.             psi->ci.fs &= ~ST_ADVISE;%@NL@%
  20820.         usType = XTYP_ADVSTOP;%@NL@%
  20821.         goto Callback;%@NL@%
  20822.         %@NL@%
  20823.     case WM_DDE_ACK:%@NL@%
  20824.         %@AB@%/*%@NL@%
  20825. %@AB@%         * This is an ack in response to the FACKREQ bit being set.%@NL@%
  20826. %@AB@%         * See if this refers to one of the advise loops.%@NL@%
  20827. %@AB@%         */%@AE@%%@NL@%
  20828.         if ((pAdviseItem = FindAdvList(psi->ci.pAdviseList,%@NL@%
  20829.                 GetHszItem(mp2, &psi->ci.cc, FALSE),%@NL@%
  20830.                 PDDES->usFormat)) &&%@NL@%
  20831.                 (pAdviseItem->fsStatus & DDE_FACKREQ)) {%@NL@%
  20832.             %@AB@%/*%@NL@%
  20833. %@AB@%             * Update advise loop status - no longer waiting for an ack.%@NL@%
  20834. %@AB@%             */%@AE@%%@NL@%
  20835.             pAdviseItem->fsStatus &= ~ADVST_WAITING;%@NL@%
  20836.             if (pAdviseItem->fsStatus & ADVST_CHANGED) {%@NL@%
  20837.                 pAdviseItem->fsStatus |= ADVST_POSTED; %@NL@%
  20838.                 %@AB@%/*%@NL@%
  20839. %@AB@%                 * The client is out of date.  Send the data%@NL@%
  20840. %@AB@%                 * again (simulate a post advise call).%@NL@%
  20841. %@AB@%                 * Don't bother the server with ACK info.%@NL@%
  20842. %@AB@%                 */%@AE@%%@NL@%
  20843.                 MakeCallback(psi->ci.pai, (HCONV)hwnd, psi->ci.hszTopic,%@NL@%
  20844.                         pAdviseItem->hszItem, %@NL@%
  20845.                         pAdviseItem->usFmt, XTYP_ADVREQ, %@NL@%
  20846.                         0L, UMSR_POSTADVISE,%@NL@%
  20847.                         pAdviseItem->fsStatus & ~DDE_FRESERVED,%@NL@%
  20848.                         psi->ci.hwndPartner);%@NL@%
  20849.                 FreeData((PMYDDES)mp2, psi->ci.pai);%@NL@%
  20850.                 return(0);%@NL@%
  20851.             }%@NL@%
  20852.         }%@NL@%
  20853.         usType = XTYP_ACK;%@NL@%
  20854.         hDmgData = PDDES->fsStatus;%@NL@%
  20855.         %@NL@%
  20856. Callback:        %@NL@%
  20857.         MakeCallback(psi->ci.pai, (HCONV)hwnd, psi->ci.hszTopic,%@NL@%
  20858. %@AI@%#if %@AE@%0 %@NL@%
  20859.                 %@AB@%/*%@NL@%
  20860. %@AB@%                 * hack for EXCEL which makes its items and data equal for%@NL@%
  20861. %@AB@%                 * execute acks which SHOULD use NULL as the item name.%@NL@%
  20862. %@AB@%                 */%@AE@%%@NL@%
  20863.                 (PDDES->offszItemName == PDDES->offabData) ?%@NL@%
  20864.                     0L :%@NL@%
  20865. %@AI@%#endif %@AE@%%@NL@%
  20866.                 GetHszItem((PMYDDES)mp2, &psi->ci.cc, TRUE),%@NL@%
  20867.                 PDDES->usFormat, usType,%@NL@%
  20868.                 hDmgData, msg, PDDES->fsStatus,%@NL@%
  20869.                 psi->ci.hwndPartner);%@NL@%
  20870.         %@AB@%/*%@NL@%
  20871. %@AB@%         * now free the incomming selector IF it wasn't passed on to%@NL@%
  20872. %@AB@%         * MakeCallback as hDmgData.%@NL@%
  20873. %@AB@%         */%@AE@%%@NL@%
  20874.         if (hDmgData != mp2)%@NL@%
  20875.             FreeData((PMYDDES)mp2, psi->ci.pai);%@NL@%
  20876.         break;%@NL@%
  20877.         %@NL@%
  20878.     case UMSR_POSTADVISE:%@NL@%
  20879.         %@AB@%/*%@NL@%
  20880. %@AB@%         * This message came from DdePostAdvise()%@NL@%
  20881. %@AB@%         *%@NL@%
  20882. %@AB@%         * Advise loops are tricky because of the desireable FACKREQ feature%@NL@%
  20883. %@AB@%         * of DDE.  The advise loop list holds information in its fsStatus%@NL@%
  20884. %@AB@%         * field to maintain the state of the advise loop.%@NL@%
  20885. %@AB@%         *%@NL@%
  20886. %@AB@%         * if the ADVST_POSTED bit is set, it means that the server already%@NL@%
  20887. %@AB@%         * has an ADVREQ message in its callback queue.  This prevents%@NL@%
  20888. %@AB@%         * unnecessary ADVREQ messages from getting thrown into the callback%@NL@%
  20889. %@AB@%         * queue.%@NL@%
  20890. %@AB@%         *%@NL@%
  20891. %@AB@%         * if the ADVST_WAITING bit is set, the server is still waiting for%@NL@%
  20892. %@AB@%         * the client to give it the go-ahead for more data with an%@NL@%
  20893. %@AB@%         * ACK message on this item. (FACKREQ is set)  Without a go-ahead,%@NL@%
  20894. %@AB@%         * the server will not send any more advise data to the client but%@NL@%
  20895. %@AB@%         * will instead set the ADVST_CHANGED bit which will cause another%@NL@%
  20896. %@AB@%         * WM_DDE_DATA message to be sent to the client as soon as the%@NL@%
  20897. %@AB@%         * go-ahead ACK is received.  This keeps the client up to date%@NL@%
  20898. %@AB@%         * but never overloads it.%@NL@%
  20899. %@AB@%         */%@AE@%%@NL@%
  20900. %@NL@%
  20901.         if (!(psi->ci.fs & ST_ADVISE) ||%@NL@%
  20902.                 !(pAdviseItem = FindAdvList(psi->ci.pAdviseList, (HSZ)mp1, 0)))%@NL@%
  20903.             break;%@NL@%
  20904. %@NL@%
  20905.         do {%@NL@%
  20906.             %@AB@%/*%@NL@%
  20907. %@AB@%             * for each format for this item that has an advise loop:%@NL@%
  20908. %@AB@%             */%@AE@%%@NL@%
  20909.             if (pAdviseItem->fsStatus & ADVST_POSTED)%@NL@%
  20910.                 continue;%@NL@%
  20911.                 %@NL@%
  20912.             if ((pAdviseItem->fsStatus & DDE_FACKREQ) &&%@NL@%
  20913.                     (pAdviseItem->fsStatus & ADVST_WAITING)) {%@NL@%
  20914.                 %@AB@%/*%@NL@%
  20915. %@AB@%                 * if the client has not yet finished with the last data%@NL@%
  20916. %@AB@%                 * we gave him, just update the advise loop status%@NL@%
  20917. %@AB@%                 * instead of sending data now.%@NL@%
  20918. %@AB@%                 */%@AE@%%@NL@%
  20919.                 pAdviseItem->fsStatus |= ADVST_CHANGED;%@NL@%
  20920.                 continue;%@NL@%
  20921.             }%@NL@%
  20922.             if (pAdviseItem->fsStatus & DDE_FNODATA) {%@NL@%
  20923.                 %@AB@%/*%@NL@%
  20924. %@AB@%                 * In the nodata case, we don't bother the server.  Just%@NL@%
  20925. %@AB@%                 * pass the client an apropriate DATA message.%@NL@%
  20926. %@AB@%                 */%@AE@%%@NL@%
  20927.                 MyDdePostMsg(psi->ci.hwndPartner, hwnd, WM_DDE_DATA,%@NL@%
  20928.                         (PMYDDES)AllocDDESel(pAdviseItem->fsStatus & ~(DDE_FNODATA | DDE_FACKREQ),%@NL@%
  20929.                         pAdviseItem->usFmt, (HSZ)mp1, 0L, 0),%@NL@%
  20930.                         psi->ci.pai, MDPM_FREEHDATA);%@NL@%
  20931.                 continue;%@NL@%
  20932.             }%@NL@%
  20933.             %@AB@%/*%@NL@%
  20934. %@AB@%             * Otherwise, lets get the data from the server.%@NL@%
  20935. %@AB@%             */%@AE@%%@NL@%
  20936.             pAdviseItem->fsStatus |= ADVST_POSTED;%@NL@%
  20937.             MakeCallback(psi->ci.pai, (HCONV)hwnd, psi->ci.hszTopic,%@NL@%
  20938.                     (HSZ)mp1, pAdviseItem->usFmt, XTYP_ADVREQ,%@NL@%
  20939.                     0, UMSR_POSTADVISE,%@NL@%
  20940.                     pAdviseItem->fsStatus & (DDE_FACKREQ | DDE_FNODATA),%@NL@%
  20941.                     psi->ci.hwndPartner);%@NL@%
  20942.         } while (pAdviseItem = FindNextAdv(pAdviseItem, (HSZ)mp1));%@NL@%
  20943.         break;%@NL@%
  20944. %@NL@%
  20945.     case UM_QUERY:%@NL@%
  20946.         %@AB@%/*%@NL@%
  20947. %@AB@%         * LOUSHORT(mp1) = info index.%@NL@%
  20948. %@AB@%         * mp2 = pData.     If pData==0, return data else copy into pData.%@NL@%
  20949. %@AB@%         */%@AE@%%@NL@%
  20950.         switch (LOUSHORT(mp1)) {%@NL@%
  20951.         case Q_STATUS:%@NL@%
  20952.              mrData = (MRESULT)psi->ci.fs;%@NL@%
  20953.              break;%@NL@%
  20954. %@NL@%
  20955.         case Q_CLIENT:%@NL@%
  20956.              mrData = FALSE;%@NL@%
  20957.              break;%@NL@%
  20958. %@NL@%
  20959.         case Q_APPINFO:%@NL@%
  20960.              mrData = psi->ci.pai;%@NL@%
  20961.              break;%@NL@%
  20962.               %@NL@%
  20963.         case Q_APPNAME:%@NL@%
  20964.              mrData = psi->ci.hszServerApp;%@NL@%
  20965.              break;%@NL@%
  20966. %@NL@%
  20967.         case Q_TOPIC:%@NL@%
  20968.              mrData = psi->ci.hszTopic;%@NL@%
  20969.              break;%@NL@%
  20970.              %@NL@%
  20971.         case Q_ALL:%@NL@%
  20972.              mrData = (MRESULT)(SERVERINFO FAR *)psi;%@NL@%
  20973.              break;%@NL@%
  20974.         }%@NL@%
  20975.         if (mp2 == 0)%@NL@%
  20976.             return(mrData);%@NL@%
  20977.         else%@NL@%
  20978.             *(MRESULT FAR *)mp2 = mrData;%@NL@%
  20979.         return(1);%@NL@%
  20980.         break;%@NL@%
  20981. %@NL@%
  20982.     default:%@NL@%
  20983.         return(WinDefWindowProc(hwnd, msg, mp1, mp2));%@NL@%
  20984.         break;%@NL@%
  20985.     }%@NL@%
  20986.     return(0);%@NL@%
  20987. %@AI@%#undef %@AE@%PDDES     %@NL@%
  20988. }%@NL@%
  20989. %@NL@%
  20990. %@NL@%
  20991. %@NL@%
  20992. %@NL@%
  20993. %@AB@%/*%@NL@%
  20994. %@AB@% * This assumes hwnd is a DDE window.  It tries to locate the proper%@NL@%
  20995. %@AB@% * top-level frame window that this window is associated with useing%@NL@%
  20996. %@AB@% * process and thread IDs.%@NL@%
  20997. %@AB@% */%@AE@%%@NL@%
  20998. HWND FindFrame(%@NL@%
  20999. HWND hwnd)%@NL@%
  21000. {%@NL@%
  21001.     PID pid, pidFrame;%@NL@%
  21002.     TID tid, tidFrame;%@NL@%
  21003.     HWND hwndMaybe = NULL;%@NL@%
  21004.     HWND hwndBetter = NULL;%@NL@%
  21005.     HWND hwndFrame;%@NL@%
  21006.     HENUM hEnum;%@NL@%
  21007.     ULONG ul;%@NL@%
  21008.     %@NL@%
  21009.     WinQueryWindowProcess(hwnd, &pid, &tid);%@NL@%
  21010.     hEnum = WinBeginEnumWindows(HWND_DESKTOP);%@NL@%
  21011.     while (hwndFrame = WinGetNextWindow(hEnum)) {%@NL@%
  21012.         %@AB@%/*%@NL@%
  21013. %@AB@%         * for all top level windows ...%@NL@%
  21014. %@AB@%         */%@AE@%%@NL@%
  21015.         ul = (ULONG)WinSendMsg(hwndFrame, WM_QUERYFRAMEINFO, 0L, 0L);%@NL@%
  21016.         if (FI_FRAME & ul) {%@NL@%
  21017.             %@AB@%/*%@NL@%
  21018. %@AB@%             * that are frames ...%@NL@%
  21019. %@AB@%             */%@AE@%%@NL@%
  21020.             WinQueryWindowProcess(hwndFrame, &pidFrame, &tidFrame);%@NL@%
  21021.             if (pidFrame == pid) {%@NL@%
  21022.                 %@AB@%/*%@NL@%
  21023. %@AB@%                 * in this process - maybe - ...%@NL@%
  21024. %@AB@%                 */%@AE@%%@NL@%
  21025.                 hwndMaybe = hwndFrame;%@NL@%
  21026.                 if (tidFrame == tid) {%@NL@%
  21027.                     %@AB@%/*%@NL@%
  21028. %@AB@%                     * in this thread - better - ...%@NL@%
  21029. %@AB@%                     */%@AE@%%@NL@%
  21030.                     hwndBetter = hwndFrame;%@NL@%
  21031.                     if (WinQueryWindowPtr(hwndFrame, QWP_PFNWP) ==%@NL@%
  21032.                             subframeWndProc) {%@NL@%
  21033.                         %@AB@%/*%@NL@%
  21034. %@AB@%                         * that are subclassed by us - certainly!%@NL@%
  21035. %@AB@%                         */%@AE@%%@NL@%
  21036.                         hwndBetter = hwndFrame;%@NL@%
  21037.                         break;%@NL@%
  21038.                     }%@NL@%
  21039.                 }%@NL@%
  21040.             }%@NL@%
  21041.         }%@NL@%
  21042.     }%@NL@%
  21043.     WinEndEnumWindows(hEnum);%@NL@%
  21044.     return(hwndBetter ? hwndBetter : hwndMaybe);%@NL@%
  21045. }%@NL@%
  21046. %@NL@%
  21047. %@NL@%
  21048. %@NL@%
  21049. %@NL@%
  21050. %@AB@%/***************************** Private Function ****************************\%@NL@%
  21051. %@AB@%* This routine handles server message replys.  This may have been called%@NL@%
  21052. %@AB@%* immediately in the case of enabled callbacks, or may have been called%@NL@%
  21053. %@AB@%* via DdeEnableCallback in which case the server action has been%@NL@%
  21054. %@AB@%* delayed.  QReply is responsible for freeing the pddes given as well as%@NL@%
  21055. %@AB@%* the pcbi->hDmgData and pcbi->hszItem.%@NL@%
  21056. %@AB@%*%@NL@%
  21057. %@AB@%* History:%@NL@%
  21058. %@AB@%*   Created     9/12/89    Sanfords%@NL@%
  21059. %@AB@%*   6/12/90 sanfords    Added checks for HDATA ownership.%@NL@%
  21060. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  21061. void QReply(pcbi, pddes)%@NL@%
  21062. PCBLI pcbi;%@NL@%
  21063. PDDESTRUCT pddes;   %@AB@%/* hDataRet */%@AE@%%@NL@%
  21064. {%@NL@%
  21065.     PSERVERINFO psi;%@NL@%
  21066.     PADVLI pAdviseItem;%@NL@%
  21067.     USHORT fsStatus, msg;%@NL@%
  21068. %@NL@%
  21069.     if ((pcbi->usType & XCLASS_MASK) == XCLASS_NOTIFICATION)%@NL@%
  21070.         return;%@NL@%
  21071. %@NL@%
  21072.     SemCheckOut();%@NL@%
  21073.     psi = WinSendMsg(pcbi->hConv, UM_QUERY, (MPARAM)Q_ALL, 0L);%@NL@%
  21074.     %@NL@%
  21075.     switch (pcbi->msg) {%@NL@%
  21076.     case UMSR_POSTADVISE:%@NL@%
  21077.         %@AB@%/*%@NL@%
  21078. %@AB@%         * The NODATA case never gets here.%@NL@%
  21079. %@AB@%         */%@AE@%%@NL@%
  21080.         if ((psi) &&%@NL@%
  21081.                 (pAdviseItem = FindAdvList(psi->ci.pAdviseList, pcbi->hszItem,%@NL@%
  21082.                 pcbi->usFmt))) {%@NL@%
  21083.             pAdviseItem->fsStatus &= ~ADVST_POSTED;%@NL@%
  21084.             if (pddes) {%@NL@%
  21085.                 pAdviseItem->fsStatus &= ~ADVST_CHANGED;%@NL@%
  21086.                 MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, WM_DDE_DATA,%@NL@%
  21087.                         (PMYDDES)pddes, psi->ci.pai, MDPM_FREEHDATA);%@NL@%
  21088.                 if (pAdviseItem->fsStatus & DDE_FACKREQ) %@NL@%
  21089.                     pAdviseItem->fsStatus |= ADVST_WAITING;%@NL@%
  21090.             }%@NL@%
  21091.         }%@NL@%
  21092.         break;%@NL@%
  21093.             %@NL@%
  21094.     case WM_DDE_REQUEST:%@NL@%
  21095.         if (pddes) {%@NL@%
  21096.             pddes->fsStatus = (pcbi->fsStatus & DDE_FACKREQ) | DDE_FRESPONSE;%@NL@%
  21097.             msg = WM_DDE_DATA;%@NL@%
  21098.         } else {%@NL@%
  21099.             %@AB@%/*%@NL@%
  21100. %@AB@%             * send a -ACK%@NL@%
  21101. %@AB@%             */%@AE@%%@NL@%
  21102.             pddes = AllocDDESel(((USHORT)pddes & DDE_FAPPSTATUS) |%@NL@%
  21103.                     ((USHORT)pddes & DDE_FBUSY ? DDE_FBUSY : DDE_NOTPROCESSED),%@NL@%
  21104.                     pcbi->usFmt, pcbi->hszItem, 0L, NULL);%@NL@%
  21105.             msg = WM_DDE_ACK;%@NL@%
  21106.         }%@NL@%
  21107.         MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, msg, (PMYDDES)pddes,%@NL@%
  21108.                 psi->ci.pai, MDPM_FREEHDATA);%@NL@%
  21109.         break;%@NL@%
  21110.         %@NL@%
  21111.     case WM_DDE_POKE:%@NL@%
  21112.     case WM_DDE_EXECUTE:%@NL@%
  21113.         %@AB@%/*%@NL@%
  21114. %@AB@%         * pddes is supposed to be the proper DDE_ constants to return.%@NL@%
  21115. %@AB@%         * we just stick them in the given pddes (hDmgData) and return%@NL@%
  21116. %@AB@%         * it as an ACK.  This frees pcbi->hDmgData in the process.%@NL@%
  21117. %@AB@%         */%@AE@%%@NL@%
  21118.         ((PDDESTRUCT)pcbi->hDmgData)->fsStatus = %@NL@%
  21119.                 (USHORT)pddes & ~DDE_FRESERVED;%@NL@%
  21120.         MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, WM_DDE_ACK,%@NL@%
  21121.                 (PMYDDES)pcbi->hDmgData, psi->ci.pai, MDPM_FREEHDATA);%@NL@%
  21122.         break;%@NL@%
  21123.         %@NL@%
  21124.     case WM_DDE_ADVISE:%@NL@%
  21125.         %@AB@%/*%@NL@%
  21126. %@AB@%         * pddes is fStartAdvise%@NL@%
  21127. %@AB@%         * If DDE_FACK, we add the item to the advise loop%@NL@%
  21128. %@AB@%         * list and +ACK else we -ACK.%@NL@%
  21129. %@AB@%         */%@AE@%%@NL@%
  21130.         if ((BOOL)pddes) {%@NL@%
  21131.             psi = (PSERVERINFO)WinQueryWindowULong(pcbi->hConv, QWL_USER);%@NL@%
  21132.             if (AddAdvList(psi->ci.pAdviseList, pcbi->hszItem,%@NL@%
  21133.                     pcbi->fsStatus & (DDE_FNODATA | DDE_FACKREQ),%@NL@%
  21134.                     pcbi->usFmt) == NULL) {%@NL@%
  21135.                 psi->ci.pai->LastError = DMGERR_MEMORY_ERROR;%@NL@%
  21136.                 fsStatus = DDE_NOTPROCESSED;%@NL@%
  21137.             } else {%@NL@%
  21138.                 psi->ci.fs |= ST_ADVISE;%@NL@%
  21139.                 fsStatus = DDE_FACK;%@NL@%
  21140.             }%@NL@%
  21141.         } else {%@NL@%
  21142.             fsStatus = DDE_NOTPROCESSED;%@NL@%
  21143.         }%@NL@%
  21144.         goto AckBack;%@NL@%
  21145.         break;%@NL@%
  21146. %@NL@%
  21147.     case WM_DDE_UNADVISE:%@NL@%
  21148.         fsStatus = DDE_FACK;%@NL@%
  21149.         goto AckBack;%@NL@%
  21150.         break;%@NL@%
  21151.     %@NL@%
  21152.     case WM_DDE_DATA:%@NL@%
  21153.         %@AB@%/*%@NL@%
  21154. %@AB@%         * must be an advise data item for the CLIENT or maybe some requested%@NL@%
  21155. %@AB@%         * data mistakenly sent here due to the client queue being flushed.%@NL@%
  21156. %@AB@%         * pddes is fsStatus.%@NL@%
  21157. %@AB@%         *%@NL@%
  21158. %@AB@%         * send an ack back if requested.%@NL@%
  21159. %@AB@%         */%@AE@%%@NL@%
  21160.         if (pcbi->fsStatus & DDE_FACKREQ) {%@NL@%
  21161.             %@AB@%/*%@NL@%
  21162. %@AB@%             * Clean up the status incase the app is messed up.%@NL@%
  21163. %@AB@%             */%@AE@%%@NL@%
  21164.             fsStatus = (USHORT)pddes & ~DDE_FRESERVED;%@NL@%
  21165.             if (fsStatus & (DDE_NOTPROCESSED | DDE_FBUSY))%@NL@%
  21166.                 fsStatus &= ~DDE_FACK;%@NL@%
  21167. AckBack:%@NL@%
  21168.             MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, WM_DDE_ACK,%@NL@%
  21169.                 (PMYDDES)AllocDDESel(fsStatus, pcbi->usFmt, pcbi->hszItem, 0L, 0),%@NL@%
  21170.                 psi->ci.pai, MDPM_FREEHDATA);%@NL@%
  21171.         }%@NL@%
  21172.         break;%@NL@%
  21173.     }%@NL@%
  21174. }%@NL@%
  21175. %@NL@%
  21176. %@NL@%
  21177. %@NL@%
  21178. %@AB@%/*%@NL@%
  21179. %@AB@% * ----------------FRAME SECTION------------------%@NL@%
  21180. %@AB@% *%@NL@%
  21181. %@AB@% * A frame window exists on behalf of every registered thread.  It%@NL@%
  21182. %@AB@% * handles conversation initiation and therefore issues callbacks%@NL@%
  21183. %@AB@% * to the server app as needed to notify or query the server app.%@NL@%
  21184. %@AB@% * The callback queue is always bypassed for these synchronous%@NL@%
  21185. %@AB@% * events.%@NL@%
  21186. %@AB@% */%@AE@%%@NL@%
  21187. %@NL@%
  21188. %@AB@%/***************************** Private Function ****************************\%@NL@%
  21189. %@AB@%* MRESULT EXPENTRY subframeWndProc(hwnd, msg, mp1, mp2)%@NL@%
  21190. %@AB@%* HWND hwnd;%@NL@%
  21191. %@AB@%* USHORT msg;%@NL@%
  21192. %@AB@%* MPARAM mp1;%@NL@%
  21193. %@AB@%* MPARAM mp2;%@NL@%
  21194. %@AB@%*%@NL@%
  21195. %@AB@%* This routine takes care of setting up server windows as needed to respond%@NL@%
  21196. %@AB@%* to incomming WM_DDE_INTIIATE messages.  It is subclassed from the top%@NL@%
  21197. %@AB@%* level frame of the server application.%@NL@%
  21198. %@AB@%*%@NL@%
  21199. %@AB@%* History:  created 12/20/88    sanfords%@NL@%
  21200. %@AB@%\***************************************************************************/%@AE@%%@NL@%
  21201. MRESULT EXPENTRY subframeWndProc(hwnd, msg, mp1, mp2)%@NL@%
  21202. HWND hwnd;%@NL@%
  21203. USHORT msg;%@NL@%
  21204. MPARAM mp1;%@NL@%
  21205. MPARAM mp2;%@NL@%
  21206. {%@NL@%
  21207.     PAPPINFO pai;%@NL@%
  21208. %@NL@%
  21209.     pai = GetCurrentAppInfo(FALSE);%@NL@%
  21210.     %@NL@%
  21211.     switch (msg) {%@NL@%
  21212.     case UM_REGISTER:%@NL@%
  21213.     case UM_UNREGISTER:%@NL@%
  21214.         %@AB@%/*%@NL@%
  21215. %@AB@%         * we pass notification messages through this proc so we can make the%@NL@%
  21216. %@AB@%         * xfer call within the correct thread's context.%@NL@%
  21217. %@AB@%         */%@AE@%%@NL@%
  21218.         MakeCallback(pai, (HCONV)0, (HSZ)0, (HSZ)mp1, 0,%@NL@%
  21219.                 msg == UM_REGISTER ? XTYP_REGISTER : XTYP_UNREGISTER,%@NL@%
  21220.                 (HDMGDATA)mp2, msg, 0, 0L);%@NL@%
  21221.         return(0);%@NL@%
  21222.         break;%@NL@%
  21223. %@NL@%
  21224.     case WM_DDE_INITIATE:%@NL@%
  21225.         FrameInitConv((HWND)mp1, (PDDEINIT)mp2);%@NL@%
  21226.         FreeData((PMYDDES)mp2, pai);%@NL@%
  21227.         break;%@NL@%
  21228. %@NL@%
  21229.     default:%@NL@%
  21230.         return((*lpfnFrameWndProc)(hwnd, msg, mp1, mp2));%@NL@%
  21231.         break;%@NL@%
  21232.     }%@NL@%
  21233. }%@NL@%
  21234. %@NL@%
  21235. %@NL@%
  21236. %@NL@%
  21237. void FrameInitConv(hwndClient, pddei)%@NL@%
  21238. HWND hwndClient;%@NL@%
  21239. PDDEINIT pddei;%@NL@%
  21240. {%@NL@%
  21241.     PAPPINFO pai, paiClient;%@NL@%
  21242.     INITINFO ii;%@NL@%
  21243.     HSZPAIR hp[2];%@NL@%
  21244.     PHSZPAIR php;%@NL@%
  21245.     HSZ hsz = 0;%@NL@%
  21246.     HDMGDATA hDataCC;%@NL@%
  21247.     PDDESTRUCT pddes;%@NL@%
  21248.     HWND hwndServer;%@NL@%
  21249.     CONVCONTEXT cc;%@NL@%
  21250.     BOOL fWild;%@NL@%
  21251. %@NL@%
  21252.     if (!CheckSel(SELECTOROF(pddei))) {%@NL@%
  21253.         AssertF(FALSE, "Invalid DDEINIT selector");%@NL@%
  21254.         return;%@NL@%
  21255.     }%@NL@%
  21256.     %@NL@%
  21257.     SemCheckOut();%@NL@%
  21258.     %@NL@%
  21259.     pai = GetCurrentAppInfo(FALSE);%@NL@%
  21260.     %@AB@%/*%@NL@%
  21261. %@AB@%     * If we are filtering and no app names are registered, quit.%@NL@%
  21262. %@AB@%     */%@AE@%%@NL@%
  21263.     if ((pai->afCmd & DMGCMD_FILTERINITS) &&%@NL@%
  21264.             QPileItemCount(pai->pAppNamePile) == 0) %@NL@%
  21265.         return;%@NL@%
  21266.         %@NL@%
  21267.     %@AB@%/*%@NL@%
  21268. %@AB@%     * filter out inits from ourselves and other agents (if we are an agent)%@NL@%
  21269. %@AB@%     */%@AE@%%@NL@%
  21270.     if (WinQueryWindowPtr(hwndClient, QWP_PFNWP) == ClientWndProc) {%@NL@%
  21271.         paiClient = WinSendMsg(hwndClient, UM_QUERY, (MPARAM)Q_APPINFO, 0L);%@NL@%
  21272.         if (paiClient == pai)%@NL@%
  21273.             return;%@NL@%
  21274.             %@NL@%
  21275.         if ((pai->afCmd & DMGCMD_AGENT) && (paiClient->afCmd & DMGCMD_AGENT)) %@NL@%
  21276.             return;%@NL@%
  21277.     }%@NL@%
  21278. %@NL@%
  21279.     %@AB@%/*%@NL@%
  21280. %@AB@%     * make sure ii.pCC is set up right.%@NL@%
  21281. %@AB@%     */%@AE@%%@NL@%
  21282.     if (pddei->cb >= sizeof(DDEINIT) && pddei->offConvContext) {%@NL@%
  21283.         %@AB@%/*%@NL@%
  21284. %@AB@%         * new dde init structure!%@NL@%
  21285. %@AB@%         */%@AE@%%@NL@%
  21286.         ii.pCC = DDEI_PCONVCONTEXT(pddei);%@NL@%
  21287.     } else {%@NL@%
  21288.         ii.pCC = &cc;%@NL@%
  21289.         cc.cb = sizeof(CONVCONTEXT);%@NL@%
  21290.         cc.idCountry = syscc.country;%@NL@%
  21291.         cc.usCodepage = syscc.codepage;%@NL@%
  21292.         cc.fsContext = 0;%@NL@%
  21293.     }%@NL@%
  21294. %@NL@%
  21295. %@NL@%
  21296.     hp[0].hszApp = GetHsz(PSZAPP(pddei), ii.pCC->idCountry,%@NL@%
  21297.             ii.pCC->usCodepage, TRUE);%@NL@%
  21298.             %@NL@%
  21299.     %@AB@%/*%@NL@%
  21300. %@AB@%     * filter out unwanted app names.%@NL@%
  21301. %@AB@%     */%@AE@%%@NL@%
  21302.     if (hp[0].hszApp && (pai->afCmd & DMGCMD_FILTERINITS) &&%@NL@%
  21303.             !FindPileItem(pai->pAppNamePile, CmppHsz, (PBYTE)&hp[0].hszApp, 0)) {%@NL@%
  21304.         FreeHsz(hp[0].hszApp);%@NL@%
  21305.         return;    %@NL@%
  21306.     }%@NL@%
  21307. %@NL@%
  21308.     hp[0].hszTopic = GetHsz(PSZTOPIC(pddei), ii.pCC->idCountry,%@NL@%
  21309.             ii.pCC->usCodepage, TRUE);%@NL@%
  21310.             %@NL@%
  21311.     hp[1].hszApp = hp[1].hszTopic = 0L;%@NL@%
  21312. %@NL@%
  21313.     fWild = (hp[0].hszApp == 0L || hp[0].hszTopic == 0);%@NL@%
  21314. %@NL@%
  21315.     hDataCC = PutData((PBYTE)ii.pCC, (ULONG)sizeof(CONVCONTEXT), 0L, (HSZ)NULL,%@NL@%
  21316.             0, 0, pai);%@NL@%
  21317. %@NL@%
  21318.     if (hDataCC == NULL)%@NL@%
  21319.         goto CheckOut;%@NL@%
  21320.         %@NL@%
  21321.     pddes = (PDDESTRUCT)DoCallback(pai, NULL, hp[0].hszTopic,%@NL@%
  21322.                     hp[0].hszApp, 0, (fWild ? XTYP_WILDINIT : XTYP_INIT),%@NL@%
  21323.                     hDataCC);%@NL@%
  21324. %@NL@%
  21325.     if (pddes == NULL)%@NL@%
  21326.         goto CheckOut;%@NL@%
  21327. %@NL@%
  21328.     FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDataCC, FPI_DELETE);%@NL@%
  21329.     DosFreeSeg(SELECTOROF(hDataCC));%@NL@%
  21330.     %@NL@%
  21331.     if (fWild) {%@NL@%
  21332.         php = (PHSZPAIR)DDES_PABDATA(pddes);%@NL@%
  21333.     } else {%@NL@%
  21334.         php = &hp[0];%@NL@%
  21335.         pddes = NULL;%@NL@%
  21336.     }%@NL@%
  21337.         %@NL@%
  21338.     %@AB@%/*%@NL@%
  21339. %@AB@%     * now php points to a 0 terminated list of hszpairs to respond to.%@NL@%
  21340. %@AB@%     */%@AE@%%@NL@%
  21341.     SemEnter();%@NL@%
  21342.     while (QuerylatomLength((LATOM)php->hszApp) &&%@NL@%
  21343.             QuerylatomLength((LATOM)php->hszTopic)) {%@NL@%
  21344.         SemLeave();%@NL@%
  21345.         if ((hwndServer = CreateServerWindow(pai, php->hszTopic)) == 0)%@NL@%
  21346.             break;%@NL@%
  21347.         %@AB@%/*%@NL@%
  21348. %@AB@%         * have the server respond%@NL@%
  21349. %@AB@%         */%@AE@%%@NL@%
  21350.         ii.hszAppName = php->hszApp;%@NL@%
  21351.         ii.hszTopic = php->hszTopic;%@NL@%
  21352.         WinSendMsg(hwndServer, UMSR_INITIATE, (MPARAM)&ii, hwndClient);%@NL@%
  21353. %@NL@%
  21354.         %@AB@%/*%@NL@%
  21355. %@AB@%         * confirm initialization to server app%@NL@%
  21356. %@AB@%         */%@AE@%%@NL@%
  21357.         DoCallback(pai, (HCONV)hwndServer, php->hszTopic, php->hszApp,%@NL@%
  21358.                 0, XTYP_INIT_CONFIRM, 0L);%@NL@%
  21359.             %@NL@%
  21360.         php++;%@NL@%
  21361.         SemEnter();%@NL@%
  21362.     }%@NL@%
  21363.     SemLeave();%@NL@%
  21364.     SemCheckOut();%@NL@%
  21365. CheckOut:    %@NL@%
  21366.     FreeHsz(hp[0].hszApp);%@NL@%
  21367.     FreeHsz(hp[0].hszTopic);%@NL@%
  21368.     if (fWild)%@NL@%
  21369.         FreeData((PMYDDES)pddes, pai);%@NL@%
  21370. }%@NL@%
  21371. %@NL@%
  21372. HWND CreateServerWindow(%@NL@%
  21373. PAPPINFO pai,%@NL@%
  21374. HSZ hszTopic)%@NL@%
  21375. {%@NL@%
  21376.     HWND hwndTSvr, hwndServer;%@NL@%
  21377.     %@NL@%
  21378.     SemCheckOut();%@NL@%
  21379.     %@AB@%/*%@NL@%
  21380. %@AB@%     * locate or make a Topic server window...%@NL@%
  21381. %@AB@%     */%@AE@%%@NL@%
  21382.     if ((hwndTSvr =%@NL@%
  21383.             HwndFromHsz(hszTopic, pai->pSvrTopicList)) == 0) {%@NL@%
  21384.         %@AB@%/*%@NL@%
  21385. %@AB@%         * NO - make one.%@NL@%
  21386. %@AB@%         */%@AE@%%@NL@%
  21387.         if ((hwndTSvr = WinCreateWindow(pai->hwndDmg, SZDEFCLASS, "", 0L,%@NL@%
  21388.                 0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_SVRTOPIC,%@NL@%
  21389.                 0L, 0L)) == 0L) {%@NL@%
  21390.             pai->LastError = DMGERR_PMWIN_ERROR;%@NL@%
  21391.             return(NULL);%@NL@%
  21392.         }%@NL@%
  21393.         AddHwndHszList(hszTopic, hwndTSvr, pai->pSvrTopicList);%@NL@%
  21394.     }%@NL@%
  21395.     %@NL@%
  21396.     %@AB@%/*%@NL@%
  21397. %@AB@%     * Create the server window%@NL@%
  21398. %@AB@%     */%@AE@%%@NL@%
  21399.     if ((hwndServer = WinCreateWindow(hwndTSvr, SZSERVERCLASS, "", 0L,%@NL@%
  21400.             0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_SERVER, 0L, 0L)) == 0L) {%@NL@%
  21401.         pai->LastError = DMGERR_PMWIN_ERROR;%@NL@%
  21402.         return(NULL);%@NL@%
  21403.     }%@NL@%
  21404.     return(hwndServer);%@NL@%
  21405. }%@NL@%
  21406. %@NL@%
  21407. %@AB@%/*%@NL@%
  21408. %@AB@% * main application window - parent of all others in app.%@NL@%
  21409. %@AB@% *%@NL@%
  21410. %@AB@% * 6/12/90 sanfords     Fixed semaphore bug%@NL@%
  21411. %@AB@% */%@AE@%%@NL@%
  21412. MRESULT EXPENTRY DmgWndProc(hwnd, msg, mp1, mp2)%@NL@%
  21413. HWND hwnd;%@NL@%
  21414. USHORT msg;%@NL@%
  21415. MPARAM mp1;%@NL@%
  21416. MPARAM mp2;%@NL@%
  21417. {%@NL@%
  21418. %@AI@%#define %@AE@%pai ((PAPPINFO)mp1) %@NL@%
  21419.     PCBLI pli, pliNext;%@NL@%
  21420.     BOOL fException;%@NL@%
  21421.     HDMGDATA hDataRet;%@NL@%
  21422. %@NL@%
  21423.     hwnd;%@NL@%
  21424.     mp2;%@NL@%
  21425.         %@NL@%
  21426.     switch (msg) {%@NL@%
  21427.     case UM_CHECKCBQ:%@NL@%
  21428.         %@AB@%/*%@NL@%
  21429. %@AB@%         * We consider everything to be blocked if we are in a client%@NL@%
  21430. %@AB@%         * transfer modal loop.   This prevents recursive timeout%@NL@%
  21431. %@AB@%         * calls.%@NL@%
  21432. %@AB@%         */%@AE@%%@NL@%
  21433.         if (pai->hwndTimer)%@NL@%
  21434.             return(0);%@NL@%
  21435.             %@NL@%
  21436.         %@AB@%/*%@NL@%
  21437. %@AB@%         * This is where we actually do callbacks.  We do them via this%@NL@%
  21438. %@AB@%         * window proc so that we can asynchronously institute callbacks%@NL@%
  21439. %@AB@%         * via a PostMsg().%@NL@%
  21440. %@AB@%         */%@AE@%%@NL@%
  21441.         SemCheckOut();%@NL@%
  21442.         SemEnter();%@NL@%
  21443.         %@AB@%/*%@NL@%
  21444. %@AB@%         * process all enabled conversation callbacks.%@NL@%
  21445. %@AB@%         */%@AE@%%@NL@%
  21446.         for (pli = (PCBLI)pai->plstCB->pItemFirst; pli; pli = (PCBLI)pliNext) {%@NL@%
  21447.             pliNext = (PCBLI)pli->next;%@NL@%
  21448.             fException = FindLstItem(pai->plstCBExceptions, CmpULONG, (PLITEM)pli)%@NL@%
  21449.                     == NULL ? FALSE : TRUE;%@NL@%
  21450.             if (fException == pai->fEnableCB)%@NL@%
  21451.                 continue; %@AB@%/* blocked */%@AE@%%@NL@%
  21452. %@NL@%
  21453.             pai->cInCallback++;%@NL@%
  21454.             SemLeave();%@NL@%
  21455.             %@AB@%/*%@NL@%
  21456. %@AB@%             * make the actual callback here.%@NL@%
  21457. %@AB@%             */%@AE@%%@NL@%
  21458.             hDataRet = DoCallback(pai, pli->hConv, pli->hszTopic,%@NL@%
  21459.                     pli->hszItem, pli->usFmt, pli->usType, pli->hDmgData);%@NL@%
  21460.             SemEnter();%@NL@%
  21461.             if (pai->cInCallback > 0)   %@AB@%/* test incase exlst processing messed it up */%@AE@%%@NL@%
  21462.                 pai->cInCallback--;%@NL@%
  21463. %@NL@%
  21464.             %@AB@%/*%@NL@%
  21465. %@AB@%             * If the callback resulted in a BLOCK, disable this conversation.%@NL@%
  21466. %@AB@%             */%@AE@%%@NL@%
  21467.             if (hDataRet == CBR_BLOCK && !(pli->usType & XTYPF_NOBLOCK)) {%@NL@%
  21468.                 SemLeave();%@NL@%
  21469.                 DdeEnableCallback(pli->hConv, FALSE);%@NL@%
  21470.                 SemEnter();%@NL@%
  21471.                 continue;%@NL@%
  21472.             } else {%@NL@%
  21473.                 %@AB@%/*%@NL@%
  21474. %@AB@%                 * otherwise finish processing the callback.%@NL@%
  21475. %@AB@%                 */%@AE@%%@NL@%
  21476.                 if (WinIsWindow(DMGHAB, pli->hConvPartner)) {%@NL@%
  21477.                     SemLeave();%@NL@%
  21478.                     QReply(pli, (PDDESTRUCT)hDataRet);%@NL@%
  21479.                     SemEnter();%@NL@%
  21480.                 }%@NL@%
  21481.                 RemoveLstItem(pai->plstCB, (PLITEM)pli);%@NL@%
  21482.             }%@NL@%
  21483.         }%@NL@%
  21484.         SemLeave();%@NL@%
  21485.         return(0);%@NL@%
  21486.         break;%@NL@%
  21487. %@NL@%
  21488.     default:%@NL@%
  21489.         WinDefWindowProc(hwnd, msg, mp1, mp2);%@NL@%
  21490.         break;%@NL@%
  21491.     }%@NL@%
  21492. %@AI@%#undef %@AE@%pai %@NL@%
  21493. }%@NL@%
  21494. %@NL@%
  21495. %@NL@%
  21496. HDMGDATA DoCallback(%@NL@%
  21497. PAPPINFO pai,%@NL@%
  21498. HCONV hConv,%@NL@%
  21499. HSZ hszTopic,%@NL@%
  21500. HSZ hszItem,%@NL@%
  21501. USHORT usFmt,%@NL@%
  21502. USHORT usType,%@NL@%
  21503. HDMGDATA hDmgData)%@NL@%
  21504. {%@NL@%
  21505.     HDMGDATA hDataRet;%@NL@%
  21506.     %@NL@%
  21507.     AssertF(IncHszCount(hszTopic) && FreeHsz(hszTopic), "Bad hszTopic on callback");%@NL@%
  21508.     AssertF(IncHszCount(hszItem) && FreeHsz(hszItem), "Bad hszItem on callback");%@NL@%
  21509. %@NL@%
  21510.     if (usType & XCLASS_DATAIN) {%@NL@%
  21511.         AssertF(CheckSel(SELECTOROF(hDmgData)), "invalid callback data handle");%@NL@%
  21512.         ((PMYDDES)hDmgData)->fs |= HDATA_READONLY;%@NL@%
  21513.     }%@NL@%
  21514.     %@NL@%
  21515. %@AI@%#ifdef %@AE@%CRUISER     %@NL@%
  21516.     if (pai->afCmd & DMGCMD_32BIT)%@NL@%
  21517.         hDataRet = ThkCallback(hConv, hszTopic, hszItem, usFmt, usType, hDmgData,%@NL@%
  21518.                 pai->pfnCallback);%@NL@%
  21519.     else%@NL@%
  21520. %@AI@%#endif %@AE@%    %@NL@%
  21521.         hDataRet = (*pai->pfnCallback)(hConv, hszTopic, hszItem, usFmt, usType,%@NL@%
  21522.                 hDmgData);%@NL@%
  21523. %@NL@%
  21524.     if (usType & XCLASS_DATA && CheckSel(SELECTOROF(hDataRet)) > sizeof(MYDDES) &&%@NL@%
  21525.             ((PMYDDES)hDataRet)->magic == MYDDESMAGIC) {%@NL@%
  21526.         if (((PMYDDES)hDataRet)->pai != pai) {%@NL@%
  21527.             AssertF(FALSE, "hData from callback not created by same thread");%@NL@%
  21528.             pai->LastError = DMGERR_DLL_USAGE;%@NL@%
  21529.             hDataRet = NULL;%@NL@%
  21530.         }%@NL@%
  21531.     }%@NL@%
  21532.     return(hDataRet);%@NL@%
  21533. }%@NL@%
  21534. %@NL@%
  21535. %@NL@%
  21536. %@NL@%
  21537. %@NL@%
  21538. %@2@%%@AH@%EA.C%@AE@%%@EH@%%@NL@%
  21539. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\STOCK\EA.C%@AE@%%@NL@%
  21540. %@NL@%
  21541. %@AB@%/***        ea.c - layer for EA support%@NL@%
  21542. %@AB@% *%@NL@%
  21543. %@AB@% *        Author:%@NL@%
  21544. %@AB@% *            Benjamin W. Slivka%@NL@%
  21545. %@AB@% *            (c) 1990%@NL@%
  21546. %@AB@% *            Microsoft Corporation%@NL@%
  21547. %@AB@% *%@NL@%
  21548. %@AB@% *        History:%@NL@%
  21549. %@AB@% *            08-Feb-1990 bens        Initial version (Subset from EA.EXE sources)%@NL@%
  21550. %@AB@% *            02-May-1990 bens        Added SetEAValue (copied from ea.exe)%@NL@%
  21551. %@AB@% *            01-Jun-1990 bens        Support binary EAs%@NL@%
  21552. %@AB@% */%@AE@%%@NL@%
  21553. %@NL@%
  21554. %@AI@%#define %@AE@%INCL_DOSERRORS %@NL@%
  21555. %@AI@%#define %@AE@%INCL_DOSFILEMGR %@NL@%
  21556. %@AI@%#define %@AE@%INCL_NOPM %@NL@%
  21557. %@NL@%
  21558. %@AI@%#include %@AE@%<os2.h> %@NL@%
  21559. %@NL@%
  21560. %@AI@%#include %@AE@%<ctype.h> %@NL@%
  21561. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  21562. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  21563. %@AI@%#include %@AE@%<string.h> %@NL@%
  21564. %@AI@%#include %@AE@%<memory.h> %@NL@%
  21565. %@NL@%
  21566. %@AI@%#include %@AE@%"ea.h" %@NL@%
  21567. %@AI@%#include %@AE@%"mem.h" %@NL@%
  21568. %@NL@%
  21569. %@NL@%
  21570. %@AI@%#ifdef %@AE@%CHECKASSERTS %@NL@%
  21571. %@AI@%#define %@AE@%dbg(a)        a %@NL@%
  21572. %@AI@%#else %@AE@%%@NL@%
  21573. %@AI@%#define %@AE@%dbg(a) %@NL@%
  21574. %@AI@%#endif %@AE@%%@NL@%
  21575. %@NL@%
  21576. // Buffer sizes for EA API calls%@NL@%
  21577. %@AI@%#define %@AE@%CB_GEAL       400                // Enough for one GEA in list %@NL@%
  21578. %@AI@%#define %@AE@%CB_FEAL      2000                // Enough for large file list %@NL@%
  21579. %@NL@%
  21580. %@NL@%
  21581. char *            TranslateValue(char *pbValue,USHORT cbValue,USHORT *pcbValue);%@NL@%
  21582. %@NL@%
  21583. %@NL@%
  21584. %@AB@%/***        EAQueryValue - Get text EA value from file%@NL@%
  21585. %@AB@% *%@NL@%
  21586. %@AB@% *        Entry%@NL@%
  21587. %@AB@% *            pszFile - File path%@NL@%
  21588. %@AB@% *            pszName - EA name%@NL@%
  21589. %@AB@% *            pcbValue - USHORT to receive value length%@NL@%
  21590. %@AB@% *%@NL@%
  21591. %@AB@% *        Exit-Success%@NL@%
  21592. %@AB@% *            returns non-zero pointer to value; Caller must free this!%@NL@%
  21593. %@AB@% *                If value is ASCII%@NL@%
  21594. %@AB@% *                    *pcbValue == 0;%@NL@%
  21595. %@AB@% *                If value is BINARY%@NL@%
  21596. %@AB@% *                    *pcbValue == length of value;%@NL@%
  21597. %@AB@% *%@NL@%
  21598. %@AB@% *        Exit-Failure%@NL@%
  21599. %@AB@% *            returns NULL%@NL@%
  21600. %@AB@% */%@AE@%%@NL@%
  21601. char *EAQueryValue(char *pszFile,char *pszName,USHORT *pcbValue)%@NL@%
  21602. {%@NL@%
  21603.     USHORT        cb;%@NL@%
  21604.     EAOP        eaop;%@NL@%
  21605.     FEA *        pfea;%@NL@%
  21606.     FEA *        pfeaEnd;%@NL@%
  21607.     FEALIST *        pFEAList;%@NL@%
  21608.     GEA *        pgea;%@NL@%
  21609.     GEALIST *        pGEAList;%@NL@%
  21610.     char *        psz;%@NL@%
  21611.     char *        pszValue;%@NL@%
  21612.     USHORT        rc;%@NL@%
  21613. %@NL@%
  21614.     //%@NL@%
  21615.     // Alloc GEAList and FEAList%@NL@%
  21616.     //%@NL@%
  21617.     pGEAList = MemAlloc(CB_GEAL);%@NL@%
  21618.     if (pGEAList == NULL) {%@NL@%
  21619.         return NULL;%@NL@%
  21620.     }%@NL@%
  21621. %@NL@%
  21622.     pFEAList = MemAlloc(CB_FEAL);%@NL@%
  21623.     if (pFEAList == NULL) {%@NL@%
  21624.         MemFree(pGEAList);%@NL@%
  21625.         return NULL;%@NL@%
  21626.     }%@NL@%
  21627. %@NL@%
  21628.     // Build GEA List with one GEA%@NL@%
  21629. %@NL@%
  21630.     pgea = pGEAList->list;                // Point at first GEA%@NL@%
  21631.     cb = strlen(pszName);%@NL@%
  21632.     pgea->cbName = (UCHAR)cb;                // Set length%@NL@%
  21633.     memcpy(pgea->szName,pszName,cb+1);        // Copy name and NUL%@NL@%
  21634.     pgea = (GEA *)((char *)pgea + cb + sizeof(GEA));%@NL@%
  21635.     pGEAList->cbList = (char *)pgea - (char *)pGEAList; // Set buffer size%@NL@%
  21636. %@NL@%
  21637.     // Get attribute value%@NL@%
  21638. %@NL@%
  21639.     pFEAList->cbList = CB_FEAL;         // Set size of FEA list%@NL@%
  21640.     eaop.fpGEAList = pGEAList;%@NL@%
  21641.     eaop.fpFEAList = pFEAList;%@NL@%
  21642. %@NL@%
  21643.     rc = DosQPathInfo(pszFile,                // File path%@NL@%
  21644.                       FIL_QUERYEASFROMLIST, // info level%@NL@%
  21645.                       (PBYTE)&eaop,        // EAOP structure%@NL@%
  21646.                       sizeof(eaop),        // Size of EAOP%@NL@%
  21647.                       0L);                // Reserved%@NL@%
  21648.     pfea = (FEA *)pFEAList->list;        // Point at FEA%@NL@%
  21649. %@NL@%
  21650.     //        NOTE: DosQPathInfo only fails if there is an inconsistency in%@NL@%
  21651.     //              one of its parameters.  It DOES NOT fail if the EA is%@NL@%
  21652.     //              not present.  Rather, on a file system that does not%@NL@%
  21653.     //              support EAs, it appears to return pFEAList->cbList ==%@NL@%
  21654.     //              sizeof(pFEAList->cbList), indicating no FEAs are present.%@NL@%
  21655.     //              If the file system *does* support EAs, but the particular%@NL@%
  21656.     //              EA is not present, pFEA->cbValue == 0.%@NL@%
  21657. %@NL@%
  21658.     if ((rc == 0) &&                        // Call succeeded,...%@NL@%
  21659.         ((pFEAList->cbList) > sizeof(pFEAList->cbList)) && // FEA is there,...%@NL@%
  21660.         (pfea->cbValue > 0)) {                // and file has EA value!%@NL@%
  21661.         // Parse EA value%@NL@%
  21662.         cb = pfea->cbName;%@NL@%
  21663.         psz = (char *)pfea + sizeof(FEA); // Point at name%@NL@%
  21664.         pszValue = psz + cb + 1;        // Point at value%@NL@%
  21665.         psz = TranslateValue(pszValue,pfea->cbValue,pcbValue);%@NL@%
  21666.     }%@NL@%
  21667.     else%@NL@%
  21668.        psz = NULL;                        // EA not present, or too big%@NL@%
  21669. %@NL@%
  21670.     MemFree(pFEAList);%@NL@%
  21671.     MemFree(pGEAList);%@NL@%
  21672.     return psz;%@NL@%
  21673. }%@NL@%
  21674. %@NL@%
  21675. %@NL@%
  21676. %@AB@%/***        TranslateValue - produce printable representation of EA value%@NL@%
  21677. %@AB@% *%@NL@%
  21678. %@AB@% *        Entry%@NL@%
  21679. %@AB@% *            pbValue  - Value buffer%@NL@%
  21680. %@AB@% *            cbValue  - Length of value buffer%@NL@%
  21681. %@AB@% *            pcbValue - USHORT to receive actual value length%@NL@%
  21682. %@AB@% *%@NL@%
  21683. %@AB@% *        Exit-Success%@NL@%
  21684. %@AB@% *            Returns non-zero pointer to value; caller MUST free!%@NL@%
  21685. %@AB@% *                If value is ASCII%@NL@%
  21686. %@AB@% *                    *pcbValue == 0;%@NL@%
  21687. %@AB@% *                If value is BINARY%@NL@%
  21688. %@AB@% *                    *pcbValue == length of value;%@NL@%
  21689. %@AB@% *%@NL@%
  21690. %@AB@% *        Exit-Failure%@NL@%
  21691. %@AB@% *            Returns NULL%@NL@%
  21692. %@AB@% *%@NL@%
  21693. %@AB@% *%@NL@%
  21694. %@AB@% *  EAT_MVMT - Multi-value, Multi-type%@NL@%
  21695. %@AB@% *%@NL@%
  21696. %@AB@% *        +------+----------+-------+------+--------+-------+---+---+---+---+%@NL@%
  21697. %@AB@% *        | Type | Codepage | Count | Type | Length | Value |...| T | L | V |%@NL@%
  21698. %@AB@% *        +------+----------+-------+------+--------+-------+---+---+---+---+%@NL@%
  21699. %@AB@% *           us            us             us      us      us       ?%@NL@%
  21700. %@AB@% *        \________________________/ \_____________________/     \_________/%@NL@%
  21701. %@AB@% *           MVMT header                          Value 1                 Value N%@NL@%
  21702. %@AB@% *%@NL@%
  21703. %@AB@% */%@AE@%%@NL@%
  21704. char * TranslateValue(char *pbValue,USHORT cbValue,USHORT *pcbValue)%@NL@%
  21705. {%@NL@%
  21706.     USHORT cb=cbValue;%@NL@%
  21707.     USHORT codePage;%@NL@%
  21708.     USHORT cValue;%@NL@%
  21709.     char * pbDst;%@NL@%
  21710.     char * pbSrc;%@NL@%
  21711.     char * pszNew;%@NL@%
  21712.     USHORT type;%@NL@%
  21713. %@NL@%
  21714.     // Parse MVMT header, if present%@NL@%
  21715. %@NL@%
  21716.     pbSrc = pbValue;%@NL@%
  21717. %@NL@%
  21718.     type = *(USHORT *)pbSrc;                // Get EA value type%@NL@%
  21719.     if (type == EAT_MVMT) {%@NL@%
  21720.         pbSrc += sizeof(USHORT);        // Skip type%@NL@%
  21721.         codePage = *((USHORT*)pbSrc)++; // Get code page%@NL@%
  21722.         cValue = *((USHORT*)pbSrc)++;        // Get count of values%@NL@%
  21723.         if (cValue != 1)                // Not exactly one value%@NL@%
  21724.             return NULL;                //  Fail%@NL@%
  21725.         type = *(USHORT *)pbSrc;        // Get EA value type%@NL@%
  21726.     }%@NL@%
  21727. %@NL@%
  21728. %@NL@%
  21729.     // Parse value%@NL@%
  21730. %@NL@%
  21731.     if ( (type == EAT_ASCII) || (type == EAT_BINARY) ) {%@NL@%
  21732.         pbSrc += sizeof(USHORT);        // Skip type%@NL@%
  21733.         cb = *((USHORT *)pbSrc)++;        // Get data length%@NL@%
  21734. %@NL@%
  21735.         // Allocate buffer for data%@NL@%
  21736. %@NL@%
  21737.         pszNew = MemAlloc(cb+1);        // Leave room for NUL, in ASCII case%@NL@%
  21738.         if (pszNew == NULL)%@NL@%
  21739.             return NULL;%@NL@%
  21740.         pbDst = pszNew;%@NL@%
  21741. %@NL@%
  21742.         // Copy data%@NL@%
  21743. %@NL@%
  21744.         memcpy(pbDst,pbSrc,cb);         // Copy value%@NL@%
  21745.         pbDst += cb;                        // Advance destination pointer%@NL@%
  21746. %@NL@%
  21747.         if (type == EAT_ASCII) {%@NL@%
  21748.             *pbDst++ = '\0';                // Terminate ASCIIZ string%@NL@%
  21749.             *pcbValue = 0;                // Indicate value is ASCIIZ%@NL@%
  21750.         }%@NL@%
  21751.         else%@NL@%
  21752.             *pcbValue = cb;                // Indicate value is binary%@NL@%
  21753.         return pszNew;                        // Return value%@NL@%
  21754.     }%@NL@%
  21755.     else%@NL@%
  21756.         return NULL;                        //  Fail%@NL@%
  21757. }%@NL@%
  21758. %@NL@%
  21759. %@NL@%
  21760. %@AB@%/***        EASetValue - Create/Change/Delete an EA%@NL@%
  21761. %@AB@% *%@NL@%
  21762. %@AB@% *        Entry%@NL@%
  21763. %@AB@% *            pszFile  - file path%@NL@%
  21764. %@AB@% *            pszName  - EA name%@NL@%
  21765. %@AB@% *            cbValue  - EA length; 0 => pszValue is ASCIIZ%@NL@%
  21766. %@AB@% *            pszValue - EA value; NULL to delete EA%@NL@%
  21767. %@AB@% *%@NL@%
  21768. %@AB@% *        Exit-Success%@NL@%
  21769. %@AB@% *            returns TRUE%@NL@%
  21770. %@AB@% *%@NL@%
  21771. %@AB@% *        Exit-Failure%@NL@%
  21772. %@AB@% *            returns FALSE%@NL@%
  21773. %@AB@% *%@NL@%
  21774. %@AB@% */%@AE@%%@NL@%
  21775. BOOL EASetValue(char *pszFile,char *pszName,USHORT cbValue,char *pszValue)%@NL@%
  21776. {%@NL@%
  21777.     USHORT        cbName;%@NL@%
  21778.     EAOP        eaop;%@NL@%
  21779.     FEA *        pfea;%@NL@%
  21780.     FEALIST *        pFEAList;%@NL@%
  21781.     char *        psz;%@NL@%
  21782.     USHORT        rc;%@NL@%
  21783.     USHORT        type;%@NL@%
  21784. %@NL@%
  21785.     // Determine operation%@NL@%
  21786. %@NL@%
  21787.     if (pszValue == NULL) {                // Delete this EA%@NL@%
  21788.         type = EAT_ASCII;%@NL@%
  21789.         cbValue = 0;%@NL@%
  21790.     }%@NL@%
  21791.     else if (cbValue == 0) {                // Create/Change value%@NL@%
  21792.         type = EAT_ASCII;%@NL@%
  21793.         cbValue = strlen(pszValue);        // Compute length (do not count NUL!)%@NL@%
  21794.     }%@NL@%
  21795.     else {                                // Create/Change Binary value%@NL@%
  21796.         type = EAT_BINARY;%@NL@%
  21797.     }%@NL@%
  21798. %@NL@%
  21799.     //%@NL@%
  21800.     // Alloc FEA List%@NL@%
  21801.     //%@NL@%
  21802.     pFEAList = MemAlloc(CB_FEAL);%@NL@%
  21803.     if (pFEAList == NULL)%@NL@%
  21804.         return FALSE;%@NL@%
  21805. %@NL@%
  21806.     cbName = strlen(pszName);%@NL@%
  21807. %@NL@%
  21808.     //%@NL@%
  21809.     // Build EA structure%@NL@%
  21810.     //%@NL@%
  21811.     pfea = (FEA *)pFEAList->list;        // Point at first FEA%@NL@%
  21812.     pfea->fEA = 0;                        // No flag settings%@NL@%
  21813.     pfea->cbName = (UCHAR)cbName;        // Set name length%@NL@%
  21814.     pfea->cbValue = cbValue;                // Set value length%@NL@%
  21815. %@NL@%
  21816.     psz = (char *)pfea + sizeof(FEA);        // Point at location for name%@NL@%
  21817.     memcpy(psz,pszName,cbName+1);        // Copy Name *and* NUL%@NL@%
  21818.     psz += cbName+1;                        // Point at location for value%@NL@%
  21819.     if (cbValue > 0) {                        // Edit/Create EA%@NL@%
  21820.         *((USHORT *)psz)++ = EAT_MVMT;        // Set MVMT type (to record code page!)%@NL@%
  21821.         *((USHORT *)psz)++ = NULL;        // Set codepage%@NL@%
  21822.         *((USHORT *)psz)++ = 1;         // Only one TLV record%@NL@%
  21823.         *((USHORT *)psz)++ = type;        // Set EA type%@NL@%
  21824.         *((USHORT *)psz)++ = cbValue;        // Set ASCII length%@NL@%
  21825. %@NL@%
  21826.         pfea->cbValue += 5*sizeof(USHORT); // MVMT header and type and length%@NL@%
  21827.         memcpy(psz,pszValue,cbValue);        // Copy Value%@NL@%
  21828.     }%@NL@%
  21829.     pfea = (FEA *)(psz + cbValue);        // Point at byte after FEA%@NL@%
  21830. %@NL@%
  21831.     //%@NL@%
  21832.     // Set size of FEA List (only one FEA)%@NL@%
  21833.     //%@NL@%
  21834. %@NL@%
  21835.     pFEAList->cbList = (char *)pfea - (char *)pFEAList;%@NL@%
  21836. %@NL@%
  21837.     eaop.fpGEAList = NULL;%@NL@%
  21838.     eaop.fpFEAList = pFEAList;%@NL@%
  21839. %@NL@%
  21840.     rc = DosSetPathInfo(pszFile,            // File path%@NL@%
  21841.                         FIL_QUERYEASIZE,    // Set EA%@NL@%
  21842.                         (PBYTE)&eaop,            // EAOP structure%@NL@%
  21843.                         sizeof(eaop),            // Size of EAOP%@NL@%
  21844.                         0,                    // Options%@NL@%
  21845.                         0L);                    // Reserved%@NL@%
  21846.     MemFree(pFEAList);%@NL@%
  21847.     return (rc == 0);%@NL@%
  21848. }%@NL@%
  21849. %@NL@%
  21850. %@NL@%
  21851. %@2@%%@AH@%EDPLINE.C%@AE@%%@EH@%%@NL@%
  21852. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\EDPLINE\EDPLINE.C%@AE@%%@NL@%
  21853. %@NL@%
  21854. %@AB@%/*%@NL@%
  21855. %@AB@%    edpline.c -- polyline editor, for practice in mouse handling%@NL@%
  21856. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  21857. %@AB@%*/%@AE@%%@NL@%
  21858. %@AI@%#define %@AE@%INCL_DOSMEMMGR %@NL@%
  21859. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  21860. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  21861. %@AI@%#define %@AE@%INCL_WINSWITCHLIST %@NL@%
  21862. %@AI@%#define %@AE@%INCL_WINDIALOGS %@NL@%
  21863. %@AI@%#define %@AE@%INCL_GPIBITMAPS %@NL@%
  21864. %@AI@%#define %@AE@%INCL_GPIPRIMITIVES %@NL@%
  21865. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  21866. %@AI@%#define %@AE@%       INCL_WININPUT %@NL@%
  21867. %@AI@%#define %@AE@%       INCL_WINFRAMEMGR %@NL@%
  21868. %@AI@%#include %@AE@%<os2.h> %@NL@%
  21869. %@NL@%
  21870. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  21871. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  21872. %@NL@%
  21873. %@AI@%#include %@AE@%"edpline.h" %@NL@%
  21874. %@NL@%
  21875. %@NL@%
  21876. %@NL@%
  21877. %@AI@%#define %@AE@%       abs(x)                        (((x) > 0) ? (x) : -(x)) %@NL@%
  21878. %@AI@%#define %@AE@%PRIM_POLYLINE                0x0001 %@NL@%
  21879. %@AI@%#define %@AE@%PRIM_POLYFILLET         0x0002 %@NL@%
  21880. %@AI@%#define %@AE@%PRIM_POLYSPLINE         0x0004 %@NL@%
  21881. %@AI@%#define %@AE@%PRIM_POINTARC                0x0008 %@NL@%
  21882. %@NL@%
  21883. %@NL@%
  21884. %@AB@%/************************************************************************%@NL@%
  21885. %@AB@%*%@NL@%
  21886. %@AB@%*   Function declarations%@NL@%
  21887. %@AB@%*%@NL@%
  21888. %@AB@%************************************************************************/%@AE@%%@NL@%
  21889. %@NL@%
  21890. %@AB@%/* Private functions */%@AE@%%@NL@%
  21891. %@NL@%
  21892. VOID   cdecl main(VOID);%@NL@%
  21893. BOOL   InitGlobals(VOID);%@NL@%
  21894. BOOL   InitApp(VOID);%@NL@%
  21895. VOID   Close(HWND);%@NL@%
  21896. VOID   Command(HWND, USHORT);%@NL@%
  21897. VOID   Paint(HPS, BOOL);%@NL@%
  21898. VOID   MouseMove(HWND, MPARAM);%@NL@%
  21899. VOID   ButtonUp(HWND, USHORT);%@NL@%
  21900. VOID   ButtonDown(HWND, USHORT, MPARAM);%@NL@%
  21901. USHORT IsPtInList(PPOINTL);%@NL@%
  21902. USHORT AddPtToList(PPOINTL);%@NL@%
  21903. BOOL   IsPtCloseToLine(PPOINTL, PPOINTL, PPOINTL);%@NL@%
  21904. VOID   DrawPrimitive(HPS, USHORT);%@NL@%
  21905. VOID   DrawPolyLine(HPS);%@NL@%
  21906. VOID   DrawPolyFillet(HPS);%@NL@%
  21907. VOID   DrawPolySpline(HPS);%@NL@%
  21908. VOID   DrawPointArc(HPS);%@NL@%
  21909. VOID   DrawControlPoints(HPS, LONG, PPOINTL);%@NL@%
  21910. VOID   MyMessageBox(HWND, PSZ);%@NL@%
  21911. VOID   SwapLong(PLONG, PLONG);%@NL@%
  21912. %@NL@%
  21913. %@AB@%/* Exported functions */%@AE@%%@NL@%
  21914. %@NL@%
  21915. ULONG        EXPENTRY WndProc(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  21916. MRESULT EXPENTRY AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  21917. %@NL@%
  21918. %@NL@%
  21919. %@NL@%
  21920. %@AB@%/************************************************************************%@NL@%
  21921. %@AB@%*%@NL@%
  21922. %@AB@%*   Global Variables%@NL@%
  21923. %@AB@%*%@NL@%
  21924. %@AB@%************************************************************************/%@AE@%%@NL@%
  21925. %@NL@%
  21926. typedef struct%@NL@%
  21927. {%@NL@%
  21928.     HAB  hab;%@NL@%
  21929.     HMQ  hMsgQ;%@NL@%
  21930.     HWND hwndFrame;%@NL@%
  21931.     HWND hwnd;%@NL@%
  21932. %@NL@%
  21933.     ULONG   flPrim;%@NL@%
  21934.     BOOL    fDisplayControlPoints;%@NL@%
  21935.     LONG    cptl;%@NL@%
  21936.     PPOINTL pptl;%@NL@%
  21937. %@NL@%
  21938.     USHORT  usPtGrabbed;%@NL@%
  21939.     BOOL    fDragging;%@NL@%
  21940. %@NL@%
  21941.     ULONG   ulHitPrecision;%@NL@%
  21942. %@NL@%
  21943. } GLOBALDATA;%@NL@%
  21944. GLOBALDATA global;%@NL@%
  21945. %@NL@%
  21946. %@NL@%
  21947. %@NL@%
  21948. %@NL@%
  21949. %@AB@%/************************************************************************%@NL@%
  21950. %@AB@%*%@NL@%
  21951. %@AB@%*   main%@NL@%
  21952. %@AB@%*%@NL@%
  21953. %@AB@%*   WinInitialize resizes our ring 2 stack, among other things, so%@NL@%
  21954. %@AB@%*   we won't GP fault trying to do graphics.  WinCreateMsgQueue defines%@NL@%
  21955. %@AB@%*   us as a REAL PM app. (as well as the WINDOWAPI statement in the .DEF%@NL@%
  21956. %@AB@%*   file...)   Call a sub to register our window class and create a window.%@NL@%
  21957. %@AB@%*   Loop over messages.  Exit cleanly.%@NL@%
  21958. %@AB@%*%@NL@%
  21959. %@AB@%************************************************************************/%@AE@%%@NL@%
  21960. %@NL@%
  21961. VOID cdecl%@NL@%
  21962. main()%@NL@%
  21963. {%@NL@%
  21964.     QMSG qMsg;%@NL@%
  21965.     int iRet = 0;%@NL@%
  21966. %@NL@%
  21967. %@NL@%
  21968.     global.hab         = WinInitialize(0);%@NL@%
  21969.     global.hMsgQ = WinCreateMsgQueue(global.hab, 0);%@NL@%
  21970. %@NL@%
  21971.     if (InitApp())%@NL@%
  21972.         while (WinGetMsg( global.hab, (PQMSG)&qMsg, (HWND)NULL, 0, 0 ))%@NL@%
  21973.             WinDispatchMsg( global.hab, (PQMSG)&qMsg );%@NL@%
  21974.     else%@NL@%
  21975.         iRet = -1;%@NL@%
  21976. %@NL@%
  21977.     WinDestroyWindow( global.hwndFrame );%@NL@%
  21978.     WinDestroyMsgQueue( global.hMsgQ );%@NL@%
  21979.     WinTerminate( global.hab );%@NL@%
  21980.     DosExit(EXIT_PROCESS, iRet);%@NL@%
  21981. }%@NL@%
  21982. %@NL@%
  21983. %@NL@%
  21984. %@NL@%
  21985. %@NL@%
  21986. %@AB@%/****************************************************************************%@NL@%
  21987. %@AB@%*%@NL@%
  21988. %@AB@%*   InitGlobals%@NL@%
  21989. %@AB@%*%@NL@%
  21990. %@AB@%*   Initialize global variables.%@NL@%
  21991. %@AB@%*%@NL@%
  21992. %@AB@%****************************************************************************/%@AE@%%@NL@%
  21993. %@NL@%
  21994. BOOL%@NL@%
  21995. InitGlobals()%@NL@%
  21996. {%@NL@%
  21997.     global.flPrim = PRIM_POLYLINE;%@NL@%
  21998.     global.fDisplayControlPoints = TRUE;%@NL@%
  21999. %@NL@%
  22000.     global.cptl = 0L;%@NL@%
  22001.     global.pptl = NULL;%@NL@%
  22002.     if (DosAllocSeg(CPTLMAX * sizeof(POINTL),%@NL@%
  22003.                    ((PUSHORT)&global.pptl)+1, 0))%@NL@%
  22004.         return FALSE;%@NL@%
  22005. %@NL@%
  22006.     global.usPtGrabbed = -1;%@NL@%
  22007.     global.fDragging = FALSE;%@NL@%
  22008.     global.ulHitPrecision = 0L;%@NL@%
  22009. %@NL@%
  22010.     return TRUE;%@NL@%
  22011. }%@NL@%
  22012. %@NL@%
  22013. %@NL@%
  22014. %@NL@%
  22015. %@NL@%
  22016. %@AB@%/****************************************************************************%@NL@%
  22017. %@AB@%*%@NL@%
  22018. %@AB@%*   InitApp%@NL@%
  22019. %@AB@%*%@NL@%
  22020. %@AB@%*   Register application window class and creates standard window.%@NL@%
  22021. %@AB@%*%@NL@%
  22022. %@AB@%****************************************************************************/%@AE@%%@NL@%
  22023. %@NL@%
  22024. %@AI@%#define %@AE@%INIT_MENU_ITEM(val, var)     \ %@NL@%
  22025.         TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var))%@NL@%
  22026. %@NL@%
  22027. BOOL%@NL@%
  22028. InitApp()%@NL@%
  22029. {%@NL@%
  22030.     char szTitle[24];%@NL@%
  22031.     ULONG ctldata;%@NL@%
  22032.     PID pid;%@NL@%
  22033.     TID tid;%@NL@%
  22034.     HSWITCH hsw;%@NL@%
  22035.     static SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE,%@NL@%
  22036.                              SWL_JUMPABLE, "Edit Polyline", 0 };%@NL@%
  22037. %@NL@%
  22038.     if (!InitGlobals())%@NL@%
  22039.         return FALSE;%@NL@%
  22040. %@NL@%
  22041. %@NL@%
  22042.     %@AB@%/*  Register Application Window Class  */%@AE@%%@NL@%
  22043. %@NL@%
  22044.     WinLoadString( global.hab, (HMODULE) NULL, IDS_TITLE, sizeof(szTitle), (PCH)szTitle );%@NL@%
  22045.     if ( !WinRegisterClass( global.hab, (PCH)szTitle, (PFNWP)WndProc,%@NL@%
  22046.             CS_SIZEREDRAW, 0 ))%@NL@%
  22047.         return FALSE;%@NL@%
  22048. %@NL@%
  22049. %@NL@%
  22050. %@NL@%
  22051.     %@AB@%/* Create a window instance of class "PolyLine Editor" */%@AE@%%@NL@%
  22052. %@NL@%
  22053.     ctldata = FCF_STANDARD &%@NL@%
  22054.      ~(ULONG)(FCF_ICON | FCF_ACCELTABLE | FCF_TASKLIST);%@NL@%
  22055. %@NL@%
  22056.     if (global.hwndFrame = WinCreateStdWindow(%@NL@%
  22057.         HWND_DESKTOP,                   %@AB@%/* specify desktop as parent window            */%@AE@%%@NL@%
  22058.         WS_VISIBLE,                   %@AB@%/* window styles                            */%@AE@%%@NL@%
  22059.         &ctldata,                   %@AB@%/* frame creation flags                    */%@AE@%%@NL@%
  22060.         (PCH)szTitle,                   %@AB@%/* window class name                     */%@AE@%%@NL@%
  22061.         (PCH)szTitle,                   %@AB@%/* name appearing in window caption            */%@AE@%%@NL@%
  22062.         0L,                           %@AB@%/*                                            */%@AE@%%@NL@%
  22063.         (HMODULE)NULL,                   %@AB@%/* use current executable module id            */%@AE@%%@NL@%
  22064.         IDR_EDPLINE,                   %@AB@%/* menu id                                    */%@AE@%%@NL@%
  22065.         (HWND FAR *)&global.hwnd   %@AB@%/* window handle                            */%@AE@%%@NL@%
  22066.         ))%@NL@%
  22067.     {%@NL@%
  22068.         INIT_MENU_ITEM(IDM_CTLPOINTS, global.fDisplayControlPoints);%@NL@%
  22069. %@NL@%
  22070.         if (global.flPrim & PRIM_POLYLINE)%@NL@%
  22071.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYLINE);%@NL@%
  22072.         if (global.flPrim & PRIM_POLYFILLET)%@NL@%
  22073.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET);%@NL@%
  22074.         if (global.flPrim & PRIM_POLYSPLINE)%@NL@%
  22075.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE);%@NL@%
  22076.         if (global.flPrim & PRIM_POINTARC)%@NL@%
  22077.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POINTARC);%@NL@%
  22078. %@NL@%
  22079. %@NL@%
  22080.         %@AB@%/* Add ourselves to the switch list. */%@AE@%%@NL@%
  22081. %@NL@%
  22082.         WinQueryWindowProcess(global.hwndFrame, &pid, &tid);%@NL@%
  22083.         swctl.hwnd        = global.hwndFrame;%@NL@%
  22084.         swctl.idProcess = pid;%@NL@%
  22085.         hsw = WinAddSwitchEntry(&swctl);%@NL@%
  22086. %@NL@%
  22087.         return TRUE;%@NL@%
  22088.     }%@NL@%
  22089.     return FALSE;%@NL@%
  22090. }%@NL@%
  22091. %@NL@%
  22092. %@NL@%
  22093. %@NL@%
  22094. %@NL@%
  22095. %@AB@%/************************************************************************%@NL@%
  22096. %@AB@%*%@NL@%
  22097. %@AB@%*   WndProc%@NL@%
  22098. %@AB@%*%@NL@%
  22099. %@AB@%*   Process messages for the window class.%@NL@%
  22100. %@AB@%*%@NL@%
  22101. %@AB@%************************************************************************/%@AE@%%@NL@%
  22102. %@NL@%
  22103. ULONG EXPENTRY%@NL@%
  22104. WndProc( hwnd, usMsg, mp1, mp2 )%@NL@%
  22105. HWND   hwnd;%@NL@%
  22106. USHORT usMsg;%@NL@%
  22107. MPARAM  mp1;%@NL@%
  22108. MPARAM  mp2;%@NL@%
  22109. {%@NL@%
  22110.     HPS   hps;%@NL@%
  22111. %@NL@%
  22112. %@NL@%
  22113.     switch (usMsg)%@NL@%
  22114.     {%@NL@%
  22115.     case WM_CLOSE:%@NL@%
  22116.         Close(hwnd);%@NL@%
  22117.         break;%@NL@%
  22118. %@NL@%
  22119.     case WM_COMMAND:%@NL@%
  22120.         Command(hwnd, LOUSHORT(mp1));%@NL@%
  22121.         break;%@NL@%
  22122. %@NL@%
  22123.     case WM_PAINT:%@NL@%
  22124.         hps = WinBeginPaint(global.hwnd, NULL, NULL);%@NL@%
  22125.         if (global.ulHitPrecision == 0L)%@NL@%
  22126.         {%@NL@%
  22127.             HDC hdc;%@NL@%
  22128.             LONG cx;%@NL@%
  22129. %@NL@%
  22130.             if (hdc = WinQueryWindowDC(global.hwnd)) {%@NL@%
  22131.                 DevQueryCaps(hdc, CAPS_MARKER_WIDTH,  1L,  &cx);%@NL@%
  22132.                 global.ulHitPrecision = (cx >> 17) + 1L;%@NL@%
  22133.             } else {%@NL@%
  22134.                 global.ulHitPrecision = 6L;%@NL@%
  22135.             }%@NL@%
  22136.         }%@NL@%
  22137.         Paint(hps, TRUE);%@NL@%
  22138.         WinEndPaint(hps);%@NL@%
  22139.         break;%@NL@%
  22140. %@NL@%
  22141.     case WM_BUTTON1DOWN:%@NL@%
  22142.     case WM_BUTTON2DOWN:%@NL@%
  22143.         ButtonDown(hwnd, usMsg, mp1);%@NL@%
  22144.         break;%@NL@%
  22145. %@NL@%
  22146.     case WM_BUTTON1UP:%@NL@%
  22147.     case WM_BUTTON2UP:%@NL@%
  22148.         ButtonUp(hwnd, usMsg);%@NL@%
  22149.         break;%@NL@%
  22150. %@NL@%
  22151.     case WM_MOUSEMOVE:%@NL@%
  22152.         MouseMove(hwnd, mp1);%@NL@%
  22153.         return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));%@NL@%
  22154.         break;%@NL@%
  22155. %@NL@%
  22156.     default:%@NL@%
  22157.         return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));%@NL@%
  22158.         break;%@NL@%
  22159.     }%@NL@%
  22160. %@NL@%
  22161.     return FALSE;%@NL@%
  22162. }%@NL@%
  22163. %@NL@%
  22164. %@NL@%
  22165. %@NL@%
  22166. %@NL@%
  22167. %@AB@%/************************************************************************%@NL@%
  22168. %@AB@%*%@NL@%
  22169. %@AB@%*   MouseMove%@NL@%
  22170. %@AB@%*%@NL@%
  22171. %@AB@%************************************************************************/%@AE@%%@NL@%
  22172. %@NL@%
  22173. VOID%@NL@%
  22174. MouseMove(hwnd, mp1)%@NL@%
  22175. HWND hwnd;%@NL@%
  22176. MPARAM mp1;%@NL@%
  22177. {%@NL@%
  22178.     POINTL ptl;%@NL@%
  22179.     HPS hps;%@NL@%
  22180. %@NL@%
  22181.     if (hwnd == global.hwnd)%@NL@%
  22182.         if (global.fDragging)%@NL@%
  22183.         {%@NL@%
  22184.             ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  22185.             ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  22186. %@NL@%
  22187.             if (global.usPtGrabbed != -1)%@NL@%
  22188.             {%@NL@%
  22189.                 hps = WinGetPS(hwnd);%@NL@%
  22190.                 Paint(hps, FALSE);%@NL@%
  22191. %@NL@%
  22192.                 *(global.pptl+global.usPtGrabbed) = ptl;%@NL@%
  22193. %@NL@%
  22194.                 Paint(hps, FALSE);%@NL@%
  22195.                 WinReleasePS(hps);%@NL@%
  22196.             }%@NL@%
  22197.         }%@NL@%
  22198. }%@NL@%
  22199. %@NL@%
  22200. %@NL@%
  22201. %@NL@%
  22202. %@NL@%
  22203. %@AB@%/************************************************************************%@NL@%
  22204. %@AB@%*%@NL@%
  22205. %@AB@%*   ButtonUp%@NL@%
  22206. %@AB@%*%@NL@%
  22207. %@AB@%************************************************************************/%@AE@%%@NL@%
  22208. %@NL@%
  22209. VOID%@NL@%
  22210. ButtonUp(hwnd, usMsg)%@NL@%
  22211. HWND hwnd;%@NL@%
  22212. USHORT usMsg;%@NL@%
  22213. {%@NL@%
  22214.     int i;%@NL@%
  22215.     HPS hps;%@NL@%
  22216. %@NL@%
  22217. %@NL@%
  22218.     if (hwnd == global.hwnd)%@NL@%
  22219.         if (global.fDragging)%@NL@%
  22220.         {%@NL@%
  22221.             global.fDragging = FALSE;%@NL@%
  22222.             if (global.usPtGrabbed != -1)%@NL@%
  22223.             {%@NL@%
  22224.                 if (usMsg == WM_BUTTON2UP)%@NL@%
  22225.                 {%@NL@%
  22226.                     hps = WinGetPS(hwnd);%@NL@%
  22227.                     Paint(hps, FALSE);%@NL@%
  22228. %@NL@%
  22229.                     if ((i = global.usPtGrabbed) < (int) global.cptl-1)%@NL@%
  22230.                         while (i < (int) global.cptl-1)%@NL@%
  22231.                         {%@NL@%
  22232.                             global.pptl[i] = global.pptl[i+1];%@NL@%
  22233.                             ++i;%@NL@%
  22234.                         }%@NL@%
  22235. %@NL@%
  22236.                     --global.cptl;%@NL@%
  22237.                     global.usPtGrabbed = -1;%@NL@%
  22238. %@NL@%
  22239.                     Paint(hps, FALSE);%@NL@%
  22240.                     WinReleasePS(hps);%@NL@%
  22241.                 }%@NL@%
  22242.                 else        %@AB@%/* WM_BUTTON1UP */%@AE@%%@NL@%
  22243.                     global.usPtGrabbed = -1;%@NL@%
  22244.             }%@NL@%
  22245.         }%@NL@%
  22246. }%@NL@%
  22247. %@NL@%
  22248. %@NL@%
  22249. %@NL@%
  22250. %@NL@%
  22251. %@AB@%/************************************************************************%@NL@%
  22252. %@AB@%*%@NL@%
  22253. %@AB@%*   ButtonDown%@NL@%
  22254. %@AB@%*%@NL@%
  22255. %@AB@%************************************************************************/%@AE@%%@NL@%
  22256. %@NL@%
  22257. VOID%@NL@%
  22258. ButtonDown(hwnd, usMsg, mp1)%@NL@%
  22259. HWND hwnd;%@NL@%
  22260. USHORT usMsg;%@NL@%
  22261. MPARAM mp1;%@NL@%
  22262. {%@NL@%
  22263.     POINTL ptl;%@NL@%
  22264.     HPS hps;%@NL@%
  22265.     USHORT usNewPtGrabbed;%@NL@%
  22266. %@NL@%
  22267. %@NL@%
  22268.     if (hwnd == global.hwnd)%@NL@%
  22269.         if (!global.fDragging)%@NL@%
  22270.         {%@NL@%
  22271.             global.fDragging = TRUE;%@NL@%
  22272. %@NL@%
  22273.             ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  22274.             ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  22275. %@NL@%
  22276.             if ((usNewPtGrabbed = IsPtInList(&ptl)) != -1)%@NL@%
  22277.                 global.usPtGrabbed = usNewPtGrabbed;%@NL@%
  22278. %@NL@%
  22279.             if (usMsg == WM_BUTTON1DOWN)%@NL@%
  22280.             {%@NL@%
  22281.                 hps = WinGetPS(hwnd);%@NL@%
  22282.                 Paint(hps, FALSE);%@NL@%
  22283. %@NL@%
  22284.                 if (usNewPtGrabbed == -1)%@NL@%
  22285.                     global.usPtGrabbed = AddPtToList(&ptl);%@NL@%
  22286.                 else%@NL@%
  22287.                     global.usPtGrabbed = usNewPtGrabbed;%@NL@%
  22288. %@NL@%
  22289.                 Paint(hps, FALSE);%@NL@%
  22290.                 WinReleasePS(hps);%@NL@%
  22291. %@NL@%
  22292.                 if (global.usPtGrabbed == -1)%@NL@%
  22293.                     MyMessageBox(global.hwnd, "Cannot add any more points.");%@NL@%
  22294.             }%@NL@%
  22295.         }%@NL@%
  22296. }%@NL@%
  22297. %@NL@%
  22298. %@NL@%
  22299. %@NL@%
  22300. %@NL@%
  22301. %@AB@%/************************************************************************%@NL@%
  22302. %@AB@%*%@NL@%
  22303. %@AB@%*   IsPtInList%@NL@%
  22304. %@AB@%*%@NL@%
  22305. %@AB@%************************************************************************/%@AE@%%@NL@%
  22306. %@NL@%
  22307. USHORT%@NL@%
  22308. IsPtInList(pptl)%@NL@%
  22309. PPOINTL pptl;%@NL@%
  22310. {%@NL@%
  22311.     int i;%@NL@%
  22312. %@NL@%
  22313. %@NL@%
  22314.     %@AB@%/* try to find pptl in the points we already have */%@AE@%%@NL@%
  22315.     for (i = 0; i < (int) global.cptl; ++i)%@NL@%
  22316.         if (((abs(pptl->x - global.pptl[i].x))%@NL@%
  22317.                 <= (LONG) global.ulHitPrecision)%@NL@%
  22318.          && ((abs(pptl->y - global.pptl[i].y))%@NL@%
  22319.                 <= (LONG) global.ulHitPrecision))%@NL@%
  22320.                 return i;%@NL@%
  22321. %@NL@%
  22322.     %@AB@%/* couldn't find it */%@AE@%%@NL@%
  22323.     return -1;%@NL@%
  22324. }%@NL@%
  22325. %@NL@%
  22326. %@NL@%
  22327. %@NL@%
  22328. %@NL@%
  22329. %@AB@%/************************************************************************%@NL@%
  22330. %@AB@%*%@NL@%
  22331. %@AB@%*   AddPtToList%@NL@%
  22332. %@AB@%*%@NL@%
  22333. %@AB@%************************************************************************/%@AE@%%@NL@%
  22334. %@NL@%
  22335. USHORT%@NL@%
  22336. AddPtToList(pptl)%@NL@%
  22337. PPOINTL pptl;%@NL@%
  22338. {%@NL@%
  22339.     int i, j;%@NL@%
  22340. %@NL@%
  22341.     if (global.cptl < CPTLMAX)%@NL@%
  22342.     {%@NL@%
  22343.         %@AB@%/* check for new points lying on a line segment */%@AE@%%@NL@%
  22344.         for (i = 0; i < (int) (global.cptl - 1L); ++i)%@NL@%
  22345.             if (IsPtCloseToLine(&global.pptl[i], &global.pptl[i+1], pptl))%@NL@%
  22346.             {%@NL@%
  22347.                 for (j = (int) global.cptl; j > i+1; --j)%@NL@%
  22348.                     global.pptl[j] = global.pptl[j - 1];%@NL@%
  22349.                 global.pptl[i+1] = *pptl;%@NL@%
  22350.                 ++global.cptl;%@NL@%
  22351.                 return i+1;%@NL@%
  22352.             }%@NL@%
  22353. %@NL@%
  22354.         %@AB@%/* append the point */%@AE@%%@NL@%
  22355. %@NL@%
  22356.         i = (int) global.cptl;%@NL@%
  22357.         global.pptl[i] = *pptl;%@NL@%
  22358.         ++global.cptl;%@NL@%
  22359.         return i;%@NL@%
  22360.     }%@NL@%
  22361. %@NL@%
  22362.     return -1;%@NL@%
  22363. }%@NL@%
  22364. %@NL@%
  22365. %@NL@%
  22366. %@NL@%
  22367. %@NL@%
  22368. %@AB@%/************************************************************************%@NL@%
  22369. %@AB@%*%@NL@%
  22370. %@AB@%*   IsPtCloseToLine%@NL@%
  22371. %@AB@%*%@NL@%
  22372. %@AB@%************************************************************************/%@AE@%%@NL@%
  22373. %@NL@%
  22374. BOOL%@NL@%
  22375. IsPtCloseToLine(pptl1, pptl2, pptlTest)%@NL@%
  22376. PPOINTL pptl1;%@NL@%
  22377. PPOINTL pptl2;%@NL@%
  22378. PPOINTL pptlTest;%@NL@%
  22379. {%@NL@%
  22380.     POINTL ptlLL, ptlUR;%@NL@%
  22381.     LONG dx, dy, yIntercept, result;%@NL@%
  22382. %@NL@%
  22383. %@NL@%
  22384.     %@AB@%/* find the bounding box of the line segment */%@AE@%%@NL@%
  22385. %@NL@%
  22386.     ptlLL = *pptl1;        %@AB@%/* assume line goes lower left to upper right */%@AE@%%@NL@%
  22387.     ptlUR = *pptl2;%@NL@%
  22388.     if (pptl1->x > pptl2->x)%@NL@%
  22389.         SwapLong(&ptlLL.x, &ptlUR.x);%@NL@%
  22390.     if (pptl1->y > pptl2->y)%@NL@%
  22391.         SwapLong(&ptlLL.y, &ptlUR.y);%@NL@%
  22392. %@NL@%
  22393. %@NL@%
  22394.     %@AB@%/* adjust the bounding box if it's too narrow */%@AE@%%@NL@%
  22395. %@NL@%
  22396.     dx = pptl2->x - pptl1->x;%@NL@%
  22397.     if (abs(dx) <= (LONG) (global.ulHitPrecision >> 1))%@NL@%
  22398.     {%@NL@%
  22399.         ptlLL.x -= (LONG) (global.ulHitPrecision >> 1);%@NL@%
  22400.         ptlUR.x += (LONG) (global.ulHitPrecision >> 1);%@NL@%
  22401.     }%@NL@%
  22402.     dy = pptl2->y - pptl1->y;%@NL@%
  22403.     if (abs(dy) <= (LONG) (global.ulHitPrecision >> 1))%@NL@%
  22404.     {%@NL@%
  22405.         ptlLL.y -= (LONG) (global.ulHitPrecision >> 1);%@NL@%
  22406.         ptlUR.y += (LONG) (global.ulHitPrecision >> 1);%@NL@%
  22407.     }%@NL@%
  22408. %@NL@%
  22409. %@NL@%
  22410.     %@AB@%/* see if the test point is in the bounding box of the line segment */%@AE@%%@NL@%
  22411. %@NL@%
  22412.     if ((pptlTest->x >= ptlLL.x) &&%@NL@%
  22413.         (pptlTest->x <= ptlUR.x) &&%@NL@%
  22414.         (pptlTest->y >= ptlLL.y) &&%@NL@%
  22415.         (pptlTest->y <= ptlUR.y))%@NL@%
  22416.     {%@NL@%
  22417.         %@AB@%/* test for special cases */%@AE@%%@NL@%
  22418. %@NL@%
  22419.         if (dx == 0)%@NL@%
  22420.         {%@NL@%
  22421.             if (abs(pptlTest->x - pptl1->x) <= (LONG) global.ulHitPrecision)%@NL@%
  22422.                 return TRUE;%@NL@%
  22423.             else%@NL@%
  22424.                 return FALSE;%@NL@%
  22425.         }%@NL@%
  22426. %@NL@%
  22427.         if (dy == 0)%@NL@%
  22428.         {%@NL@%
  22429.             if (abs(pptlTest->y - pptl1->y) <= (LONG) global.ulHitPrecision)%@NL@%
  22430.                 return TRUE;%@NL@%
  22431.             else%@NL@%
  22432.                 return FALSE;%@NL@%
  22433.         }%@NL@%
  22434. %@NL@%
  22435. %@NL@%
  22436.         %@AB@%/* test for general case */%@AE@%%@NL@%
  22437. %@NL@%
  22438.         yIntercept = pptl1->y - (pptl1->x * dy) / dx;%@NL@%
  22439. %@NL@%
  22440.         result = pptlTest->y - (pptlTest->x * dy / dx) - yIntercept;%@NL@%
  22441.         if (abs(result) <= (LONG) global.ulHitPrecision)%@NL@%
  22442.             return TRUE;%@NL@%
  22443.     }%@NL@%
  22444. %@NL@%
  22445.     return FALSE;%@NL@%
  22446. }%@NL@%
  22447. %@NL@%
  22448. %@NL@%
  22449. %@NL@%
  22450. %@NL@%
  22451. %@AB@%/************************************************************************%@NL@%
  22452. %@AB@%*%@NL@%
  22453. %@AB@%*   SwapLong%@NL@%
  22454. %@AB@%*%@NL@%
  22455. %@AB@%************************************************************************/%@AE@%%@NL@%
  22456. %@NL@%
  22457. VOID%@NL@%
  22458. SwapLong(pl1, pl2)%@NL@%
  22459. PLONG pl1, pl2;%@NL@%
  22460. {%@NL@%
  22461.     LONG lTmp;%@NL@%
  22462. %@NL@%
  22463.     lTmp = *pl1;%@NL@%
  22464.     *pl1 = *pl2;%@NL@%
  22465.     *pl2 = lTmp;%@NL@%
  22466. }%@NL@%
  22467. %@NL@%
  22468. %@NL@%
  22469. %@NL@%
  22470. %@NL@%
  22471. %@AB@%/************************************************************************%@NL@%
  22472. %@AB@%*%@NL@%
  22473. %@AB@%*   Close%@NL@%
  22474. %@AB@%*%@NL@%
  22475. %@AB@%************************************************************************/%@AE@%%@NL@%
  22476. %@NL@%
  22477. VOID%@NL@%
  22478. Close(hwnd)%@NL@%
  22479. HWND hwnd;%@NL@%
  22480. {%@NL@%
  22481.     WinPostMsg(hwnd, WM_QUIT, 0L, 0L);%@NL@%
  22482. }%@NL@%
  22483. %@NL@%
  22484. %@NL@%
  22485. %@NL@%
  22486. %@NL@%
  22487. %@AB@%/************************************************************************%@NL@%
  22488. %@AB@%*%@NL@%
  22489. %@AB@%*   Command%@NL@%
  22490. %@AB@%*%@NL@%
  22491. %@AB@%*   Dispatches menu commands to the proper handlers.%@NL@%
  22492. %@AB@%*%@NL@%
  22493. %@AB@%************************************************************************/%@AE@%%@NL@%
  22494. %@NL@%
  22495. %@AI@%#define %@AE@%UPDATE_MENU_BOOL(var, val)                                \ %@NL@%
  22496.         {                                                        \%@NL@%
  22497.             TOGGLE_BOOL((var));                                 \%@NL@%
  22498.             TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var));        \%@NL@%
  22499.         }%@NL@%
  22500. %@NL@%
  22501. %@AI@%#define %@AE@%UPDATE_MENU_LIST(var, val)                                \ %@NL@%
  22502.         {                                                        \%@NL@%
  22503.             UNCHECK_MENU_ITEM(global.hwndFrame, (var));         \%@NL@%
  22504.             (var) = (val);                                        \%@NL@%
  22505.             CHECK_MENU_ITEM(global.hwndFrame, (var));                \%@NL@%
  22506.         }%@NL@%
  22507. %@NL@%
  22508. VOID%@NL@%
  22509. Command(hwnd, id)%@NL@%
  22510. HWND hwnd;%@NL@%
  22511. USHORT id;%@NL@%
  22512. {%@NL@%
  22513.     HPS hps;%@NL@%
  22514.     BOOL fRedraw = FALSE;%@NL@%
  22515.     int rc;%@NL@%
  22516. %@NL@%
  22517.     switch (id)%@NL@%
  22518.     {%@NL@%
  22519.     case IDM_ABOUT:%@NL@%
  22520.         rc = WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, (HMODULE) NULL, IDD_ABOUT, NULL);%@NL@%
  22521.         fRedraw = FALSE;%@NL@%
  22522.         break;%@NL@%
  22523. %@NL@%
  22524.     case IDM_NOPRIM:%@NL@%
  22525.         global.flPrim = 0L;%@NL@%
  22526.         TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYLINE, 0);%@NL@%
  22527.         TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET, 0);%@NL@%
  22528.         TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE, 0);%@NL@%
  22529.         fRedraw = TRUE;%@NL@%
  22530.         break;%@NL@%
  22531. %@NL@%
  22532.     case IDM_POLYLINE:%@NL@%
  22533.         global.flPrim ^= PRIM_POLYLINE;%@NL@%
  22534.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYLINE));%@NL@%
  22535.         fRedraw = TRUE;%@NL@%
  22536.         break;%@NL@%
  22537. %@NL@%
  22538.     case IDM_POLYFILLET:%@NL@%
  22539.         global.flPrim ^= PRIM_POLYFILLET;%@NL@%
  22540.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYFILLET));%@NL@%
  22541.         fRedraw = TRUE;%@NL@%
  22542.         break;%@NL@%
  22543. %@NL@%
  22544.     case IDM_POLYSPLINE:%@NL@%
  22545.         global.flPrim ^= PRIM_POLYSPLINE;%@NL@%
  22546.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYSPLINE));%@NL@%
  22547.         fRedraw = TRUE;%@NL@%
  22548.         break;%@NL@%
  22549. %@NL@%
  22550.     case IDM_POINTARC:%@NL@%
  22551.         global.flPrim ^= PRIM_POINTARC;%@NL@%
  22552.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POINTARC));%@NL@%
  22553.         fRedraw = TRUE;%@NL@%
  22554.         break;%@NL@%
  22555. %@NL@%
  22556.     case IDM_CTLPOINTS:%@NL@%
  22557.         UPDATE_MENU_BOOL(global.fDisplayControlPoints, IDM_CTLPOINTS);%@NL@%
  22558.         fRedraw = TRUE;%@NL@%
  22559.         break;%@NL@%
  22560. %@NL@%
  22561.     case IDM_CLEARALL:%@NL@%
  22562.         global.cptl = 0L;%@NL@%
  22563.         fRedraw = TRUE;%@NL@%
  22564.         break;%@NL@%
  22565.     }%@NL@%
  22566. %@NL@%
  22567.     if (fRedraw)%@NL@%
  22568.     {%@NL@%
  22569.         hps = WinGetPS(hwnd);%@NL@%
  22570.         Paint(hps, TRUE);%@NL@%
  22571.         WinReleasePS(hps);%@NL@%
  22572.     }%@NL@%
  22573. }%@NL@%
  22574. %@NL@%
  22575. %@NL@%
  22576. %@NL@%
  22577. %@NL@%
  22578. %@AB@%/************************************************************************%@NL@%
  22579. %@AB@%*%@NL@%
  22580. %@AB@%*   Paint%@NL@%
  22581. %@AB@%*%@NL@%
  22582. %@AB@%************************************************************************/%@AE@%%@NL@%
  22583. %@NL@%
  22584. VOID%@NL@%
  22585. Paint(hps, fClearScreen)%@NL@%
  22586. HPS  hps;%@NL@%
  22587. BOOL fClearScreen;%@NL@%
  22588. {%@NL@%
  22589.     LINEBUNDLE lb;%@NL@%
  22590.     RECTL rcl;%@NL@%
  22591. %@NL@%
  22592. %@NL@%
  22593. %@NL@%
  22594.     if (fClearScreen)%@NL@%
  22595.     {%@NL@%
  22596.         %@AB@%/* clear the screen */%@AE@%%@NL@%
  22597.         WinQueryWindowRect(global.hwnd, &rcl);%@NL@%
  22598.         GpiBitBlt(hps, NULL, 2L, (PPOINTL) &rcl, ROP_ONE, 0L);%@NL@%
  22599.     }%@NL@%
  22600. %@NL@%
  22601. %@NL@%
  22602.     if (global.cptl > 0L)%@NL@%
  22603.     {%@NL@%
  22604.         if (global.fDisplayControlPoints)%@NL@%
  22605.         {%@NL@%
  22606.             if (fClearScreen)%@NL@%
  22607.                 %@AB@%/* draw all the control points */%@AE@%%@NL@%
  22608.                 DrawControlPoints(hps, global.cptl, global.pptl);%@NL@%
  22609.             else if (global.usPtGrabbed != -1)%@NL@%
  22610.                 %@AB@%/* draw just the control point that moved */%@AE@%%@NL@%
  22611.                 DrawControlPoints(hps, 1L, global.pptl+global.usPtGrabbed);%@NL@%
  22612.         }%@NL@%
  22613. %@NL@%
  22614.         %@AB@%/* set mix mode to xor */%@AE@%%@NL@%
  22615.         lb.usMixMode = FM_XOR;%@NL@%
  22616.         GpiSetAttrs(hps, PRIM_LINE, LBB_MIX_MODE, 0L, &lb);%@NL@%
  22617. %@NL@%
  22618.         %@AB@%/* draw the current primitives */%@AE@%%@NL@%
  22619. %@NL@%
  22620.         if (global.flPrim & PRIM_POLYLINE)%@NL@%
  22621.         {%@NL@%
  22622.             lb.lColor = CLR_BROWN;%@NL@%
  22623.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  22624.             DrawPrimitive(hps, IDM_POLYLINE);%@NL@%
  22625.         }%@NL@%
  22626. %@NL@%
  22627.         if (global.flPrim & PRIM_POLYFILLET)%@NL@%
  22628.         {%@NL@%
  22629.             lb.lColor = CLR_DARKCYAN;%@NL@%
  22630.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  22631.             DrawPrimitive(hps, IDM_POLYFILLET);%@NL@%
  22632.         }%@NL@%
  22633. %@NL@%
  22634.         if (global.flPrim & PRIM_POLYSPLINE)%@NL@%
  22635.         {%@NL@%
  22636.             lb.lColor = CLR_DARKPINK;%@NL@%
  22637.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  22638.             DrawPrimitive(hps, IDM_POLYSPLINE);%@NL@%
  22639.         }%@NL@%
  22640. %@NL@%
  22641.         if (global.flPrim & PRIM_POINTARC)%@NL@%
  22642.         {%@NL@%
  22643.             lb.lColor = CLR_BACKGROUND;%@NL@%
  22644.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  22645.             DrawPrimitive(hps, IDM_POINTARC);%@NL@%
  22646.         }%@NL@%
  22647.     }%@NL@%
  22648. }%@NL@%
  22649. %@NL@%
  22650. %@NL@%
  22651. %@NL@%
  22652. %@NL@%
  22653. %@AB@%/************************************************************************%@NL@%
  22654. %@AB@%*%@NL@%
  22655. %@AB@%*   DrawPrimitive%@NL@%
  22656. %@AB@%*%@NL@%
  22657. %@AB@%************************************************************************/%@AE@%%@NL@%
  22658. %@NL@%
  22659. VOID%@NL@%
  22660. DrawPrimitive(hps, usPrim)%@NL@%
  22661. HPS hps;%@NL@%
  22662. USHORT usPrim;%@NL@%
  22663. {%@NL@%
  22664.     switch ( usPrim )%@NL@%
  22665.     {%@NL@%
  22666.     case IDM_POLYLINE:%@NL@%
  22667.         DrawPolyLine(hps);%@NL@%
  22668.         break;%@NL@%
  22669. %@NL@%
  22670.     case IDM_POLYFILLET:%@NL@%
  22671.         DrawPolyFillet(hps);%@NL@%
  22672.         break;%@NL@%
  22673. %@NL@%
  22674.     case IDM_POLYSPLINE:%@NL@%
  22675.         DrawPolySpline(hps);%@NL@%
  22676.         break;%@NL@%
  22677. %@NL@%
  22678.     case IDM_POINTARC:%@NL@%
  22679.         DrawPointArc(hps);%@NL@%
  22680.         break;%@NL@%
  22681.     }%@NL@%
  22682. }%@NL@%
  22683. %@NL@%
  22684. %@NL@%
  22685. %@NL@%
  22686. %@NL@%
  22687. %@AB@%/************************************************************************%@NL@%
  22688. %@AB@%*%@NL@%
  22689. %@AB@%*   DrawPolyLine%@NL@%
  22690. %@AB@%*%@NL@%
  22691. %@AB@%************************************************************************/%@AE@%%@NL@%
  22692. %@NL@%
  22693. VOID%@NL@%
  22694. DrawPolyLine(hps)%@NL@%
  22695. HPS hps;%@NL@%
  22696. {%@NL@%
  22697.     GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  22698.     GpiPolyLine( hps, global.cptl-1L, global.pptl+1 );%@NL@%
  22699. }%@NL@%
  22700. %@NL@%
  22701. %@NL@%
  22702. %@NL@%
  22703. %@NL@%
  22704. %@AB@%/************************************************************************%@NL@%
  22705. %@AB@%*%@NL@%
  22706. %@AB@%*   DrawPolyFillet%@NL@%
  22707. %@AB@%*%@NL@%
  22708. %@AB@%************************************************************************/%@AE@%%@NL@%
  22709. %@NL@%
  22710. VOID%@NL@%
  22711. DrawPolyFillet(hps)%@NL@%
  22712. HPS hps;%@NL@%
  22713. {%@NL@%
  22714.     if (global.cptl > 2)%@NL@%
  22715.     {%@NL@%
  22716.         GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  22717.         GpiPolyFillet( hps, global.cptl-1L, global.pptl+1 );%@NL@%
  22718.     }%@NL@%
  22719. }%@NL@%
  22720. %@NL@%
  22721. %@NL@%
  22722. %@NL@%
  22723. %@NL@%
  22724. %@AB@%/************************************************************************%@NL@%
  22725. %@AB@%*%@NL@%
  22726. %@AB@%*   DrawPolySpline%@NL@%
  22727. %@AB@%*%@NL@%
  22728. %@AB@%************************************************************************/%@AE@%%@NL@%
  22729. %@NL@%
  22730. VOID%@NL@%
  22731. DrawPolySpline(hps)%@NL@%
  22732. HPS hps;%@NL@%
  22733. {%@NL@%
  22734.     USHORT cptSlack;        %@AB@%/* # points in pptl not usable by PolySpline */%@AE@%%@NL@%
  22735. %@NL@%
  22736.     %@AB@%/* GpiPolySpline expects the number of points to be a%@NL@%
  22737. %@AB@%       multiple of 3.  If we have a non-multiple of three,%@NL@%
  22738. %@AB@%       (excluding the first point, which we've used to set%@NL@%
  22739. %@AB@%       the current position), only pass the largest multiple%@NL@%
  22740. %@AB@%       of three, saving the rest for the next go-round. */%@AE@%%@NL@%
  22741. %@NL@%
  22742.     cptSlack = (int)((global.cptl-1L) % 3) + 1;%@NL@%
  22743.     GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  22744.     GpiPolySpline( hps, global.cptl-cptSlack,%@NL@%
  22745.                    global.pptl+1 );%@NL@%
  22746. }%@NL@%
  22747. %@NL@%
  22748. %@NL@%
  22749. %@NL@%
  22750. %@NL@%
  22751. %@AB@%/************************************************************************%@NL@%
  22752. %@AB@%*%@NL@%
  22753. %@AB@%*   DrawPointArc%@NL@%
  22754. %@AB@%*%@NL@%
  22755. %@AB@%************************************************************************/%@AE@%%@NL@%
  22756. %@NL@%
  22757. VOID%@NL@%
  22758. DrawPointArc(hps)%@NL@%
  22759. HPS hps;%@NL@%
  22760. {%@NL@%
  22761.     if (global.cptl >= 3L)%@NL@%
  22762.     {%@NL@%
  22763.         GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  22764.         GpiPointArc( hps, global.pptl+1 );%@NL@%
  22765.     }%@NL@%
  22766. }%@NL@%
  22767. %@NL@%
  22768. %@NL@%
  22769. %@NL@%
  22770. %@NL@%
  22771. %@AB@%/************************************************************************%@NL@%
  22772. %@AB@%*%@NL@%
  22773. %@AB@%*   DrawControlPoints%@NL@%
  22774. %@AB@%*%@NL@%
  22775. %@AB@%************************************************************************/%@AE@%%@NL@%
  22776. %@NL@%
  22777. VOID%@NL@%
  22778. DrawControlPoints(hps, cptl, pptl)%@NL@%
  22779. HPS hps;%@NL@%
  22780. LONG cptl;%@NL@%
  22781. PPOINTL pptl;%@NL@%
  22782. {%@NL@%
  22783.     MARKERBUNDLE mb;%@NL@%
  22784. %@NL@%
  22785.     mb.lColor = CLR_TRUE;%@NL@%
  22786.     mb.usMixMode = FM_XOR;%@NL@%
  22787.     GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR | MBB_MIX_MODE, 0L, &mb);%@NL@%
  22788. %@NL@%
  22789.     GpiPolyMarker(hps, cptl, pptl);%@NL@%
  22790. }%@NL@%
  22791. %@NL@%
  22792. %@NL@%
  22793. %@NL@%
  22794. %@NL@%
  22795. %@AB@%/************************************************************************%@NL@%
  22796. %@AB@%*%@NL@%
  22797. %@AB@%*   MyMessageBox%@NL@%
  22798. %@AB@%*%@NL@%
  22799. %@AB@%*   Displays a message box with the given string.  To simplify matters,%@NL@%
  22800. %@AB@%*   the box will always have the same title ("PolyLine Editor"), will always%@NL@%
  22801. %@AB@%*   have a single button ("Ok"), will always have an exclamation point%@NL@%
  22802. %@AB@%*   icon, and will always be application modal.%@NL@%
  22803. %@AB@%*%@NL@%
  22804. %@AB@%************************************************************************/%@AE@%%@NL@%
  22805. %@NL@%
  22806. VOID%@NL@%
  22807. MyMessageBox(hWnd, sz)%@NL@%
  22808. HWND hWnd;%@NL@%
  22809. PSZ sz;%@NL@%
  22810. {%@NL@%
  22811.     static char *szTitle = "PolyLine Editor";%@NL@%
  22812. %@NL@%
  22813.     WinMessageBox(HWND_DESKTOP, hWnd, sz, szTitle, (HMODULE) NULL,%@NL@%
  22814.                   MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);%@NL@%
  22815. }%@NL@%
  22816. %@NL@%
  22817. MRESULT EXPENTRY AboutDlgProc(hDlg, msg, mp1, mp2)%@NL@%
  22818. %@AB@%/*%@NL@%
  22819. %@AB@%    About... dialog procedure%@NL@%
  22820. %@AB@%*/%@AE@%%@NL@%
  22821. HWND        hDlg;%@NL@%
  22822. USHORT        msg;%@NL@%
  22823. MPARAM        mp1;%@NL@%
  22824. MPARAM        mp2;%@NL@%
  22825. {%@NL@%
  22826.     switch(msg) {%@NL@%
  22827.         case WM_COMMAND:%@NL@%
  22828.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  22829.                 case DID_OK: WinDismissDlg(hDlg, TRUE); break;%@NL@%
  22830.                 default: break;%@NL@%
  22831.             }%@NL@%
  22832.         default: return WinDefDlgProc(hDlg, msg, mp1, mp2);%@NL@%
  22833.     }%@NL@%
  22834.     return FALSE;%@NL@%
  22835. }%@NL@%
  22836. %@NL@%
  22837. %@NL@%
  22838. %@2@%%@AH@%EDPLINE.C%@AE@%%@EH@%%@NL@%
  22839. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\CLIPVIEW\EDPLINE\EDPLINE.C%@AE@%%@NL@%
  22840. %@NL@%
  22841. %@AB@%/*%@NL@%
  22842. %@AB@%    edpline.c -- polyline editor, for practice in mouse handling%@NL@%
  22843. %@AB@%    Created by Microsoft Corporation, 1989%@NL@%
  22844. %@AB@%*/%@AE@%%@NL@%
  22845. %@AI@%#define %@AE@%INCL_DOSMEMMGR %@NL@%
  22846. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  22847. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  22848. %@AI@%#define %@AE@%INCL_WINSWITCHLIST %@NL@%
  22849. %@AI@%#define %@AE@%INCL_WINDIALOGS %@NL@%
  22850. %@AI@%#define %@AE@%INCL_GPIBITMAPS %@NL@%
  22851. %@AI@%#define %@AE@%INCL_GPIPRIMITIVES %@NL@%
  22852. %@AI@%#define %@AE@%       INCL_GPITRANSFORMS %@NL@%
  22853. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  22854. %@AI@%#define %@AE@%       INCL_WININPUT %@NL@%
  22855. %@AI@%#define %@AE@%       INCL_WINFRAMEMGR %@NL@%
  22856. %@AI@%#define %@AE@%       INCL_WINCLIPBOARD %@NL@%
  22857. %@AI@%#include %@AE@%<os2.h> %@NL@%
  22858. %@NL@%
  22859. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  22860. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  22861. %@NL@%
  22862. %@AI@%#include %@AE@%"edpline.h" %@NL@%
  22863. %@NL@%
  22864. %@NL@%
  22865. %@NL@%
  22866. %@AI@%#define %@AE@%       abs(x)                        (((x) > 0) ? (x) : -(x)) %@NL@%
  22867. %@AI@%#define %@AE@%PRIM_POLYLINE                0x0001 %@NL@%
  22868. %@AI@%#define %@AE@%PRIM_POLYFILLET         0x0002 %@NL@%
  22869. %@AI@%#define %@AE@%PRIM_POLYSPLINE         0x0004 %@NL@%
  22870. %@AI@%#define %@AE@%PRIM_POINTARC                0x0008 %@NL@%
  22871. %@NL@%
  22872. %@NL@%
  22873. %@AB@%/************************************************************************%@NL@%
  22874. %@AB@%*%@NL@%
  22875. %@AB@%*   Function declarations%@NL@%
  22876. %@AB@%*%@NL@%
  22877. %@AB@%************************************************************************/%@AE@%%@NL@%
  22878. %@NL@%
  22879. %@AB@%/* Private functions */%@AE@%%@NL@%
  22880. %@NL@%
  22881. VOID   cdecl main(VOID);%@NL@%
  22882. BOOL   InitGlobals(VOID);%@NL@%
  22883. BOOL   InitApp(VOID);%@NL@%
  22884. VOID   Close(HWND);%@NL@%
  22885. VOID   Command(HWND, USHORT);%@NL@%
  22886. VOID   Paint(HPS, BOOL);%@NL@%
  22887. VOID   MouseMove(HWND, MPARAM);%@NL@%
  22888. VOID   ButtonUp(HWND, USHORT);%@NL@%
  22889. VOID   ButtonDown(HWND, USHORT, MPARAM);%@NL@%
  22890. USHORT IsPtInList(PPOINTL);%@NL@%
  22891. USHORT AddPtToList(PPOINTL);%@NL@%
  22892. BOOL   IsPtCloseToLine(PPOINTL, PPOINTL, PPOINTL);%@NL@%
  22893. VOID   DrawPrimitive(HPS, USHORT);%@NL@%
  22894. VOID   DrawPolyLine(HPS);%@NL@%
  22895. VOID   DrawPolyFillet(HPS);%@NL@%
  22896. VOID   DrawPolySpline(HPS);%@NL@%
  22897. VOID   DrawPointArc(HPS);%@NL@%
  22898. VOID   DrawControlPoints(HPS, LONG, PPOINTL);%@NL@%
  22899. VOID   MyMessageBox(HWND, PSZ);%@NL@%
  22900. VOID   SwapLong(PLONG, PLONG);%@NL@%
  22901. %@NL@%
  22902. %@AB@%/* Exported functions */%@AE@%%@NL@%
  22903. %@NL@%
  22904. ULONG        CALLBACK WndProc(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  22905. MRESULT CALLBACK AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  22906. %@NL@%
  22907. %@NL@%
  22908. %@NL@%
  22909. %@AB@%/************************************************************************%@NL@%
  22910. %@AB@%*%@NL@%
  22911. %@AB@%*   Global Variables%@NL@%
  22912. %@AB@%*%@NL@%
  22913. %@AB@%************************************************************************/%@AE@%%@NL@%
  22914. %@NL@%
  22915. typedef struct%@NL@%
  22916. {%@NL@%
  22917.     HAB  hab;%@NL@%
  22918.     HMQ  hMsgQ;%@NL@%
  22919.     HWND hwndFrame;%@NL@%
  22920.     HWND hwnd;%@NL@%
  22921. %@NL@%
  22922.     ULONG   flPrim;%@NL@%
  22923.     BOOL    fDisplayControlPoints;%@NL@%
  22924.     LONG    cptl;%@NL@%
  22925.     PPOINTL pptl;%@NL@%
  22926. %@NL@%
  22927.     USHORT  usPtGrabbed;%@NL@%
  22928.     BOOL    fDragging;%@NL@%
  22929. %@NL@%
  22930.     ULONG   ulHitPrecision;%@NL@%
  22931. %@NL@%
  22932.     HPS     hpsMetafile;%@NL@%
  22933.     HDC     hdcMetafile;%@NL@%
  22934.     ULONG   hItem;%@NL@%
  22935.     SIZEL   sizlPage;%@NL@%
  22936.     DEVOPENSTRUC dop;%@NL@%
  22937. %@NL@%
  22938. } GLOBALDATA;%@NL@%
  22939. GLOBALDATA global;%@NL@%
  22940. %@NL@%
  22941. %@NL@%
  22942. %@AB@%/************************************************************************%@NL@%
  22943. %@AB@%*%@NL@%
  22944. %@AB@%*   main%@NL@%
  22945. %@AB@%*%@NL@%
  22946. %@AB@%*   WinInitialize resizes our ring 2 stack, among other things, so%@NL@%
  22947. %@AB@%*   we won't GP fault trying to do graphics.  WinCreateMsgQueue defines%@NL@%
  22948. %@AB@%*   us as a REAL PM app. (as well as the WINDOWAPI statement in the .DEF%@NL@%
  22949. %@AB@%*   file...)   Call a sub to register our window class and create a window.%@NL@%
  22950. %@AB@%*   Loop over messages.  Exit cleanly.%@NL@%
  22951. %@AB@%*%@NL@%
  22952. %@AB@%************************************************************************/%@AE@%%@NL@%
  22953. %@NL@%
  22954. VOID cdecl%@NL@%
  22955. main()%@NL@%
  22956. {%@NL@%
  22957.     QMSG qMsg;%@NL@%
  22958.     int iRet = 0;%@NL@%
  22959. %@NL@%
  22960. %@NL@%
  22961.     global.hab         = WinInitialize(0);%@NL@%
  22962.     global.hMsgQ = WinCreateMsgQueue(global.hab, 0);%@NL@%
  22963. %@NL@%
  22964.     if (InitApp())%@NL@%
  22965.         while (WinGetMsg( global.hab, (PQMSG)&qMsg, (HWND)NULL, 0, 0 ))%@NL@%
  22966.             WinDispatchMsg( global.hab, (PQMSG)&qMsg );%@NL@%
  22967.     else%@NL@%
  22968.         iRet = -1;%@NL@%
  22969. %@NL@%
  22970.     WinDestroyWindow( global.hwndFrame );%@NL@%
  22971.     WinDestroyMsgQueue( global.hMsgQ );%@NL@%
  22972.     WinTerminate( global.hab );%@NL@%
  22973.     DosExit(EXIT_PROCESS, iRet);%@NL@%
  22974. }%@NL@%
  22975. %@NL@%
  22976. %@NL@%
  22977. %@NL@%
  22978. %@NL@%
  22979. %@AB@%/****************************************************************************%@NL@%
  22980. %@AB@%*%@NL@%
  22981. %@AB@%*   InitGlobals%@NL@%
  22982. %@AB@%*%@NL@%
  22983. %@AB@%*   Initialize global variables.%@NL@%
  22984. %@AB@%*%@NL@%
  22985. %@AB@%****************************************************************************/%@AE@%%@NL@%
  22986. %@NL@%
  22987. BOOL%@NL@%
  22988. InitGlobals()%@NL@%
  22989. {%@NL@%
  22990.     global.flPrim = PRIM_POLYLINE;%@NL@%
  22991.     global.fDisplayControlPoints = TRUE;%@NL@%
  22992. %@NL@%
  22993.     global.cptl = 0L;%@NL@%
  22994.     global.pptl = NULL;%@NL@%
  22995.     if (DosAllocSeg(CPTLMAX * sizeof(POINTL),%@NL@%
  22996.                    ((PUSHORT)&global.pptl)+1, 0))%@NL@%
  22997.         return FALSE;%@NL@%
  22998. %@NL@%
  22999.     global.usPtGrabbed = -1;%@NL@%
  23000.     global.fDragging = FALSE;%@NL@%
  23001.     global.ulHitPrecision = 0L;%@NL@%
  23002. %@NL@%
  23003.     return TRUE;%@NL@%
  23004. }%@NL@%
  23005. %@NL@%
  23006. %@NL@%
  23007. %@NL@%
  23008. %@NL@%
  23009. %@AB@%/****************************************************************************%@NL@%
  23010. %@AB@%*%@NL@%
  23011. %@AB@%*   InitApp%@NL@%
  23012. %@AB@%*%@NL@%
  23013. %@AB@%*   Register application window class and creates standard window.%@NL@%
  23014. %@AB@%*%@NL@%
  23015. %@AB@%****************************************************************************/%@AE@%%@NL@%
  23016. %@NL@%
  23017. %@AI@%#define %@AE@%INIT_MENU_ITEM(val, var)     \ %@NL@%
  23018.         TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var))%@NL@%
  23019. %@NL@%
  23020. BOOL%@NL@%
  23021. InitApp()%@NL@%
  23022. {%@NL@%
  23023.     char szTitle[24];%@NL@%
  23024.     ULONG ctldata;%@NL@%
  23025.     PID pid;%@NL@%
  23026.     TID tid;%@NL@%
  23027.     HSWITCH hsw;%@NL@%
  23028.     static SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE,%@NL@%
  23029.                              SWL_JUMPABLE, "Edit Polyline", 0 };%@NL@%
  23030. %@NL@%
  23031.     if (!InitGlobals())%@NL@%
  23032.         return FALSE;%@NL@%
  23033. %@NL@%
  23034. %@NL@%
  23035.     %@AB@%/*  Register Application Window Class  */%@AE@%%@NL@%
  23036. %@NL@%
  23037.     WinLoadString( global.hab, (HMODULE) NULL, IDS_TITLE, sizeof(szTitle), (PCH)szTitle );%@NL@%
  23038.     if ( !WinRegisterClass( global.hab, (PCH)szTitle, (PFNWP)WndProc,%@NL@%
  23039.             CS_SIZEREDRAW, 0 ))%@NL@%
  23040.         return FALSE;%@NL@%
  23041. %@NL@%
  23042. %@NL@%
  23043. %@NL@%
  23044.     %@AB@%/* Create a window instance of class "PolyLine Editor" */%@AE@%%@NL@%
  23045. %@NL@%
  23046.     ctldata = FCF_STANDARD &%@NL@%
  23047.      ~(ULONG)(FCF_ICON | FCF_TASKLIST);%@NL@%
  23048. %@NL@%
  23049.     if (global.hwndFrame = WinCreateStdWindow(%@NL@%
  23050.         HWND_DESKTOP,                   %@AB@%/* specify desktop as parent window            */%@AE@%%@NL@%
  23051.         WS_VISIBLE,                   %@AB@%/* window styles                            */%@AE@%%@NL@%
  23052.         &ctldata,                   %@AB@%/* frame creation flags                    */%@AE@%%@NL@%
  23053.         (PCH)szTitle,                   %@AB@%/* window class name                     */%@AE@%%@NL@%
  23054.         (PCH)szTitle,                   %@AB@%/* name appearing in window caption            */%@AE@%%@NL@%
  23055.         0L,                           %@AB@%/*                                            */%@AE@%%@NL@%
  23056.         (HMODULE)NULL,                   %@AB@%/* use current executable module id            */%@AE@%%@NL@%
  23057.         IDR_EDPLINE,                   %@AB@%/* menu id                                    */%@AE@%%@NL@%
  23058.         (HWND FAR *)&global.hwnd   %@AB@%/* window handle                            */%@AE@%%@NL@%
  23059.         ))%@NL@%
  23060.     {%@NL@%
  23061.         INIT_MENU_ITEM(IDM_CTLPOINTS, global.fDisplayControlPoints);%@NL@%
  23062. %@NL@%
  23063.         if (global.flPrim & PRIM_POLYLINE)%@NL@%
  23064.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYLINE);%@NL@%
  23065.         if (global.flPrim & PRIM_POLYFILLET)%@NL@%
  23066.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET);%@NL@%
  23067.         if (global.flPrim & PRIM_POLYSPLINE)%@NL@%
  23068.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE);%@NL@%
  23069.         if (global.flPrim & PRIM_POINTARC)%@NL@%
  23070.             CHECK_MENU_ITEM(global.hwndFrame, IDM_POINTARC);%@NL@%
  23071. %@NL@%
  23072. %@NL@%
  23073.         %@AB@%/* Add ourselves to the switch list. */%@AE@%%@NL@%
  23074. %@NL@%
  23075.         WinQueryWindowProcess(global.hwndFrame, &pid, &tid);%@NL@%
  23076.         swctl.hwnd        = global.hwndFrame;%@NL@%
  23077.         swctl.idProcess = pid;%@NL@%
  23078.         hsw = WinAddSwitchEntry(&swctl);%@NL@%
  23079. %@NL@%
  23080.         return TRUE;%@NL@%
  23081.     }%@NL@%
  23082.     return FALSE;%@NL@%
  23083. }%@NL@%
  23084. %@NL@%
  23085. %@NL@%
  23086. %@NL@%
  23087. %@NL@%
  23088. %@AB@%/************************************************************************%@NL@%
  23089. %@AB@%*%@NL@%
  23090. %@AB@%*   WndProc%@NL@%
  23091. %@AB@%*%@NL@%
  23092. %@AB@%*   Process messages for the window class.%@NL@%
  23093. %@AB@%*%@NL@%
  23094. %@AB@%************************************************************************/%@AE@%%@NL@%
  23095. %@NL@%
  23096. ULONG CALLBACK%@NL@%
  23097. WndProc( hwnd, usMsg, mp1, mp2 )%@NL@%
  23098. HWND   hwnd;%@NL@%
  23099. USHORT usMsg;%@NL@%
  23100. MPARAM  mp1;%@NL@%
  23101. MPARAM  mp2;%@NL@%
  23102. {%@NL@%
  23103.     HPS   hps;%@NL@%
  23104. %@NL@%
  23105.     switch (usMsg)%@NL@%
  23106.     {%@NL@%
  23107.     case WM_CLOSE:%@NL@%
  23108.         Close(hwnd);%@NL@%
  23109.         break;%@NL@%
  23110. %@NL@%
  23111.     case WM_COMMAND:%@NL@%
  23112.         Command(hwnd, LOUSHORT(mp1));%@NL@%
  23113.         break;%@NL@%
  23114. %@NL@%
  23115.     case WM_PAINT:%@NL@%
  23116.         hps = WinBeginPaint(global.hwnd, NULL, NULL);%@NL@%
  23117. %@NL@%
  23118.         if (global.ulHitPrecision == 0L)%@NL@%
  23119.         {%@NL@%
  23120.             HDC hdc;%@NL@%
  23121.             LONG cx;%@NL@%
  23122. %@NL@%
  23123.             if (hdc = WinQueryWindowDC(global.hwnd)) {%@NL@%
  23124.                 DevQueryCaps(hdc, CAPS_MARKER_WIDTH,  1L,  &cx);%@NL@%
  23125.                 global.ulHitPrecision = (cx >> 17) + 1L;%@NL@%
  23126.             } else {%@NL@%
  23127.                 global.ulHitPrecision = 6L;%@NL@%
  23128.             }%@NL@%
  23129.         }%@NL@%
  23130.         Paint(hps, TRUE);%@NL@%
  23131.         WinEndPaint(hps);%@NL@%
  23132.         break;%@NL@%
  23133. %@NL@%
  23134.     case WM_BUTTON1DOWN:%@NL@%
  23135.     case WM_BUTTON2DOWN:%@NL@%
  23136.         ButtonDown(hwnd, usMsg, mp1);%@NL@%
  23137.         break;%@NL@%
  23138. %@NL@%
  23139.     case WM_BUTTON1UP:%@NL@%
  23140.     case WM_BUTTON2UP:%@NL@%
  23141.         ButtonUp(hwnd, usMsg);%@NL@%
  23142.         break;%@NL@%
  23143. %@NL@%
  23144.     case WM_MOUSEMOVE:%@NL@%
  23145.         MouseMove(hwnd, mp1);%@NL@%
  23146.         return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));%@NL@%
  23147.         break;%@NL@%
  23148. %@NL@%
  23149.     default:%@NL@%
  23150.         return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));%@NL@%
  23151.         break;%@NL@%
  23152.     }%@NL@%
  23153. %@NL@%
  23154.     return FALSE;%@NL@%
  23155. }%@NL@%
  23156. %@NL@%
  23157. %@NL@%
  23158. %@NL@%
  23159. %@NL@%
  23160. %@AB@%/************************************************************************%@NL@%
  23161. %@AB@%*%@NL@%
  23162. %@AB@%*   MouseMove%@NL@%
  23163. %@AB@%*%@NL@%
  23164. %@AB@%************************************************************************/%@AE@%%@NL@%
  23165. %@NL@%
  23166. VOID%@NL@%
  23167. MouseMove(hwnd, mp1)%@NL@%
  23168. HWND hwnd;%@NL@%
  23169. MPARAM mp1;%@NL@%
  23170. {%@NL@%
  23171.     POINTL ptl;%@NL@%
  23172.     HPS hps;%@NL@%
  23173. %@NL@%
  23174.     if (hwnd == global.hwnd)%@NL@%
  23175.         if (global.fDragging)%@NL@%
  23176.         {%@NL@%
  23177.             ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  23178.             ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  23179. %@NL@%
  23180.             if (global.usPtGrabbed != -1)%@NL@%
  23181.             {%@NL@%
  23182.                 hps = WinGetPS(hwnd);%@NL@%
  23183.                 Paint(hps, FALSE);%@NL@%
  23184. %@NL@%
  23185.                 *(global.pptl+global.usPtGrabbed) = ptl;%@NL@%
  23186. %@NL@%
  23187.                 Paint(hps, FALSE);%@NL@%
  23188.                 WinReleasePS(hps);%@NL@%
  23189.             }%@NL@%
  23190.         }%@NL@%
  23191. }%@NL@%
  23192. %@NL@%
  23193. %@NL@%
  23194. %@NL@%
  23195. %@NL@%
  23196. %@AB@%/************************************************************************%@NL@%
  23197. %@AB@%*%@NL@%
  23198. %@AB@%*   ButtonUp%@NL@%
  23199. %@AB@%*%@NL@%
  23200. %@AB@%************************************************************************/%@AE@%%@NL@%
  23201. %@NL@%
  23202. VOID%@NL@%
  23203. ButtonUp(hwnd, usMsg)%@NL@%
  23204. HWND hwnd;%@NL@%
  23205. USHORT usMsg;%@NL@%
  23206. {%@NL@%
  23207.     int i;%@NL@%
  23208.     HPS hps;%@NL@%
  23209. %@NL@%
  23210. %@NL@%
  23211.     if (hwnd == global.hwnd)%@NL@%
  23212.         if (global.fDragging)%@NL@%
  23213.         {%@NL@%
  23214.             global.fDragging = FALSE;%@NL@%
  23215.             if (global.usPtGrabbed != -1)%@NL@%
  23216.             {%@NL@%
  23217.                 if (usMsg == WM_BUTTON2UP)%@NL@%
  23218.                 {%@NL@%
  23219.                     hps = WinGetPS(hwnd);%@NL@%
  23220.                     Paint(hps, FALSE);%@NL@%
  23221. %@NL@%
  23222.                     if ((i = global.usPtGrabbed) < (int) global.cptl-1)%@NL@%
  23223.                         while (i < (int) global.cptl-1)%@NL@%
  23224.                         {%@NL@%
  23225.                             global.pptl[i] = global.pptl[i+1];%@NL@%
  23226.                             ++i;%@NL@%
  23227.                         }%@NL@%
  23228. %@NL@%
  23229.                     --global.cptl;%@NL@%
  23230.                     global.usPtGrabbed = -1;%@NL@%
  23231. %@NL@%
  23232.                     Paint(hps, FALSE);%@NL@%
  23233.                     WinReleasePS(hps);%@NL@%
  23234.                 }%@NL@%
  23235.                 else        %@AB@%/* WM_BUTTON1UP */%@AE@%%@NL@%
  23236.                     global.usPtGrabbed = -1;%@NL@%
  23237.             }%@NL@%
  23238.         }%@NL@%
  23239. }%@NL@%
  23240. %@NL@%
  23241. %@NL@%
  23242. %@NL@%
  23243. %@NL@%
  23244. %@AB@%/************************************************************************%@NL@%
  23245. %@AB@%*%@NL@%
  23246. %@AB@%*   ButtonDown%@NL@%
  23247. %@AB@%*%@NL@%
  23248. %@AB@%************************************************************************/%@AE@%%@NL@%
  23249. %@NL@%
  23250. VOID%@NL@%
  23251. ButtonDown(hwnd, usMsg, mp1)%@NL@%
  23252. HWND hwnd;%@NL@%
  23253. USHORT usMsg;%@NL@%
  23254. MPARAM mp1;%@NL@%
  23255. {%@NL@%
  23256.     POINTL ptl;%@NL@%
  23257.     HPS hps;%@NL@%
  23258.     USHORT usNewPtGrabbed;%@NL@%
  23259. %@NL@%
  23260. %@NL@%
  23261.     if (hwnd == global.hwnd)%@NL@%
  23262.         if (!global.fDragging)%@NL@%
  23263.         {%@NL@%
  23264.             global.fDragging = TRUE;%@NL@%
  23265. %@NL@%
  23266.             ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  23267.             ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  23268. %@NL@%
  23269.             if ((usNewPtGrabbed = IsPtInList(&ptl)) != -1)%@NL@%
  23270.                 global.usPtGrabbed = usNewPtGrabbed;%@NL@%
  23271. %@NL@%
  23272.             if (usMsg == WM_BUTTON1DOWN)%@NL@%
  23273.             {%@NL@%
  23274.                 hps = WinGetPS(hwnd);%@NL@%
  23275.                 Paint(hps, FALSE);%@NL@%
  23276. %@NL@%
  23277.                 if (usNewPtGrabbed == -1)%@NL@%
  23278.                     global.usPtGrabbed = AddPtToList(&ptl);%@NL@%
  23279.                 else%@NL@%
  23280.                     global.usPtGrabbed = usNewPtGrabbed;%@NL@%
  23281. %@NL@%
  23282.                 Paint(hps, FALSE);%@NL@%
  23283.                 WinReleasePS(hps);%@NL@%
  23284. %@NL@%
  23285.                 if (global.usPtGrabbed == -1)%@NL@%
  23286.                     MyMessageBox(global.hwnd, "Cannot add any more points.");%@NL@%
  23287.             }%@NL@%
  23288.         }%@NL@%
  23289. }%@NL@%
  23290. %@NL@%
  23291. %@NL@%
  23292. %@NL@%
  23293. %@NL@%
  23294. %@AB@%/************************************************************************%@NL@%
  23295. %@AB@%*%@NL@%
  23296. %@AB@%*   IsPtInList%@NL@%
  23297. %@AB@%*%@NL@%
  23298. %@AB@%************************************************************************/%@AE@%%@NL@%
  23299. %@NL@%
  23300. USHORT%@NL@%
  23301. IsPtInList(pptl)%@NL@%
  23302. PPOINTL pptl;%@NL@%
  23303. {%@NL@%
  23304.     int i;%@NL@%
  23305. %@NL@%
  23306. %@NL@%
  23307.     %@AB@%/* try to find pptl in the points we already have */%@AE@%%@NL@%
  23308.     for (i = 0; i < (int) global.cptl; ++i)%@NL@%
  23309.         if (((abs(pptl->x - global.pptl[i].x))%@NL@%
  23310.                 <= (LONG) global.ulHitPrecision)%@NL@%
  23311.          && ((abs(pptl->y - global.pptl[i].y))%@NL@%
  23312.                 <= (LONG) global.ulHitPrecision))%@NL@%
  23313.                 return i;%@NL@%
  23314. %@NL@%
  23315.     %@AB@%/* couldn't find it */%@AE@%%@NL@%
  23316.     return -1;%@NL@%
  23317. }%@NL@%
  23318. %@NL@%
  23319. %@NL@%
  23320. %@NL@%
  23321. %@NL@%
  23322. %@AB@%/************************************************************************%@NL@%
  23323. %@AB@%*%@NL@%
  23324. %@AB@%*   AddPtToList%@NL@%
  23325. %@AB@%*%@NL@%
  23326. %@AB@%************************************************************************/%@AE@%%@NL@%
  23327. %@NL@%
  23328. USHORT%@NL@%
  23329. AddPtToList(pptl)%@NL@%
  23330. PPOINTL pptl;%@NL@%
  23331. {%@NL@%
  23332.     int i, j;%@NL@%
  23333. %@NL@%
  23334.     if (global.cptl < CPTLMAX)%@NL@%
  23335.     {%@NL@%
  23336.         %@AB@%/* check for new points lying on a line segment */%@AE@%%@NL@%
  23337.         for (i = 0; i < (int) (global.cptl - 1L); ++i)%@NL@%
  23338.             if (IsPtCloseToLine(&global.pptl[i], &global.pptl[i+1], pptl))%@NL@%
  23339.             {%@NL@%
  23340.                 for (j = (int) global.cptl; j > i+1; --j)%@NL@%
  23341.                     global.pptl[j] = global.pptl[j - 1];%@NL@%
  23342.                 global.pptl[i+1] = *pptl;%@NL@%
  23343.                 ++global.cptl;%@NL@%
  23344.                 return i+1;%@NL@%
  23345.             }%@NL@%
  23346. %@NL@%
  23347.         %@AB@%/* append the point */%@AE@%%@NL@%
  23348. %@NL@%
  23349.         i = (int) global.cptl;%@NL@%
  23350.         global.pptl[i] = *pptl;%@NL@%
  23351.         ++global.cptl;%@NL@%
  23352.         return i;%@NL@%
  23353.     }%@NL@%
  23354. %@NL@%
  23355.     return -1;%@NL@%
  23356. }%@NL@%
  23357. %@NL@%
  23358. %@NL@%
  23359. %@NL@%
  23360. %@NL@%
  23361. %@AB@%/************************************************************************%@NL@%
  23362. %@AB@%*%@NL@%
  23363. %@AB@%*   IsPtCloseToLine%@NL@%
  23364. %@AB@%*%@NL@%
  23365. %@AB@%************************************************************************/%@AE@%%@NL@%
  23366. %@NL@%
  23367. BOOL%@NL@%
  23368. IsPtCloseToLine(pptl1, pptl2, pptlTest)%@NL@%
  23369. PPOINTL pptl1;%@NL@%
  23370. PPOINTL pptl2;%@NL@%
  23371. PPOINTL pptlTest;%@NL@%
  23372. {%@NL@%
  23373.     POINTL ptlLL, ptlUR;%@NL@%
  23374.     LONG dx, dy, yIntercept, result;%@NL@%
  23375. %@NL@%
  23376. %@NL@%
  23377.     %@AB@%/* find the bounding box of the line segment */%@AE@%%@NL@%
  23378. %@NL@%
  23379.     ptlLL = *pptl1;        %@AB@%/* assume line goes lower left to upper right */%@AE@%%@NL@%
  23380.     ptlUR = *pptl2;%@NL@%
  23381.     if (pptl1->x > pptl2->x)%@NL@%
  23382.         SwapLong(&ptlLL.x, &ptlUR.x);%@NL@%
  23383.     if (pptl1->y > pptl2->y)%@NL@%
  23384.         SwapLong(&ptlLL.y, &ptlUR.y);%@NL@%
  23385. %@NL@%
  23386. %@NL@%
  23387.     %@AB@%/* adjust the bounding box if it's too narrow */%@AE@%%@NL@%
  23388. %@NL@%
  23389.     dx = pptl2->x - pptl1->x;%@NL@%
  23390.     if (abs(dx) <= (LONG) (global.ulHitPrecision >> 1))%@NL@%
  23391.     {%@NL@%
  23392.         ptlLL.x -= (LONG) (global.ulHitPrecision >> 1);%@NL@%
  23393.         ptlUR.x += (LONG) (global.ulHitPrecision >> 1);%@NL@%
  23394.     }%@NL@%
  23395.     dy = pptl2->y - pptl1->y;%@NL@%
  23396.     if (abs(dy) <= (LONG) (global.ulHitPrecision >> 1))%@NL@%
  23397.     {%@NL@%
  23398.         ptlLL.y -= (LONG) (global.ulHitPrecision >> 1);%@NL@%
  23399.         ptlUR.y += (LONG) (global.ulHitPrecision >> 1);%@NL@%
  23400.     }%@NL@%
  23401. %@NL@%
  23402. %@NL@%
  23403.     %@AB@%/* see if the test point is in the bounding box of the line segment */%@AE@%%@NL@%
  23404. %@NL@%
  23405.     if ((pptlTest->x >= ptlLL.x) &&%@NL@%
  23406.         (pptlTest->x <= ptlUR.x) &&%@NL@%
  23407.         (pptlTest->y >= ptlLL.y) &&%@NL@%
  23408.         (pptlTest->y <= ptlUR.y))%@NL@%
  23409.     {%@NL@%
  23410.         %@AB@%/* test for special cases */%@AE@%%@NL@%
  23411. %@NL@%
  23412.         if (dx == 0)%@NL@%
  23413.         {%@NL@%
  23414.             if (abs(pptlTest->x - pptl1->x) <= (LONG) global.ulHitPrecision)%@NL@%
  23415.                 return TRUE;%@NL@%
  23416.             else%@NL@%
  23417.                 return FALSE;%@NL@%
  23418.         }%@NL@%
  23419. %@NL@%
  23420.         if (dy == 0)%@NL@%
  23421.         {%@NL@%
  23422.             if (abs(pptlTest->y - pptl1->y) <= (LONG) global.ulHitPrecision)%@NL@%
  23423.                 return TRUE;%@NL@%
  23424.             else%@NL@%
  23425.                 return FALSE;%@NL@%
  23426.         }%@NL@%
  23427. %@NL@%
  23428. %@NL@%
  23429.         %@AB@%/* test for general case */%@AE@%%@NL@%
  23430. %@NL@%
  23431.         yIntercept = pptl1->y - (pptl1->x * dy) / dx;%@NL@%
  23432. %@NL@%
  23433.         result = pptlTest->y - (pptlTest->x * dy / dx) - yIntercept;%@NL@%
  23434.         if (abs(result) <= (LONG) global.ulHitPrecision)%@NL@%
  23435.             return TRUE;%@NL@%
  23436.     }%@NL@%
  23437. %@NL@%
  23438.     return FALSE;%@NL@%
  23439. }%@NL@%
  23440. %@NL@%
  23441. %@NL@%
  23442. %@NL@%
  23443. %@NL@%
  23444. %@AB@%/************************************************************************%@NL@%
  23445. %@AB@%*%@NL@%
  23446. %@AB@%*   SwapLong%@NL@%
  23447. %@AB@%*%@NL@%
  23448. %@AB@%************************************************************************/%@AE@%%@NL@%
  23449. %@NL@%
  23450. VOID%@NL@%
  23451. SwapLong(pl1, pl2)%@NL@%
  23452. PLONG pl1, pl2;%@NL@%
  23453. {%@NL@%
  23454.     LONG lTmp;%@NL@%
  23455. %@NL@%
  23456.     lTmp = *pl1;%@NL@%
  23457.     *pl1 = *pl2;%@NL@%
  23458.     *pl2 = lTmp;%@NL@%
  23459. }%@NL@%
  23460. %@NL@%
  23461. %@NL@%
  23462. %@NL@%
  23463. %@NL@%
  23464. %@AB@%/************************************************************************%@NL@%
  23465. %@AB@%*%@NL@%
  23466. %@AB@%*   Close%@NL@%
  23467. %@AB@%*%@NL@%
  23468. %@AB@%************************************************************************/%@AE@%%@NL@%
  23469. %@NL@%
  23470. VOID%@NL@%
  23471. Close(hwnd)%@NL@%
  23472. HWND hwnd;%@NL@%
  23473. {%@NL@%
  23474.     WinPostMsg(hwnd, WM_QUIT, 0L, 0L);%@NL@%
  23475. }%@NL@%
  23476. %@NL@%
  23477. %@NL@%
  23478. %@NL@%
  23479. %@NL@%
  23480. %@AB@%/************************************************************************%@NL@%
  23481. %@AB@%*%@NL@%
  23482. %@AB@%*   Command%@NL@%
  23483. %@AB@%*%@NL@%
  23484. %@AB@%*   Dispatches menu commands to the proper handlers.%@NL@%
  23485. %@AB@%*%@NL@%
  23486. %@AB@%************************************************************************/%@AE@%%@NL@%
  23487. %@NL@%
  23488. %@AI@%#define %@AE@%UPDATE_MENU_BOOL(var, val)                                \ %@NL@%
  23489.         {                                                        \%@NL@%
  23490.             TOGGLE_BOOL((var));                                 \%@NL@%
  23491.             TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var));        \%@NL@%
  23492.         }%@NL@%
  23493. %@NL@%
  23494. %@AI@%#define %@AE@%UPDATE_MENU_LIST(var, val)                                \ %@NL@%
  23495.         {                                                        \%@NL@%
  23496.             UNCHECK_MENU_ITEM(global.hwndFrame, (var));         \%@NL@%
  23497.             (var) = (val);                                        \%@NL@%
  23498.             CHECK_MENU_ITEM(global.hwndFrame, (var));                \%@NL@%
  23499.         }%@NL@%
  23500. %@NL@%
  23501. VOID%@NL@%
  23502. Command(hwnd, id)%@NL@%
  23503. HWND hwnd;%@NL@%
  23504. USHORT id;%@NL@%
  23505. {%@NL@%
  23506.     HPS hps;%@NL@%
  23507.     BOOL fRedraw = FALSE;%@NL@%
  23508.     int rc;%@NL@%
  23509. %@NL@%
  23510.     switch (id)%@NL@%
  23511.     {%@NL@%
  23512.     case IDM_ABOUT:%@NL@%
  23513.         rc = WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, (HMODULE) NULL, IDD_ABOUT, NULL);%@NL@%
  23514.         fRedraw = FALSE;%@NL@%
  23515.         break;%@NL@%
  23516. %@NL@%
  23517.     case IDM_NOPRIM:%@NL@%
  23518.         global.flPrim = 0L;%@NL@%
  23519.         TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYLINE, 0);%@NL@%
  23520.         TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET, 0);%@NL@%
  23521.         TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE, 0);%@NL@%
  23522.         fRedraw = TRUE;%@NL@%
  23523.         break;%@NL@%
  23524. %@NL@%
  23525.     case IDM_POLYLINE:%@NL@%
  23526.         global.flPrim ^= PRIM_POLYLINE;%@NL@%
  23527.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYLINE));%@NL@%
  23528.         fRedraw = TRUE;%@NL@%
  23529.         break;%@NL@%
  23530. %@NL@%
  23531.     case IDM_POLYFILLET:%@NL@%
  23532.         global.flPrim ^= PRIM_POLYFILLET;%@NL@%
  23533.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYFILLET));%@NL@%
  23534.         fRedraw = TRUE;%@NL@%
  23535.         break;%@NL@%
  23536. %@NL@%
  23537.     case IDM_POLYSPLINE:%@NL@%
  23538.         global.flPrim ^= PRIM_POLYSPLINE;%@NL@%
  23539.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYSPLINE));%@NL@%
  23540.         fRedraw = TRUE;%@NL@%
  23541.         break;%@NL@%
  23542. %@NL@%
  23543.     case IDM_POINTARC:%@NL@%
  23544.         global.flPrim ^= PRIM_POINTARC;%@NL@%
  23545.         TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POINTARC));%@NL@%
  23546.         fRedraw = TRUE;%@NL@%
  23547.         break;%@NL@%
  23548. %@NL@%
  23549.     case IDM_CTLPOINTS:%@NL@%
  23550.         UPDATE_MENU_BOOL(global.fDisplayControlPoints, IDM_CTLPOINTS);%@NL@%
  23551.         fRedraw = TRUE;%@NL@%
  23552.         break;%@NL@%
  23553. %@NL@%
  23554.     case IDM_CLEARALL:%@NL@%
  23555.         global.cptl = 0L;%@NL@%
  23556.         fRedraw = TRUE;%@NL@%
  23557.         break;%@NL@%
  23558. %@NL@%
  23559.     case IDM_COPY:%@NL@%
  23560.         %@AB@%/*%@NL@%
  23561. %@AB@%            To put this image on the clipboard, create a Metafile DC.%@NL@%
  23562. %@AB@%%@NL@%
  23563. %@AB@%            Associate a presentation space with the DC, then play the%@NL@%
  23564. %@AB@%            drawing orders into the metafile.%@NL@%
  23565. %@AB@%        */%@AE@%%@NL@%
  23566.         global.dop.pszLogAddress = NULL;%@NL@%
  23567.         global.dop.pszDriverName = "DISPLAY";%@NL@%
  23568.         global.dop.pdriv = NULL;%@NL@%
  23569.         global.dop.pszDataType = NULL;%@NL@%
  23570. %@NL@%
  23571.         global.hdcMetafile = DevOpenDC(global.hab, OD_METAFILE,%@NL@%
  23572.                             "*", 4L, (PDEVOPENDATA) &global.dop, NULL);%@NL@%
  23573.         global.hpsMetafile = GpiCreatePS(global.hab, global.hdcMetafile,%@NL@%
  23574.                                     &global.sizlPage, PU_PELS | GPIA_ASSOC);%@NL@%
  23575. %@NL@%
  23576.         Paint(global.hpsMetafile, TRUE);%@NL@%
  23577.         %@AB@%/*%@NL@%
  23578. %@AB@%            Clean up.  A handle to the metafile is obtained when%@NL@%
  23579. %@AB@%            calling DevCloseDC().%@NL@%
  23580. %@AB@%        */%@AE@%%@NL@%
  23581.         GpiAssociate(global.hpsMetafile, NULL);%@NL@%
  23582.         GpiDestroyPS(global.hpsMetafile);%@NL@%
  23583.         global.hItem = (ULONG) DevCloseDC(global.hdcMetafile);%@NL@%
  23584.         %@AB@%/*%@NL@%
  23585. %@AB@%            Be sure to empty the clipboard of other data.  This will%@NL@%
  23586. %@AB@%            also empty previous data stored in other formats.%@NL@%
  23587. %@AB@%            Then, set the clipboard data with type METAFILE, passing%@NL@%
  23588. %@AB@%            the handle to our metafile.%@NL@%
  23589. %@AB@%        */%@AE@%%@NL@%
  23590.         if (WinOpenClipbrd(global.hab)) {%@NL@%
  23591.             WinEmptyClipbrd(global.hab);%@NL@%
  23592.             WinSetClipbrdData(global.hab,global.hItem, CF_METAFILE, CFI_HANDLE);%@NL@%
  23593.             WinCloseClipbrd(global.hab);%@NL@%
  23594.         }%@NL@%
  23595.         break;%@NL@%
  23596.     }%@NL@%
  23597. %@NL@%
  23598.     if (fRedraw)%@NL@%
  23599.     {%@NL@%
  23600.         hps = WinGetPS(hwnd);%@NL@%
  23601.         Paint(hps, TRUE);%@NL@%
  23602.         WinReleasePS(hps);%@NL@%
  23603.     }%@NL@%
  23604. }%@NL@%
  23605. %@NL@%
  23606. %@NL@%
  23607. %@NL@%
  23608. %@NL@%
  23609. %@AB@%/************************************************************************%@NL@%
  23610. %@AB@%*%@NL@%
  23611. %@AB@%*   Paint%@NL@%
  23612. %@AB@%*%@NL@%
  23613. %@AB@%************************************************************************/%@AE@%%@NL@%
  23614. %@NL@%
  23615. VOID%@NL@%
  23616. Paint(hps, fClearScreen)%@NL@%
  23617. HPS  hps;%@NL@%
  23618. BOOL fClearScreen;%@NL@%
  23619. {%@NL@%
  23620.     LINEBUNDLE lb;%@NL@%
  23621.     RECTL rcl;%@NL@%
  23622.     if (fClearScreen)%@NL@%
  23623.     {%@NL@%
  23624.         %@AB@%/* clear the screen */%@AE@%%@NL@%
  23625.         WinQueryWindowRect(global.hwnd, &rcl);%@NL@%
  23626.         GpiBitBlt(hps, NULL, 2L, (PPOINTL) &rcl, ROP_ONE, 0L);%@NL@%
  23627.     }%@NL@%
  23628. %@NL@%
  23629. %@NL@%
  23630.     if (global.cptl > 0L)%@NL@%
  23631.     {%@NL@%
  23632.         if (global.fDisplayControlPoints)%@NL@%
  23633.         {%@NL@%
  23634.             if (fClearScreen)%@NL@%
  23635.                 %@AB@%/* draw all the control points */%@AE@%%@NL@%
  23636.                 DrawControlPoints(hps, global.cptl, global.pptl);%@NL@%
  23637.             else if (global.usPtGrabbed != -1)%@NL@%
  23638.                 %@AB@%/* draw just the control point that moved */%@AE@%%@NL@%
  23639.                 DrawControlPoints(hps, 1L, global.pptl+global.usPtGrabbed);%@NL@%
  23640.         }%@NL@%
  23641. %@NL@%
  23642.         %@AB@%/* set mix mode to xor */%@AE@%%@NL@%
  23643.         lb.usMixMode = FM_XOR;%@NL@%
  23644.         GpiSetAttrs(hps, PRIM_LINE, LBB_MIX_MODE, 0L, &lb);%@NL@%
  23645. %@NL@%
  23646.         %@AB@%/* draw the current primitives */%@AE@%%@NL@%
  23647. %@NL@%
  23648.         if (global.flPrim & PRIM_POLYLINE)%@NL@%
  23649.         {%@NL@%
  23650.             lb.lColor = CLR_BROWN;%@NL@%
  23651.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  23652.             DrawPrimitive(hps, IDM_POLYLINE);%@NL@%
  23653.         }%@NL@%
  23654. %@NL@%
  23655.         if (global.flPrim & PRIM_POLYFILLET)%@NL@%
  23656.         {%@NL@%
  23657.             lb.lColor = CLR_DARKCYAN;%@NL@%
  23658.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  23659.             DrawPrimitive(hps, IDM_POLYFILLET);%@NL@%
  23660.         }%@NL@%
  23661. %@NL@%
  23662.         if (global.flPrim & PRIM_POLYSPLINE)%@NL@%
  23663.         {%@NL@%
  23664.             lb.lColor = CLR_DARKPINK;%@NL@%
  23665.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  23666.             DrawPrimitive(hps, IDM_POLYSPLINE);%@NL@%
  23667.         }%@NL@%
  23668. %@NL@%
  23669.         if (global.flPrim & PRIM_POINTARC)%@NL@%
  23670.         {%@NL@%
  23671.             lb.lColor = CLR_BACKGROUND;%@NL@%
  23672.             GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  23673.             DrawPrimitive(hps, IDM_POINTARC);%@NL@%
  23674.         }%@NL@%
  23675.     }%@NL@%
  23676. }%@NL@%
  23677. %@NL@%
  23678. %@NL@%
  23679. %@NL@%
  23680. %@NL@%
  23681. %@AB@%/************************************************************************%@NL@%
  23682. %@AB@%*%@NL@%
  23683. %@AB@%*   DrawPrimitive%@NL@%
  23684. %@AB@%*%@NL@%
  23685. %@AB@%************************************************************************/%@AE@%%@NL@%
  23686. %@NL@%
  23687. VOID%@NL@%
  23688. DrawPrimitive(hps, usPrim)%@NL@%
  23689. HPS hps;%@NL@%
  23690. USHORT usPrim;%@NL@%
  23691. {%@NL@%
  23692.     switch ( usPrim )%@NL@%
  23693.     {%@NL@%
  23694.     case IDM_POLYLINE:%@NL@%
  23695.         DrawPolyLine(hps);%@NL@%
  23696.         break;%@NL@%
  23697. %@NL@%
  23698.     case IDM_POLYFILLET:%@NL@%
  23699.         DrawPolyFillet(hps);%@NL@%
  23700.         break;%@NL@%
  23701. %@NL@%
  23702.     case IDM_POLYSPLINE:%@NL@%
  23703.         DrawPolySpline(hps);%@NL@%
  23704.         break;%@NL@%
  23705. %@NL@%
  23706.     case IDM_POINTARC:%@NL@%
  23707.         DrawPointArc(hps);%@NL@%
  23708.         break;%@NL@%
  23709.     }%@NL@%
  23710. }%@NL@%
  23711. %@NL@%
  23712. %@NL@%
  23713. %@NL@%
  23714. %@NL@%
  23715. %@AB@%/************************************************************************%@NL@%
  23716. %@AB@%*%@NL@%
  23717. %@AB@%*   DrawPolyLine%@NL@%
  23718. %@AB@%*%@NL@%
  23719. %@AB@%************************************************************************/%@AE@%%@NL@%
  23720. %@NL@%
  23721. VOID%@NL@%
  23722. DrawPolyLine(hps)%@NL@%
  23723. HPS hps;%@NL@%
  23724. {%@NL@%
  23725.     GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  23726.     GpiPolyLine( hps, global.cptl-1L, global.pptl+1 );%@NL@%
  23727. }%@NL@%
  23728. %@NL@%
  23729. %@NL@%
  23730. %@NL@%
  23731. %@NL@%
  23732. %@AB@%/************************************************************************%@NL@%
  23733. %@AB@%*%@NL@%
  23734. %@AB@%*   DrawPolyFillet%@NL@%
  23735. %@AB@%*%@NL@%
  23736. %@AB@%************************************************************************/%@AE@%%@NL@%
  23737. %@NL@%
  23738. VOID%@NL@%
  23739. DrawPolyFillet(hps)%@NL@%
  23740. HPS hps;%@NL@%
  23741. {%@NL@%
  23742.     if (global.cptl > 2)%@NL@%
  23743.     {%@NL@%
  23744.         GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  23745.         GpiPolyFillet( hps, global.cptl-1L, global.pptl+1 );%@NL@%
  23746.     }%@NL@%
  23747. }%@NL@%
  23748. %@NL@%
  23749. %@NL@%
  23750. %@NL@%
  23751. %@NL@%
  23752. %@AB@%/************************************************************************%@NL@%
  23753. %@AB@%*%@NL@%
  23754. %@AB@%*   DrawPolySpline%@NL@%
  23755. %@AB@%*%@NL@%
  23756. %@AB@%************************************************************************/%@AE@%%@NL@%
  23757. %@NL@%
  23758. VOID%@NL@%
  23759. DrawPolySpline(hps)%@NL@%
  23760. HPS hps;%@NL@%
  23761. {%@NL@%
  23762.     USHORT cptSlack;        %@AB@%/* # points in pptl not usable by PolySpline */%@AE@%%@NL@%
  23763. %@NL@%
  23764.     %@AB@%/* GpiPolySpline expects the number of points to be a%@NL@%
  23765. %@AB@%       multiple of 3.  If we have a non-multiple of three,%@NL@%
  23766. %@AB@%       (excluding the first point, which we've used to set%@NL@%
  23767. %@AB@%       the current position), only pass the largest multiple%@NL@%
  23768. %@AB@%       of three, saving the rest for the next go-round. */%@AE@%%@NL@%
  23769. %@NL@%
  23770.     cptSlack = (int)((global.cptl-1L) % 3) + 1;%@NL@%
  23771.     GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  23772.     GpiPolySpline( hps, global.cptl-cptSlack,%@NL@%
  23773.                    global.pptl+1 );%@NL@%
  23774. }%@NL@%
  23775. %@NL@%
  23776. %@NL@%
  23777. %@NL@%
  23778. %@NL@%
  23779. %@AB@%/************************************************************************%@NL@%
  23780. %@AB@%*%@NL@%
  23781. %@AB@%*   DrawPointArc%@NL@%
  23782. %@AB@%*%@NL@%
  23783. %@AB@%************************************************************************/%@AE@%%@NL@%
  23784. %@NL@%
  23785. VOID%@NL@%
  23786. DrawPointArc(hps)%@NL@%
  23787. HPS hps;%@NL@%
  23788. {%@NL@%
  23789.     if (global.cptl >= 3L)%@NL@%
  23790.     {%@NL@%
  23791.         GpiSetCurrentPosition( hps, global.pptl );%@NL@%
  23792.         GpiPointArc( hps, global.pptl+1 );%@NL@%
  23793.     }%@NL@%
  23794. }%@NL@%
  23795. %@NL@%
  23796. %@NL@%
  23797. %@NL@%
  23798. %@NL@%
  23799. %@AB@%/************************************************************************%@NL@%
  23800. %@AB@%*%@NL@%
  23801. %@AB@%*   DrawControlPoints%@NL@%
  23802. %@AB@%*%@NL@%
  23803. %@AB@%************************************************************************/%@AE@%%@NL@%
  23804. %@NL@%
  23805. VOID%@NL@%
  23806. DrawControlPoints(hps, cptl, pptl)%@NL@%
  23807. HPS hps;%@NL@%
  23808. LONG cptl;%@NL@%
  23809. PPOINTL pptl;%@NL@%
  23810. {%@NL@%
  23811.     MARKERBUNDLE mb;%@NL@%
  23812. %@NL@%
  23813.     mb.lColor = CLR_TRUE;%@NL@%
  23814.     mb.usMixMode = FM_XOR;%@NL@%
  23815.     GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR | MBB_MIX_MODE, 0L, &mb);%@NL@%
  23816. %@NL@%
  23817.     GpiPolyMarker(hps, cptl, pptl);%@NL@%
  23818. }%@NL@%
  23819. %@NL@%
  23820. %@NL@%
  23821. %@NL@%
  23822. %@NL@%
  23823. %@AB@%/************************************************************************%@NL@%
  23824. %@AB@%*%@NL@%
  23825. %@AB@%*   MyMessageBox%@NL@%
  23826. %@AB@%*%@NL@%
  23827. %@AB@%*   Displays a message box with the given string.  To simplify matters,%@NL@%
  23828. %@AB@%*   the box will always have the same title ("PolyLine Editor"), will always%@NL@%
  23829. %@AB@%*   have a single button ("Ok"), will always have an exclamation point%@NL@%
  23830. %@AB@%*   icon, and will always be application modal.%@NL@%
  23831. %@AB@%*%@NL@%
  23832. %@AB@%************************************************************************/%@AE@%%@NL@%
  23833. %@NL@%
  23834. VOID%@NL@%
  23835. MyMessageBox(hWnd, sz)%@NL@%
  23836. HWND hWnd;%@NL@%
  23837. PSZ sz;%@NL@%
  23838. {%@NL@%
  23839.     static char *szTitle = "PolyLine Editor";%@NL@%
  23840. %@NL@%
  23841.     WinMessageBox(HWND_DESKTOP, hWnd, sz, szTitle, 0,%@NL@%
  23842.                   MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);%@NL@%
  23843. }%@NL@%
  23844. %@NL@%
  23845. MRESULT CALLBACK AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) {%@NL@%
  23846. %@AB@%/*%@NL@%
  23847. %@AB@%    About... dialog procedure%@NL@%
  23848. %@AB@%*/%@AE@%%@NL@%
  23849.     switch(msg) {%@NL@%
  23850.         case WM_COMMAND:%@NL@%
  23851.             switch(COMMANDMSG(&msg)->cmd) {%@NL@%
  23852.                 case DID_OK: WinDismissDlg(hDlg, TRUE); break;%@NL@%
  23853.                 default: break;%@NL@%
  23854.             }%@NL@%
  23855.         default: return WinDefDlgProc(hDlg, msg, mp1, mp2);%@NL@%
  23856.     }%@NL@%
  23857.     return FALSE;%@NL@%
  23858. }%@NL@%
  23859. %@NL@%
  23860. %@NL@%
  23861. %@2@%%@AH@%EXPAND.C%@AE@%%@EH@%%@NL@%
  23862. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\EXPAND\EXPAND.C%@AE@%%@NL@%
  23863. %@NL@%
  23864. %@AI@%#define %@AE@%INCL_PM %@NL@%
  23865. %@AI@%#include %@AE@%<OS2.H> %@NL@%
  23866. %@AI@%#include %@AE@%"Expand.H" %@NL@%
  23867. %@NL@%
  23868. MRESULT EXPENTRY WndProc      (HWND, USHORT, MPARAM, MPARAM );%@NL@%
  23869. MRESULT EXPENTRY AboutDlgProc (HWND, USHORT, MPARAM, MPARAM);%@NL@%
  23870. MRESULT EXPENTRY DialogProc  (HWND, USHORT, MPARAM, MPARAM);%@NL@%
  23871. %@NL@%
  23872. int cdecl main(void);%@NL@%
  23873. %@NL@%
  23874. char szAppName[] = "Expand";%@NL@%
  23875. %@NL@%
  23876. HAB        hAB;%@NL@%
  23877. HMQ        hmqMsgQueue;%@NL@%
  23878. HWND        hWndMain,%@NL@%
  23879.         hWndFrame;%@NL@%
  23880. %@NL@%
  23881. int cdecl main()%@NL@%
  23882. {%@NL@%
  23883.     QMSG    qmsg;%@NL@%
  23884.     ULONG   ctlData;%@NL@%
  23885. %@NL@%
  23886.     hAB = WinInitialize (0);%@NL@%
  23887.     hmqMsgQueue = WinCreateMsgQueue (hAB, 0);%@NL@%
  23888. %@NL@%
  23889.     if (!WinRegisterClass (hAB,%@NL@%
  23890.                            szAppName,%@NL@%
  23891.                            WndProc,%@NL@%
  23892.                            CS_SYNCPAINT | CS_SIZEREDRAW,%@NL@%
  23893.                            0)) {%@NL@%
  23894.         return(0);%@NL@%
  23895.     }%@NL@%
  23896. %@NL@%
  23897. %@NL@%
  23898.     ctlData = FCF_STANDARD;%@NL@%
  23899.     hWndFrame = WinCreateStdWindow ( HWND_DESKTOP,%@NL@%
  23900.                                     WS_VISIBLE,%@NL@%
  23901.                                     &ctlData,%@NL@%
  23902.                                     szAppName,%@NL@%
  23903.                                     NULL,%@NL@%
  23904.                                     0L,%@NL@%
  23905.                                     0,%@NL@%
  23906.                                     ID_RESOURCE,%@NL@%
  23907.                                     &hWndMain);%@NL@%
  23908.     WinSetWindowText (hWndFrame, szAppName);%@NL@%
  23909.     WinShowWindow (hWndFrame, TRUE);%@NL@%
  23910. %@NL@%
  23911.     while ( WinGetMsg (hAB, &qmsg, NULL, 0, 0)) {%@NL@%
  23912.         WinDispatchMsg (hAB, &qmsg);%@NL@%
  23913.     }%@NL@%
  23914. %@NL@%
  23915.     WinDestroyWindow   (hWndFrame);%@NL@%
  23916.     WinDestroyMsgQueue (hmqMsgQueue);%@NL@%
  23917.     WinTerminate       (hAB);%@NL@%
  23918. }%@NL@%
  23919. %@NL@%
  23920. MRESULT EXPENTRY WndProc (hWnd, msg, mp1, mp2)%@NL@%
  23921.     HWND    hWnd;%@NL@%
  23922.     USHORT  msg;%@NL@%
  23923.     MPARAM  mp1, mp2;%@NL@%
  23924. {%@NL@%
  23925.     HPS    hPS;%@NL@%
  23926.     RECTL   rclPaint, rclWindow;%@NL@%
  23927.     POINTL  ptlPatternRef;%@NL@%
  23928. %@NL@%
  23929.     switch (msg) {%@NL@%
  23930. %@NL@%
  23931.         case WM_COMMAND:%@NL@%
  23932.             switch (COMMANDMSG(&msg)->cmd) {%@NL@%
  23933.                 case IDM_ABOUT:%@NL@%
  23934.                     WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,%@NL@%
  23935.                         (HMODULE) NULL, ID_RESOURCE, NULL);%@NL@%
  23936.                     break;%@NL@%
  23937. %@NL@%
  23938.                 case IDM_ITEM+1:%@NL@%
  23939.                     WinDlgBox(HWND_DESKTOP, hWnd, DialogProc,%@NL@%
  23940.                         (HMODULE) NULL, ID_DIALOG, NULL);%@NL@%
  23941.                     break;%@NL@%
  23942. %@NL@%
  23943.                 case IDM_ITEM+2:%@NL@%
  23944.                 case IDM_ITEM+3:%@NL@%
  23945.                 case IDM_ITEM+4:%@NL@%
  23946.                     break;%@NL@%
  23947. %@NL@%
  23948.                 case IDM_EXIT:%@NL@%
  23949.                     WinPostMsg (hWnd, WM_CLOSE, 0L, 0L);%@NL@%
  23950.                     break;%@NL@%
  23951.             }%@NL@%
  23952.             break;%@NL@%
  23953. %@NL@%
  23954.         case WM_HELP:%@NL@%
  23955.             WinMessageBox (HWND_DESKTOP, hWnd,%@NL@%
  23956.                 "Help Not Implemented Yet.",%@NL@%
  23957.                 " - Help - ",%@NL@%
  23958.                 0,%@NL@%
  23959.                 MB_OK | MB_MOVEABLE | MB_APPLMODAL);%@NL@%
  23960.             break;%@NL@%
  23961. %@NL@%
  23962.         case WM_CLOSE:%@NL@%
  23963.             WinPostMsg (hWnd, WM_QUIT, 0L, 0L);%@NL@%
  23964.             break;%@NL@%
  23965. %@NL@%
  23966.         case WM_PAINT:%@NL@%
  23967.             hPS = WinBeginPaint (hWnd, NULL, &rclPaint);%@NL@%
  23968. %@NL@%
  23969.             WinQueryWindowRect(hWnd, &rclWindow);%@NL@%
  23970.             ptlPatternRef.x = rclWindow.xLeft;%@NL@%
  23971.             ptlPatternRef.y = rclWindow.yTop;%@NL@%
  23972.             GpiSetPatternRefPoint(hPS, &ptlPatternRef);%@NL@%
  23973.             WinFillRect(hPS, &rclPaint, SYSCLR_APPWORKSPACE);%@NL@%
  23974. %@NL@%
  23975.             WinEndPaint (hPS);%@NL@%
  23976.             break;%@NL@%
  23977. %@NL@%
  23978.         default:%@NL@%
  23979.             return (WinDefWindowProc (hWnd, msg, mp1, mp2));%@NL@%
  23980.     }%@NL@%
  23981.     return 0L;%@NL@%
  23982. }%@NL@%
  23983. %@NL@%
  23984. %@NL@%
  23985. MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  23986. {%@NL@%
  23987.     switch (msg) {%@NL@%
  23988.         case WM_COMMAND:%@NL@%
  23989.             switch (COMMANDMSG(&msg)->cmd) {%@NL@%
  23990.                 case IDB_OK:%@NL@%
  23991.                     WinDismissDlg (hwnd, TRUE);%@NL@%
  23992.                     return 0;%@NL@%
  23993.             }%@NL@%
  23994.             break;%@NL@%
  23995.      }%@NL@%
  23996.      return WinDefDlgProc (hwnd, msg, mp1, mp2);%@NL@%
  23997. }%@NL@%
  23998. %@NL@%
  23999. MRESULT EXPENTRY DialogProc (HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2)%@NL@%
  24000. {%@NL@%
  24001.     SWP  swpDlg, swpParent, swpOwner;%@NL@%
  24002.     static HWND option, button1, button2, button3, button4;%@NL@%
  24003. %@NL@%
  24004.     switch (msg) {%@NL@%
  24005. %@NL@%
  24006.         case WM_INITDLG:%@NL@%
  24007.             WinSendDlgItemMsg (hDlg, 256, EM_SETTEXTLIMIT, MPFROMSHORT(8), 0L);%@NL@%
  24008.             WinQueryWindowPos (hDlg, &swpDlg);%@NL@%
  24009.             WinQueryWindowPos (WinQueryWindow(hDlg, QW_PARENT, FALSE), &swpParent);%@NL@%
  24010.             WinQueryWindowPos (WinQueryWindow(hDlg, QW_OWNER, FALSE), &swpOwner);%@NL@%
  24011.             swpDlg.x = swpOwner.x + ((swpOwner.cx / 2) - ((swpDlg.cx+120) / 2));%@NL@%
  24012.             swpDlg.y = swpOwner.y + ((swpOwner.cy / 2) - (swpDlg.cy / 2));%@NL@%
  24013.             WinSetMultWindowPos (hAB, &swpDlg, 1);%@NL@%
  24014.             option  = WinWindowFromID (hDlg, IDB_OPTION);%@NL@%
  24015.             button1 = WinWindowFromID (hDlg, IDB_RADIO1);%@NL@%
  24016.             WinShowWindow (button1, FALSE);%@NL@%
  24017.             button2 = WinWindowFromID (hDlg, IDB_RADIO2);%@NL@%
  24018.             WinShowWindow (button2, FALSE);%@NL@%
  24019.             button3 = WinWindowFromID (hDlg, IDB_RADIO3);%@NL@%
  24020.             WinShowWindow (button3, FALSE);%@NL@%
  24021.             button4 = WinWindowFromID (hDlg, IDB_RADIO4);%@NL@%
  24022.             WinShowWindow (button4, FALSE);%@NL@%
  24023.             break;%@NL@%
  24024. %@NL@%
  24025.         case WM_COMMAND:%@NL@%
  24026.             switch (COMMANDMSG(&msg)->cmd) {%@NL@%
  24027.                 case IDB_OPTION:%@NL@%
  24028.                     WinQueryWindowPos (hDlg, &swpDlg);%@NL@%
  24029.                     swpDlg.fs = SWP_SIZE;%@NL@%
  24030.                     swpDlg.cx += 120;%@NL@%
  24031.                     WinSetMultWindowPos (hAB, &swpDlg, 1);%@NL@%
  24032.                     WinEnableWindow (option, FALSE);%@NL@%
  24033.                     WinShowWindow (button1, TRUE);%@NL@%
  24034.                     WinShowWindow (button2, TRUE);%@NL@%
  24035.                     WinShowWindow (button3, TRUE);%@NL@%
  24036.                     WinShowWindow (button4, TRUE);%@NL@%
  24037.                     WinSetFocus (HWND_DESKTOP, button1);%@NL@%
  24038.                     return FALSE;%@NL@%
  24039. %@NL@%
  24040.                 case IDB_OK:%@NL@%
  24041.                 case IDB_CANCEL:%@NL@%
  24042.                     WinDismissDlg (hDlg, TRUE);%@NL@%
  24043.                     return 0;%@NL@%
  24044.             }%@NL@%
  24045.             break;%@NL@%
  24046.      }%@NL@%
  24047.      return WinDefDlgProc (hDlg, msg, mp1, mp2);%@NL@%
  24048. }%@NL@%
  24049. %@NL@%
  24050. %@NL@%
  24051. %@2@%%@AH@%FATPEL.C%@AE@%%@EH@%%@NL@%
  24052. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\FATPEL\FATPEL.C%@AE@%%@NL@%
  24053. %@NL@%
  24054. %@AB@%/************************************************************************%@NL@%
  24055. %@AB@%*%@NL@%
  24056. %@AB@%*   fatpel.c -- The Diamond Metric, Theory vs. Practice%@NL@%
  24057. %@AB@%*%@NL@%
  24058. %@AB@%*   Created by Microsoft Corporation, 1989%@NL@%
  24059. %@AB@%*%@NL@%
  24060. %@AB@%************************************************************************/%@AE@%%@NL@%
  24061.  %@NL@%
  24062. %@AI@%#define %@AE@%INCL_WINFRAMEMGR %@NL@%
  24063. %@AI@%#define %@AE@%INCL_WINWINDOWMGR %@NL@%
  24064. %@AI@%#define %@AE@%INCL_WINMESSAGEMGR %@NL@%
  24065. %@AI@%#define %@AE@%       INCL_WINPOINTERS %@NL@%
  24066. %@AI@%#define %@AE@%INCL_WINSWITCHLIST %@NL@%
  24067. %@AI@%#define %@AE@%INCL_WINTRACKRECT %@NL@%
  24068. %@AI@%#define %@AE@%INCL_WINDIALOGS %@NL@%
  24069. %@AI@%#define %@AE@%INCL_WINBUTTONS %@NL@%
  24070. %@AI@%#define %@AE@%INCL_GPILOGCOLORTABLE %@NL@%
  24071. %@AI@%#define %@AE@%INCL_GPIBITMAPS %@NL@%
  24072. %@AI@%#define %@AE@%       INCL_GPITRANSFORMS %@NL@%
  24073. %@AI@%#define %@AE@%INCL_DOSMEMMGR %@NL@%
  24074. %@AI@%#define %@AE@%INCL_DOSFILEMGR %@NL@%
  24075. %@AI@%#define %@AE@%INCL_BITMAPFILEFORMAT %@NL@%
  24076. %@AI@%#define %@AE@%INCL_GPIPRIMITIVES %@NL@%
  24077. %@AI@%#define %@AE@%INCL_WINMENUS %@NL@%
  24078. %@AI@%#define %@AE@%INCL_GPIREGIONS %@NL@%
  24079. %@AI@%#define %@AE@%INCL_WINPOINTERS %@NL@%
  24080. %@AI@%#define %@AE@%INCL_WININPUT %@NL@%
  24081. %@AI@%#include %@AE@%<os2.h> %@NL@%
  24082. %@NL@%
  24083. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  24084. %@AI@%#include %@AE@%<stdlib.h> %@NL@%
  24085. %@AI@%#include %@AE@%<string.h> %@NL@%
  24086. %@NL@%
  24087. %@AI@%#include %@AE@%"opendlg.h" %@NL@%
  24088. %@AI@%#include %@AE@%"fatpel.h" %@NL@%
  24089. %@NL@%
  24090. %@NL@%
  24091. %@NL@%
  24092. %@NL@%
  24093. %@AB@%/************************************************************************%@NL@%
  24094. %@AB@%*%@NL@%
  24095. %@AB@%*   Function declarations%@NL@%
  24096. %@AB@%*%@NL@%
  24097. %@AB@%************************************************************************/%@AE@%%@NL@%
  24098. %@NL@%
  24099. %@AB@%/* Private functions */%@AE@%%@NL@%
  24100. %@NL@%
  24101. VOID  cdecl main(VOID);%@NL@%
  24102. BOOL  FAR InitGlobals(VOID);%@NL@%
  24103. BOOL  FAR InitApp(VOID);%@NL@%
  24104. VOID  Close(HWND);%@NL@%
  24105. VOID  Command(HWND, USHORT);%@NL@%
  24106. VOID  Paint(HPS, USHORT);%@NL@%
  24107. VOID  EraseBackground(HPS);%@NL@%
  24108. VOID  DrawGrid(HPS);%@NL@%
  24109. VOID  DisplayRenderedPels(HPS, USHORT);%@NL@%
  24110. VOID  DisplayControlPoints(HPS, LONG, PPOINTL, USHORT);%@NL@%
  24111. VOID  DisplayMathematicalObject(HPS, USHORT);%@NL@%
  24112. VOID  DrawFatPels(HPS);%@NL@%
  24113. VOID  DrawOneFatPel(HPS, PPOINTL, COLOR);%@NL@%
  24114. VOID  GetFatPelFromPt(PPOINTL, PPOINTL);%@NL@%
  24115. VOID  SetFatPel(PPOINTL, COLOR);%@NL@%
  24116. VOID  RoundControlPoints(HPS, LONG, PPOINTL, PPOINTL, LONG, LONG);%@NL@%
  24117. VOID  ComputeTransform(PRECTL, PRECTL);%@NL@%
  24118. VOID  DrawPrimitive(HPS, LONG, PPOINTL);%@NL@%
  24119. VOID  UpdateSurfaceDims(VOID);%@NL@%
  24120. VOID  MySetWindowLong        (HWND, USHORT, LONG);%@NL@%
  24121. VOID  MySetWindowLongHex(HWND, USHORT, LONG);%@NL@%
  24122. LONG  MyGetWindowLong        (HWND, USHORT);%@NL@%
  24123. VOID  MouseMove(HWND, MPARAM);%@NL@%
  24124. VOID  ButtonUp(HWND, USHORT);%@NL@%
  24125. VOID  ButtonDown(HWND, USHORT, MPARAM);%@NL@%
  24126. VOID  DragPelSize(HWND, POINTS);%@NL@%
  24127. VOID  WriteFile(HWND, HPS);%@NL@%
  24128. BOOL  WriteBMP(HFILE, HPS, PBITMAPINFOHEADER);%@NL@%
  24129. VOID  MyMessageBox(HWND, PSZ);%@NL@%
  24130. VOID  SaveWindowToFile(HWND);%@NL@%
  24131. SHORT IsPtInList(PPOINTL);%@NL@%
  24132. SHORT AddPtToList(PPOINTL);%@NL@%
  24133. BOOL  IsPtCloseToLine(PPOINTL, PPOINTL, PPOINTL);%@NL@%
  24134. VOID  SwapLong(PLONG, PLONG);%@NL@%
  24135. %@NL@%
  24136. %@NL@%
  24137. %@AB@%/* Exported functions */%@AE@%%@NL@%
  24138. %@NL@%
  24139. ULONG CALLBACK WndProc         (HWND, USHORT, MPARAM, MPARAM);%@NL@%
  24140. ULONG CALLBACK AboutDlg  (HWND, USHORT, MPARAM, MPARAM);%@NL@%
  24141. ULONG CALLBACK ColorsDlg (HWND, USHORT, MPARAM, MPARAM);%@NL@%
  24142. ULONG CALLBACK PelSizeDlg(HWND, USHORT, MPARAM, MPARAM);%@NL@%
  24143. %@NL@%
  24144. %@NL@%
  24145. %@NL@%
  24146. %@NL@%
  24147. %@AB@%/************************************************************************%@NL@%
  24148. %@AB@%*%@NL@%
  24149. %@AB@%*   Global Variables%@NL@%
  24150. %@AB@%*%@NL@%
  24151. %@AB@%************************************************************************/%@AE@%%@NL@%
  24152. %@NL@%
  24153. %@AB@%/* compute absolute value for arbitrary (in my case, LONG) number */%@AE@%%@NL@%
  24154. %@AB@%/* this is to avoid compiler warnings about data conversion */%@AE@%%@NL@%
  24155. %@AI@%#define %@AE@%L_ABS(x)        (((x) > 0) ? (x) : (-(x))) %@NL@%
  24156. %@NL@%
  24157. typedef struct%@NL@%
  24158. {%@NL@%
  24159.     HAB      hab;%@NL@%
  24160.     HMQ      hMsgQ;%@NL@%
  24161.     HWND     hwndFrame;%@NL@%
  24162.     HWND     hwnd;%@NL@%
  24163. %@NL@%
  24164.     BOOL     fFirstTime;   %@AB@%/* TRUE --> first time initialization of rcl */%@AE@%%@NL@%
  24165.     RECTL    rcl;           %@AB@%/* dimensions of client rectangle */%@AE@%%@NL@%
  24166. %@NL@%
  24167.     HPS      hpsFat;%@NL@%
  24168.     HDC      hdcFat;%@NL@%
  24169.     HBITMAP  hbmFat;%@NL@%
  24170.     HPS      hpsFatShadow;%@NL@%
  24171.     HDC      hdcFatShadow;%@NL@%
  24172.     HBITMAP  hbmFatShadow;%@NL@%
  24173. %@NL@%
  24174.     RECTL    rclFatBM;           %@AB@%/* dimensions of fatbits bitmap */%@AE@%%@NL@%
  24175.     RECTL    rclFat;           %@AB@%/* dimensions of active fat bits grid */%@AE@%%@NL@%
  24176.     LONG     cxFatPel;            %@AB@%/* width of fat pel */%@AE@%%@NL@%
  24177.     LONG     cyFatPel;            %@AB@%/* height of fat pel */%@AE@%%@NL@%
  24178.     LONG     cxHalfFatPel;%@NL@%
  24179.     LONG     cyHalfFatPel;%@NL@%
  24180.     USHORT   usPelShape;%@NL@%
  24181. %@NL@%
  24182.     MATRIXLF matlf;        %@AB@%/* goes from window coords to fatpel coords */%@AE@%%@NL@%
  24183. %@NL@%
  24184.     BOOL     fRGB;           %@AB@%/* TRUE --> color mode is RGB */%@AE@%%@NL@%
  24185.     COLOR    clrMathObj;%@NL@%
  24186.     COLOR    clrRenderedObj;%@NL@%
  24187.     COLOR    clrField;%@NL@%
  24188.     COLOR    clrCrossHair;%@NL@%
  24189.     COLOR    clrInterstice;%@NL@%
  24190.     COLOR    clrControlPoints;%@NL@%
  24191. %@NL@%
  24192.     COLOR    clrBlackIndex;%@NL@%
  24193.     COLOR    clrEditPel;%@NL@%
  24194. %@NL@%
  24195.     USHORT   usControlPointSymbol;%@NL@%
  24196. %@NL@%
  24197.     BOOL     fDisplayRenderedObj;%@NL@%
  24198.     BOOL     fDisplayMathObj;%@NL@%
  24199.     BOOL     fDisplayControlPoints;%@NL@%
  24200.     BOOL     fDisplayCrossHairs;%@NL@%
  24201.     BOOL     fDisplayPelBorder;%@NL@%
  24202.     BOOL     fRoundControlPoints;%@NL@%
  24203.     BOOL     fAutoRedraw;%@NL@%
  24204.     USHORT   usCurPrim;%@NL@%
  24205.     USHORT   usMix;%@NL@%
  24206. %@NL@%
  24207.     LONG     cptl;%@NL@%
  24208.     PPOINTL  pptl;%@NL@%
  24209.     PPOINTL  pptlTmp;%@NL@%
  24210. %@NL@%
  24211.     BOOL     fDraggingPelSize;%@NL@%
  24212.     HPOINTER hptrDragSize;%@NL@%
  24213. %@NL@%
  24214.     BOOL     fDraggingPelColor;%@NL@%
  24215.     HPOINTER hptrDragColor;%@NL@%
  24216. %@NL@%
  24217.     SHORT    sPtGrabbed;%@NL@%
  24218.     BOOL     fDraggingControlPoint;%@NL@%
  24219.     LONG     lHitPrecision;%@NL@%
  24220. %@NL@%
  24221.     BOOL     fEditPelColors;%@NL@%
  24222. %@NL@%
  24223. } GLOBALDATA;%@NL@%
  24224. GLOBALDATA global;%@NL@%
  24225. %@NL@%
  24226. %@NL@%
  24227. %@NL@%
  24228. %@NL@%
  24229. %@AB@%/************************************************************************%@NL@%
  24230. %@AB@%*%@NL@%
  24231. %@AB@%*   main%@NL@%
  24232. %@AB@%*%@NL@%
  24233. %@AB@%*   WinInitialize resizes our ring 2 stack, among other things, so%@NL@%
  24234. %@AB@%*   we won't GP fault trying to do graphics.  WinCreateMsgQueue defines%@NL@%
  24235. %@AB@%*   us as a REAL PM app. (WINDOWAPI in .DEF file does also).%@NL@%
  24236. %@AB@%*   Call a sub to register our window class and create a window.%@NL@%
  24237. %@AB@%*   Loop over messages.  Exit cleanly.%@NL@%
  24238. %@AB@%*%@NL@%
  24239. %@AB@%************************************************************************/%@AE@%%@NL@%
  24240. %@NL@%
  24241. VOID cdecl%@NL@%
  24242. main()%@NL@%
  24243. {%@NL@%
  24244.     QMSG qMsg;%@NL@%
  24245.     int iRet = 0;%@NL@%
  24246. %@NL@%
  24247. %@NL@%
  24248.     global.hab         = WinInitialize(0);%@NL@%
  24249.     global.hMsgQ = WinCreateMsgQueue(global.hab, 0);%@NL@%
  24250. %@NL@%
  24251.     if (InitApp())%@NL@%
  24252.         while (WinGetMsg( global.hab, (PQMSG)&qMsg, (HWND)NULL, 0, 0 ))%@NL@%
  24253.             WinDispatchMsg( global.hab, (PQMSG)&qMsg );%@NL@%
  24254.     else%@NL@%
  24255.         iRet = -1;%@NL@%
  24256. %@NL@%
  24257.     WinDestroyWindow( global.hwndFrame );%@NL@%
  24258.     WinDestroyMsgQueue( global.hMsgQ );%@NL@%
  24259.     WinTerminate( global.hab );%@NL@%
  24260.     DosExit(EXIT_PROCESS, iRet);%@NL@%
  24261. }%@NL@%
  24262. %@NL@%
  24263. %@NL@%
  24264. %@NL@%
  24265. %@NL@%
  24266. %@AB@%/****************************************************************************%@NL@%
  24267. %@AB@%*%@NL@%
  24268. %@AB@%*   InitGlobals%@NL@%
  24269. %@AB@%*%@NL@%
  24270. %@AB@%*   Initialize global variables.%@NL@%
  24271. %@AB@%*%@NL@%
  24272. %@AB@%****************************************************************************/%@AE@%%@NL@%
  24273. %@NL@%
  24274. BOOL FAR%@NL@%
  24275. InitGlobals()%@NL@%
  24276. {%@NL@%
  24277.     global.fFirstTime                 = TRUE;%@NL@%
  24278. %@NL@%
  24279.     global.rcl.xLeft                 = 0L;%@NL@%
  24280.     global.rcl.yBottom                 = 0L;%@NL@%
  24281.     global.rcl.xRight                 = 0L;%@NL@%
  24282.     global.rcl.yTop                 = 0L;%@NL@%
  24283. %@NL@%
  24284.     global.hpsFat                 = NULL;%@NL@%
  24285.     global.hdcFat                 = NULL;%@NL@%
  24286.     global.hbmFat                 = NULL;%@NL@%
  24287.     global.hpsFatShadow          = NULL;%@NL@%
  24288.     global.hdcFatShadow          = NULL;%@NL@%
  24289.     global.hbmFatShadow          = NULL;%@NL@%
  24290.     global.rclFatBM.xLeft         = 0L;%@NL@%
  24291.     global.rclFatBM.yBottom         = 0L;%@NL@%
  24292.     global.rclFatBM.xRight         = 0L;%@NL@%
  24293.     global.rclFatBM.yTop         = 0L;%@NL@%
  24294. %@NL@%
  24295.     global.cxFatPel                 = 32L;%@NL@%
  24296.     global.cyFatPel                 = 32L;%@NL@%
  24297.     global.cxHalfFatPel          = global.cxFatPel / 2L;%@NL@%
  24298.     global.cyHalfFatPel          = global.cyFatPel / 2L;%@NL@%
  24299.     global.usPelShape                 = IDD_CIRCLE;%@NL@%
  24300. %@NL@%
  24301.     global.fRGB                  = FALSE;%@NL@%
  24302.     global.clrMathObj                 = CLR_BLUE;%@NL@%
  24303.     global.clrRenderedObj         = CLR_NEUTRAL;%@NL@%
  24304.     global.clrField                 = CLR_CYAN;%@NL@%
  24305.     global.clrCrossHair          = CLR_DARKCYAN;%@NL@%
  24306.     global.clrInterstice         = CLR_BACKGROUND;%@NL@%
  24307.     global.clrControlPoints         = CLR_YELLOW;%@NL@%
  24308. %@NL@%
  24309.     global.clrBlackIndex         = CLR_ERROR;%@NL@%
  24310.     global.clrEditPel                 = CLR_ERROR;%@NL@%
  24311. %@NL@%
  24312.     global.usControlPointSymbol  = MARKSYM_SOLIDDIAMOND;%@NL@%
  24313. %@NL@%
  24314.     global.fDisplayRenderedObj         = TRUE;%@NL@%
  24315.     global.fDisplayMathObj         = TRUE;%@NL@%
  24316.     global.fDisplayControlPoints = TRUE;%@NL@%
  24317.     global.fDisplayCrossHairs         = TRUE;%@NL@%
  24318.     global.fDisplayPelBorder         = TRUE;%@NL@%
  24319.     global.fRoundControlPoints         = FALSE;%@NL@%
  24320.     global.fAutoRedraw                 = TRUE;%@NL@%
  24321.     global.usCurPrim                 = IDM_POLYLINE;%@NL@%
  24322.     global.usMix                 = FM_OVERPAINT;%@NL@%
  24323. %@NL@%
  24324.     global.fDraggingPelSize         = FALSE;%@NL@%
  24325.     global.fDraggingPelColor         = FALSE;%@NL@%
  24326.     global.fDraggingControlPoint = FALSE;%@NL@%
  24327.     global.sPtGrabbed                 = NO_POINT;%@NL@%
  24328.     global.lHitPrecision         = 0L;%@NL@%
  24329. %@NL@%
  24330.     global.fEditPelColors         = FALSE;%@NL@%
  24331. %@NL@%
  24332. %@NL@%
  24333.     global.cptl = 0L;%@NL@%
  24334.     global.pptl = NULL;%@NL@%
  24335.     if (DosAllocSeg(CPTLMAX * sizeof(POINTL),%@NL@%
  24336.                    ((PUSHORT)&global.pptl)+1, 0))%@NL@%
  24337.         return FALSE;%@NL@%
  24338.     global.pptlTmp = NULL;%@NL@%
  24339.     if (DosAllocSeg(CPTLMAX * sizeof(POINTL),%@NL@%
  24340.                    ((PUSHORT)&global.pptlTmp)+1, 0))%@NL@%
  24341.         return FALSE;%@NL@%
  24342. %@NL@%
  24343.     return TRUE;%@NL@%
  24344. }%@NL@%
  24345. %@NL@%
  24346. %@NL@%
  24347. %@NL@%
  24348. %@NL@%
  24349. %@AB@%/****************************************************************************%@NL@%
  24350. %@AB@%*%@NL@%
  24351. %@AB@%*   InitApp%@NL@%
  24352. %@AB@%*%@NL@%
  24353. %@AB@%*   Register application window class and creates standard window.%@NL@%
  24354. %@AB@%*%@NL@%
  24355. %@AB@%****************************************************************************/%@AE@%%@NL@%
  24356.          %@NL@%
  24357. %@AI@%#define %@AE@%INIT_MENU_ITEM(val, var)     \ %@NL@%
  24358.         TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var))%@NL@%
  24359. %@NL@%
  24360. BOOL FAR%@NL@%
  24361. InitApp()%@NL@%
  24362. {%@NL@%
  24363.     char szTitle[24];%@NL@%
  24364.     ULONG ctldata;%@NL@%
  24365.     PID pid;%@NL@%
  24366.     TID tid;%@NL@%
  24367.     HSWITCH hsw;%@NL@%
  24368.     static SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE,%@NL@%
  24369.                              SWL_JUMPABLE, "FatPels", 0 };%@NL@%
  24370. %@NL@%
  24371.     if (!InitGlobals())%@NL@%
  24372.         return FALSE;%@NL@%
  24373. %@NL@%
  24374. %@NL@%
  24375.     %@AB@%/*  Register Application Window Class  */%@AE@%%@NL@%
  24376. %@NL@%
  24377.     WinLoadString( global.hab, (HMODULE) NULL, IDS_TITLE, sizeof(szTitle), (PCH)szTitle );%@NL@%
  24378.     if ( !WinRegisterClass( global.hab, (PCH)szTitle, (PFNWP)WndProc,%@NL@%
  24379.             CS_SIZEREDRAW, 0 ))%@NL@%
  24380.         return FALSE;%@NL@%
  24381. %@NL@%
  24382. %@NL@%
  24383.     %@AB@%/* Load the pointer to use when dragging pel size. */%@AE@%%@NL@%
  24384.     if (!(global.hptrDragSize = WinLoadPointer( HWND_DESKTOP, (HMODULE) NULL, IDR_DRAGSIZEPTR )))%@NL@%
  24385.         return FALSE;%@NL@%
  24386. %@NL@%
  24387.     %@AB@%/* Load the pointer to use when dragging pel color. */%@AE@%%@NL@%
  24388.     if (!(global.hptrDragColor = WinLoadPointer( HWND_DESKTOP, (HMODULE) NULL, IDR_DRAGCOLORPTR )))%@NL@%
  24389.         return FALSE;%@NL@%
  24390. %@NL@%
  24391. %@NL@%
  24392.     %@AB@%/* Create a window instance of class "FatPel" */%@AE@%%@NL@%
  24393. %@NL@%
  24394.     ctldata = FCF_STANDARD &%@NL@%
  24395.      ~(ULONG)(FCF_ICON | FCF_ACCELTABLE | FCF_TASKLIST);%@NL@%
  24396. %@NL@%
  24397.     if (global.hwndFrame = WinCreateStdWindow(%@NL@%
  24398.         HWND_DESKTOP,                   %@AB@%/* specify desktop as parent window            */%@AE@%%@NL@%
  24399.         WS_VISIBLE,                   %@AB@%/* window styles                            */%@AE@%%@NL@%
  24400.         &ctldata,                   %@AB@%/* frame creation flags                    */%@AE@%%@NL@%
  24401.         (PCH)szTitle,                   %@AB@%/* window class name                     */%@AE@%%@NL@%
  24402.         (PCH)szTitle,                   %@AB@%/* name appearing in window caption            */%@AE@%%@NL@%
  24403.         0L,                           %@AB@%/*                                            */%@AE@%%@NL@%
  24404.         (HMODULE)NULL,                   %@AB@%/* use current executable module id            */%@AE@%%@NL@%
  24405.         IDR_FATPEL,                   %@AB@%/* menu id                                    */%@AE@%%@NL@%
  24406.         (HWND FAR *)&global.hwnd   %@AB@%/* window handle                            */%@AE@%%@NL@%
  24407.         ))%@NL@%
  24408.     {%@NL@%
  24409.         INIT_MENU_ITEM(IDM_RENDEREDOBJ,         global.fDisplayRenderedObj);%@NL@%
  24410.         INIT_MENU_ITEM(IDM_MATHOBJ,         global.fDisplayMathObj);%@NL@%
  24411.         INIT_MENU_ITEM(IDM_CTLPOINTS,         global.fDisplayControlPoints);%@NL@%
  24412.         INIT_MENU_ITEM(IDM_CROSSHAIRS,         global.fDisplayCrossHairs);%@NL@%
  24413.         INIT_MENU_ITEM(IDM_PELBORDER,         global.fDisplayPelBorder);%@NL@%
  24414.         INIT_MENU_ITEM(IDM_ROUNDPOINTS,         global.fRoundControlPoints);%@NL@%
  24415.         INIT_MENU_ITEM(IDM_AUTOREDRAW,         global.fAutoRedraw);%@NL@%
  24416.         INIT_MENU_ITEM(IDM_EDITPELCOLORS, global.fEditPelColors);%@NL@%
  24417. %@NL@%
  24418.         CHECK_MENU_ITEM(global.hwndFrame, global.usCurPrim);%@NL@%
  24419. %@NL@%
  24420. %@NL@%
  24421.         %@AB@%/* Add ourselves to the switch list. */%@AE@%%@NL@%
  24422. %@NL@%
  24423.         WinQueryWindowProcess(global.hwndFrame, &pid, &tid);%@NL@%
  24424.         swctl.hwnd        = global.hwndFrame;%@NL@%
  24425.         swctl.idProcess = pid;%@NL@%
  24426.         hsw = WinAddSwitchEntry(&swctl);%@NL@%
  24427. %@NL@%
  24428.         return TRUE;%@NL@%
  24429.     }%@NL@%
  24430.     return FALSE;%@NL@%
  24431. }%@NL@%
  24432. %@NL@%
  24433. %@NL@%
  24434. %@NL@%
  24435. %@NL@%
  24436. %@AB@%/*************************************************************************%@NL@%
  24437. %@AB@%*%@NL@%
  24438. %@AB@%*   WndProc%@NL@%
  24439. %@AB@%*%@NL@%
  24440. %@AB@%*   Process messages for the window class.%@NL@%
  24441. %@AB@%*%@NL@%
  24442. %@AB@%************************************************************************/%@AE@%%@NL@%
  24443. %@NL@%
  24444. ULONG CALLBACK%@NL@%
  24445. WndProc( hwnd, usMsg, mp1, mp2 )%@NL@%
  24446. HWND        hwnd;%@NL@%
  24447. USHORT        usMsg;%@NL@%
  24448. MPARAM  mp1;%@NL@%
  24449. MPARAM  mp2;%@NL@%
  24450. {%@NL@%
  24451.     switch (usMsg)%@NL@%
  24452.     {%@NL@%
  24453.     case WM_CLOSE:%@NL@%
  24454.         Close(hwnd);%@NL@%
  24455.         break;%@NL@%
  24456. %@NL@%
  24457.     case WM_COMMAND:%@NL@%
  24458.         Command(hwnd, LOUSHORT(mp1));%@NL@%
  24459.         break;%@NL@%
  24460. %@NL@%
  24461.     case WM_PAINT:%@NL@%
  24462.         {%@NL@%
  24463.             HPS   hps;%@NL@%
  24464. %@NL@%
  24465.             if (global.fFirstTime)%@NL@%
  24466.             {%@NL@%
  24467.                 SIZEF sizfx;%@NL@%
  24468. %@NL@%
  24469.                 hps = WinGetPS(hwnd);%@NL@%
  24470.                 GpiQueryMarkerBox(hps, &sizfx);%@NL@%
  24471.                 global.lHitPrecision = sizfx.cx / 0x20000L + 1L;%@NL@%
  24472.                 WinReleasePS(hps);%@NL@%
  24473. %@NL@%
  24474.                 UpdateSurfaceDims();%@NL@%
  24475.                 global.fFirstTime = FALSE;%@NL@%
  24476.             }%@NL@%
  24477. %@NL@%
  24478.             %@AB@%/* The small bitmap may have been resized since we last%@NL@%
  24479. %@AB@%             * painted, in which case it will have been initialized to%@NL@%
  24480. %@AB@%             * the field color.  Therefore, we will render the mathematical%@NL@%
  24481. %@AB@%             * object to make sure the right fatpels are there.%@NL@%
  24482. %@AB@%             */%@AE@%%@NL@%
  24483.             global.usMix = FM_OVERPAINT;%@NL@%
  24484.             hps = WinBeginPaint(global.hwnd, NULL, NULL);%@NL@%
  24485.             Paint(hps, CLEAR_BACKGROUND|RENDER_MATH_OBJ);%@NL@%
  24486.             WinEndPaint(hps);%@NL@%
  24487.         }%@NL@%
  24488.         break;%@NL@%
  24489. %@NL@%
  24490.     case WM_BUTTON1DOWN:%@NL@%
  24491.     case WM_BUTTON2DOWN:%@NL@%
  24492.         ButtonDown(hwnd, usMsg, mp1);%@NL@%
  24493.         break;%@NL@%
  24494. %@NL@%
  24495.     case WM_BUTTON1UP:%@NL@%
  24496.     case WM_BUTTON2UP:%@NL@%
  24497.         ButtonUp(hwnd, usMsg);%@NL@%
  24498.         break;%@NL@%
  24499. %@NL@%
  24500.     case WM_MOUSEMOVE:%@NL@%
  24501.         MouseMove(hwnd, mp1);%@NL@%
  24502.         break;%@NL@%
  24503. %@NL@%
  24504.     case WM_SIZE:%@NL@%
  24505.         UpdateSurfaceDims();%@NL@%
  24506.         return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));%@NL@%
  24507.         break;%@NL@%
  24508. %@NL@%
  24509.     default:%@NL@%
  24510.         return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));%@NL@%
  24511.         break;%@NL@%
  24512.     }%@NL@%
  24513. %@NL@%
  24514.     return FALSE;%@NL@%
  24515. }%@NL@%
  24516. %@NL@%
  24517. %@NL@%
  24518. %@NL@%
  24519. %@NL@%
  24520. %@AB@%/************************************************************************%@NL@%
  24521. %@AB@%*%@NL@%
  24522. %@AB@%*   MouseMove%@NL@%
  24523. %@AB@%*%@NL@%
  24524. %@AB@%************************************************************************/%@AE@%%@NL@%
  24525. %@NL@%
  24526. VOID%@NL@%
  24527. MouseMove(hwnd, mp1)%@NL@%
  24528. HWND hwnd;%@NL@%
  24529. MPARAM mp1;%@NL@%
  24530. {%@NL@%
  24531.     POINTL ptl;%@NL@%
  24532.     HPS hps;%@NL@%
  24533. %@NL@%
  24534. %@NL@%
  24535.     %@AB@%/* make sure we still have our pointer */%@AE@%%@NL@%
  24536.     %@AB@%/* notice the hierarchy of pointer modes */%@AE@%%@NL@%
  24537. %@NL@%
  24538.     if (global.fDraggingPelSize)%@NL@%
  24539.     {%@NL@%
  24540.         if (global.hptrDragSize)%@NL@%
  24541.             WinSetPointer(HWND_DESKTOP,global.hptrDragSize);%@NL@%
  24542.     }%@NL@%
  24543.     else if (global.fEditPelColors)%@NL@%
  24544.     {%@NL@%
  24545.         if (global.hptrDragColor)%@NL@%
  24546.             WinSetPointer(HWND_DESKTOP,global.hptrDragColor);%@NL@%
  24547.     }%@NL@%
  24548.     else%@NL@%
  24549.         WinSetPointer(HWND_DESKTOP,%@NL@%
  24550.                   WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,FALSE));%@NL@%
  24551. %@NL@%
  24552. %@NL@%
  24553.     if (global.fDraggingPelColor)%@NL@%
  24554.     {%@NL@%
  24555.         POINTL ptl, ptlFat;%@NL@%
  24556.         HPS hps;%@NL@%
  24557. %@NL@%
  24558. %@NL@%
  24559.         ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  24560.         ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  24561. %@NL@%
  24562.         %@AB@%/* letting the point go negative causes overflow errors */%@AE@%%@NL@%
  24563.         if (ptl.x < 0)%@NL@%
  24564.             ptl.x = 0;%@NL@%
  24565.         if (ptl.y < 0)%@NL@%
  24566.             ptl.y = 0;%@NL@%
  24567. %@NL@%
  24568.         GetFatPelFromPt(&ptl, &ptlFat);%@NL@%
  24569.         SetFatPel(&ptlFat, global.clrEditPel);%@NL@%
  24570. %@NL@%
  24571.         hps = WinGetPS(hwnd);%@NL@%
  24572.         Paint(hps, OVERRIDE_RENDERED_OBJ);%@NL@%
  24573.         Paint(hps, IGNORED);        %@AB@%/* this call just copies fatpels to the screen */%@AE@%%@NL@%
  24574.         WinReleasePS(hps);%@NL@%
  24575.     }%@NL@%
  24576.     else if (global.fDraggingControlPoint)%@NL@%
  24577.     {%@NL@%
  24578.         ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  24579.         ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  24580. %@NL@%
  24581.         %@AB@%/* letting the point go negative causes overflow errors */%@AE@%%@NL@%
  24582.         if (ptl.x < 0)%@NL@%
  24583.             ptl.x = 0;%@NL@%
  24584.         if (ptl.y < 0)%@NL@%
  24585.             ptl.y = 0;%@NL@%
  24586. %@NL@%
  24587.         if (global.sPtGrabbed != NO_POINT)%@NL@%
  24588.         {%@NL@%
  24589.             hps = WinGetPS(hwnd);%@NL@%
  24590.             Paint(hps, OVERRIDE_RENDERED_OBJ);%@NL@%
  24591. %@NL@%
  24592.             global.pptl[global.sPtGrabbed] = ptl;%@NL@%
  24593. %@NL@%
  24594.             Paint(hps, CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);%@NL@%
  24595.             WinReleasePS(hps);%@NL@%
  24596.         }%@NL@%
  24597.     }%@NL@%
  24598. }%@NL@%
  24599. %@NL@%
  24600. %@NL@%
  24601. %@NL@%
  24602. %@NL@%
  24603. %@AB@%/************************************************************************%@NL@%
  24604. %@AB@%*%@NL@%
  24605. %@AB@%*   ButtonUp%@NL@%
  24606. %@AB@%*%@NL@%
  24607. %@AB@%************************************************************************/%@AE@%%@NL@%
  24608. %@NL@%
  24609. VOID%@NL@%
  24610. ButtonUp(hwnd, usMsg)%@NL@%
  24611. HWND hwnd;%@NL@%
  24612. USHORT usMsg;%@NL@%
  24613. {%@NL@%
  24614.     SHORT i;%@NL@%
  24615.     HPS hps;%@NL@%
  24616. %@NL@%
  24617. %@NL@%
  24618.     if (global.fDraggingPelColor)%@NL@%
  24619.     {%@NL@%
  24620.         global.fDraggingPelColor = FALSE;%@NL@%
  24621.         WinSetCapture(HWND_DESKTOP, NULL);%@NL@%
  24622.     }%@NL@%
  24623.     else if (global.fDraggingControlPoint)%@NL@%
  24624.     {%@NL@%
  24625.         global.fDraggingControlPoint = FALSE;%@NL@%
  24626.         WinSetCapture(HWND_DESKTOP, NULL);%@NL@%
  24627.         if (global.sPtGrabbed != NO_POINT)%@NL@%
  24628.         {%@NL@%
  24629.             if (usMsg == WM_BUTTON2UP)        %@AB@%/* remove point? */%@AE@%%@NL@%
  24630.             {%@NL@%
  24631.                 hps = WinGetPS(hwnd);%@NL@%
  24632.                 Paint(hps, OVERRIDE_RENDERED_OBJ);%@NL@%
  24633. %@NL@%
  24634.                 %@AB@%/* squeeze out selected point */%@AE@%%@NL@%
  24635.                 if ((i = global.sPtGrabbed) < (SHORT)(global.cptl-1))%@NL@%
  24636.                     while (i < (SHORT)(global.cptl-1))%@NL@%
  24637.                     {%@NL@%
  24638.                         global.pptl[i] = global.pptl[i+1];%@NL@%
  24639.                         ++i;%@NL@%
  24640.                     }%@NL@%
  24641. %@NL@%
  24642.                 --global.cptl;%@NL@%
  24643.                 global.sPtGrabbed = NO_POINT;%@NL@%
  24644. %@NL@%
  24645.                 Paint(hps, CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);%@NL@%
  24646.                 WinReleasePS(hps);%@NL@%
  24647.             }%@NL@%
  24648.             else    %@AB@%/* WM_BUTTON1UP */%@AE@%%@NL@%
  24649.                 global.sPtGrabbed = NO_POINT;%@NL@%
  24650.         }%@NL@%
  24651.     }%@NL@%
  24652. }%@NL@%
  24653. %@NL@%
  24654. %@NL@%
  24655. %@NL@%
  24656. %@NL@%
  24657. %@AB@%/************************************************************************%@NL@%
  24658. %@AB@%*%@NL@%
  24659. %@AB@%*   ButtonDown%@NL@%
  24660. %@AB@%*%@NL@%
  24661. %@AB@%************************************************************************/%@AE@%%@NL@%
  24662. %@NL@%
  24663. VOID%@NL@%
  24664. ButtonDown(hwnd, usMsg, mp1)%@NL@%
  24665. HWND hwnd;%@NL@%
  24666. USHORT usMsg;%@NL@%
  24667. MPARAM mp1;%@NL@%
  24668. {%@NL@%
  24669.     if (global.fDraggingPelSize)%@NL@%
  24670.     {%@NL@%
  24671.         POINTS pt;%@NL@%
  24672.         HPS hps;%@NL@%
  24673. %@NL@%
  24674.         pt.x = LOUSHORT(mp1);%@NL@%
  24675.         pt.y = HIUSHORT(mp1);%@NL@%
  24676.         DragPelSize(hwnd, pt);%@NL@%
  24677.         global.fDraggingPelSize = FALSE;%@NL@%
  24678. %@NL@%
  24679.         WinSetPointer(HWND_DESKTOP,%@NL@%
  24680.                       WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,FALSE));%@NL@%
  24681. %@NL@%
  24682.         hps = WinGetPS(hwnd);%@NL@%
  24683.         global.usMix = FM_OVERPAINT;%@NL@%
  24684.         Paint(hps, CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);%@NL@%
  24685.         WinReleasePS(hps);%@NL@%
  24686.     }%@NL@%
  24687.     else if (global.fEditPelColors)%@NL@%
  24688.     {%@NL@%
  24689.         POINTL ptl, ptlFat;%@NL@%
  24690.         HPS hps;%@NL@%
  24691. %@NL@%
  24692.         global.fDraggingPelColor = TRUE;%@NL@%
  24693.         WinSetCapture(HWND_DESKTOP, hwnd);%@NL@%
  24694. %@NL@%
  24695.         ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  24696.         ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  24697. %@NL@%
  24698.         if (global.usMix != FM_XOR)%@NL@%
  24699.         {%@NL@%
  24700.             hps = WinGetPS(hwnd);%@NL@%
  24701.             global.usMix = FM_XOR;%@NL@%
  24702.             Paint(hps, CLEAR_BACKGROUND);%@NL@%
  24703.             WinReleasePS(hps);%@NL@%
  24704.         }%@NL@%
  24705. %@NL@%
  24706.         if (usMsg == WM_BUTTON1DOWN)%@NL@%
  24707.             global.clrEditPel = global.clrRenderedObj;%@NL@%
  24708.         else%@NL@%
  24709.             global.clrEditPel = global.clrField;%@NL@%
  24710. %@NL@%
  24711.         GetFatPelFromPt(&ptl, &ptlFat);%@NL@%
  24712.         SetFatPel(&ptlFat, global.clrEditPel);%@NL@%
  24713. %@NL@%
  24714.         hps = WinGetPS(hwnd);%@NL@%
  24715.         Paint(hps, OVERRIDE_RENDERED_OBJ);%@NL@%
  24716.         Paint(hps, IGNORED);        %@AB@%/* this call just copies fatpels to the screen */%@AE@%%@NL@%
  24717.         WinReleasePS(hps);%@NL@%
  24718.     }%@NL@%
  24719.     else if (!global.fDraggingControlPoint)%@NL@%
  24720.     {%@NL@%
  24721.         POINTL ptl;%@NL@%
  24722.         SHORT sNewPtGrabbed;%@NL@%
  24723.         HPS hps;%@NL@%
  24724. %@NL@%
  24725.         global.fDraggingControlPoint = TRUE;%@NL@%
  24726.         WinSetCapture(HWND_DESKTOP, hwnd);%@NL@%
  24727. %@NL@%
  24728.         ptl.x = (LONG) LOUSHORT(mp1);%@NL@%
  24729.         ptl.y = (LONG) HIUSHORT(mp1);%@NL@%
  24730. %@NL@%
  24731.         sNewPtGrabbed = IsPtInList(&ptl);%@NL@%
  24732. %@NL@%
  24733.         if (global.usMix != FM_XOR)%@NL@%
  24734.         {%@NL@%
  24735.             hps = WinGetPS(hwnd);%@NL@%
  24736.             global.usMix = FM_XOR;%@NL@%
  24737.             Paint(hps, CLEAR_BACKGROUND);%@NL@%
  24738.             WinReleasePS(hps);%@NL@%
  24739.         }%@NL@%
  24740. %@NL@%
  24741.         if (usMsg == WM_BUTTON1DOWN)        %@AB@%/* add/move point? */%@AE@%%@NL@%
  24742.         {%@NL@%
  24743.             hps = WinGetPS(hwnd);%@NL@%
  24744. %@NL@%
  24745.             if (sNewPtGrabbed != NO_POINT)%@NL@%
  24746.                 global.sPtGrabbed = sNewPtGrabbed;%@NL@%
  24747.             Paint(hps, OVERRIDE_RENDERED_OBJ);%@NL@%
  24748. %@NL@%
  24749.             if (sNewPtGrabbed == NO_POINT)%@NL@%
  24750.                 global.sPtGrabbed = AddPtToList(&ptl);%@NL@%
  24751.             else%@NL@%
  24752.                 global.sPtGrabbed = sNewPtGrabbed;%@NL@%
  24753. %@NL@%
  24754.             Paint(hps, CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);%@NL@%
  24755.             WinReleasePS(hps);%@NL@%
  24756. %@NL@%
  24757.             if (global.sPtGrabbed == NO_POINT)%@NL@%
  24758.                 MyMessageBox(global.hwnd, "Cannot add any more points.");%@NL@%
  24759.         }%@NL@%
  24760.         else if (sNewPtGrabbed != NO_POINT)%@NL@%
  24761.             global.sPtGrabbed = sNewPtGrabbed;%@NL@%
  24762.     }%@NL@%
  24763. }%@NL@%
  24764. %@NL@%
  24765. %@NL@%
  24766. %@NL@%
  24767. %@NL@%
  24768. %@AB@%/************************************************************************%@NL@%
  24769. %@AB@%*%@NL@%
  24770. %@AB@%*   GetFatPelFromPt%@NL@%
  24771. %@AB@%*%@NL@%
  24772. %@AB@%************************************************************************/%@AE@%%@NL@%
  24773. %@NL@%
  24774. VOID%@NL@%
  24775. GetFatPelFromPt(pptl, pptlFat)%@NL@%
  24776. PPOINTL pptl;%@NL@%
  24777. PPOINTL pptlFat;%@NL@%
  24778. {%@NL@%
  24779.     pptlFat->x = pptl->x / global.cxFatPel;%@NL@%
  24780.     pptlFat->y = pptl->y / global.cyFatPel;%@NL@%
  24781. }%@NL@%
  24782. %@NL@%
  24783. %@NL@%
  24784. %@NL@%
  24785. %@NL@%
  24786. %@AB@%/************************************************************************%@NL@%
  24787. %@AB@%*%@NL@%
  24788. %@AB@%*   SetFatPel%@NL@%
  24789. %@AB@%*%@NL@%
  24790. %@AB@%************************************************************************/%@AE@%%@NL@%
  24791. %@NL@%
  24792. VOID%@NL@%
  24793. SetFatPel(pptl, clr)%@NL@%
  24794. PPOINTL pptl;%@NL@%
  24795. COLOR clr;%@NL@%
  24796. {%@NL@%
  24797.     LINEBUNDLE lb;%@NL@%
  24798. %@NL@%
  24799.     if (global.hpsFat)%@NL@%
  24800.     {%@NL@%
  24801.         lb.lColor = clr;%@NL@%
  24802.         GpiSetAttrs(global.hpsFat, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  24803.         GpiSetPel(global.hpsFat, pptl);%@NL@%
  24804.     }%@NL@%
  24805. }%@NL@%
  24806. %@NL@%
  24807. %@NL@%
  24808. %@NL@%
  24809. %@NL@%
  24810. %@AB@%/************************************************************************%@NL@%
  24811. %@AB@%*%@NL@%
  24812. %@AB@%*   IsPtInList%@NL@%
  24813. %@AB@%*%@NL@%
  24814. %@AB@%************************************************************************/%@AE@%%@NL@%
  24815. %@NL@%
  24816. SHORT%@NL@%
  24817. IsPtInList(pptl)%@NL@%
  24818. PPOINTL pptl;%@NL@%
  24819. {%@NL@%
  24820.     SHORT i;%@NL@%
  24821. %@NL@%
  24822. %@NL@%
  24823.     %@AB@%/* try to find pptl in the points we already have */%@AE@%%@NL@%
  24824.     for (i = 0; i < (SHORT)global.cptl; ++i)%@NL@%
  24825.         if (((L_ABS(pptl->x - global.pptl[i].x)) <= global.lHitPrecision) &&%@NL@%
  24826.             ((L_ABS(pptl->y - global.pptl[i].y)) <= global.lHitPrecision))%@NL@%
  24827.                 return i;%@NL@%
  24828. %@NL@%
  24829.     %@AB@%/* couldn't find it */%@AE@%%@NL@%
  24830.     return NO_POINT;%@NL@%
  24831. }%@NL@%
  24832. %@NL@%
  24833. %@NL@%
  24834. %@NL@%
  24835. %@NL@%
  24836. %@AB@%/************************************************************************%@NL@%
  24837. %@AB@%*%@NL@%
  24838. %@AB@%*   AddPtToList%@NL@%
  24839. %@AB@%*%@NL@%
  24840. %@AB@%************************************************************************/%@AE@%%@NL@%
  24841. %@NL@%
  24842. SHORT%@NL@%
  24843. AddPtToList(pptl)%@NL@%
  24844. PPOINTL pptl;%@NL@%
  24845. {%@NL@%
  24846.     SHORT i, j;%@NL@%
  24847. %@NL@%
  24848.     if (global.cptl < CPTLMAX)%@NL@%
  24849.     {%@NL@%
  24850.         %@AB@%/* check for new points lying on a line segment */%@AE@%%@NL@%
  24851.         for (i = 0; i < (SHORT)(global.cptl-1L); ++i)%@NL@%
  24852.             if (IsPtCloseToLine(&global.pptl[i], &global.pptl[i+1], pptl))%@NL@%
  24853.             {%@NL@%
  24854.                 %@AB@%/* insert point between endpoints of nearest line segment */%@AE@%%@NL@%
  24855.                 for (j = (SHORT)global.cptl; j > i+1; --j)%@NL@%
  24856.                     global.pptl[j] = global.pptl[j - 1];%@NL@%
  24857.                 global.pptl[i+1] = *pptl;%@NL@%
  24858.                 ++global.cptl;%@NL@%
  24859.                 return i+1;%@NL@%
  24860.             }%@NL@%
  24861. %@NL@%
  24862.         %@AB@%/* append the point */%@AE@%%@NL@%
  24863. %@NL@%
  24864.         i = (SHORT) global.cptl;%@NL@%
  24865.         global.pptl[i] = *pptl;%@NL@%
  24866.         ++global.cptl;%@NL@%
  24867.         return i;%@NL@%
  24868.     }%@NL@%
  24869. %@NL@%
  24870.     return NO_POINT;%@NL@%
  24871. }%@NL@%
  24872. %@NL@%
  24873. %@NL@%
  24874. %@NL@%
  24875. %@NL@%
  24876. %@AB@%/************************************************************************%@NL@%
  24877. %@AB@%*%@NL@%
  24878. %@AB@%*   IsPtCloseToLine%@NL@%
  24879. %@AB@%*%@NL@%
  24880. %@AB@%************************************************************************/%@AE@%%@NL@%
  24881. %@NL@%
  24882. BOOL%@NL@%
  24883. IsPtCloseToLine(pptl1, pptl2, pptlTest)%@NL@%
  24884. PPOINTL pptl1;%@NL@%
  24885. PPOINTL pptl2;%@NL@%
  24886. PPOINTL pptlTest;%@NL@%
  24887. {%@NL@%
  24888.     POINTL ptlLL, ptlUR;%@NL@%
  24889.     LONG dx, dy, yIntercept, error;%@NL@%
  24890.     LONG lBoxAdjustment;%@NL@%
  24891. %@NL@%
  24892. %@NL@%
  24893.     %@AB@%/* find the bounding box of the line segment */%@AE@%%@NL@%
  24894. %@NL@%
  24895.     ptlLL = *pptl1;        %@AB@%/* assume line goes lower left to upper right */%@AE@%%@NL@%
  24896.     ptlUR = *pptl2;%@NL@%
  24897.     if (pptl1->x > pptl2->x)%@NL@%
  24898.         SwapLong(&ptlLL.x, &ptlUR.x);%@NL@%
  24899.     if (pptl1->y > pptl2->y)%@NL@%
  24900.         SwapLong(&ptlLL.y, &ptlUR.y);%@NL@%
  24901. %@NL@%
  24902. %@NL@%
  24903.     %@AB@%/* adjust the bounding box if it's too narrow */%@AE@%%@NL@%
  24904. %@NL@%
  24905.     lBoxAdjustment = global.lHitPrecision/2L;%@NL@%
  24906. %@NL@%
  24907.     dx = pptl2->x - pptl1->x;%@NL@%
  24908.     if (L_ABS(dx) <= global.lHitPrecision)%@NL@%
  24909.     {%@NL@%
  24910.         ptlLL.x -= lBoxAdjustment;%@NL@%
  24911.         ptlUR.x += lBoxAdjustment;%@NL@%
  24912.     }%@NL@%
  24913.     dy = pptl2->y - pptl1->y;%@NL@%
  24914.     if (L_ABS(dy) <= global.lHitPrecision)%@NL@%
  24915.     {%@NL@%
  24916.         ptlLL.y -= lBoxAdjustment;%@NL@%
  24917.         ptlUR.y += lBoxAdjustment;%@NL@%
  24918.     }%@NL@%
  24919. %@NL@%
  24920. %@NL@%
  24921.     %@AB@%/* see if the test point is in the bounding box of the line segment */%@AE@%%@NL@%
  24922. %@NL@%
  24923.     if ((pptlTest->x >= ptlLL.x) &&%@NL@%
  24924.         (pptlTest->x <= ptlUR.x) &&%@NL@%
  24925.         (pptlTest->y >= ptlLL.y) &&%@NL@%
  24926.         (pptlTest->y <= ptlUR.y))%@NL@%
  24927.     {%@NL@%
  24928.         %@AB@%/* test for special cases */%@AE@%%@NL@%
  24929. %@NL@%
  24930.         if (dx == 0)        %@AB@%/* vertical line */%@AE@%%@NL@%
  24931.         {%@NL@%
  24932.             return (L_ABS(pptlTest->x - pptl1->x) <= global.lHitPrecision);%@NL@%
  24933.         }%@NL@%
  24934. %@NL@%
  24935.         if (dy == 0)        %@AB@%/* horizontal line */%@AE@%%@NL@%
  24936.         {%@NL@%
  24937.             return (L_ABS(pptlTest->y - pptl1->y) <= global.lHitPrecision);%@NL@%
  24938.         }%@NL@%
  24939. %@NL@%
  24940. %@NL@%
  24941.         %@AB@%/* test for general case */%@AE@%%@NL@%
  24942. %@NL@%
  24943.         yIntercept = pptl1->y - (pptl1->x * dy) / dx;%@NL@%
  24944. %@NL@%
  24945.         error = pptlTest->y - (pptlTest->x * dy / dx) - yIntercept;%@NL@%
  24946.         if (L_ABS(error) <= global.lHitPrecision)%@NL@%
  24947.             return TRUE;%@NL@%
  24948.     }%@NL@%
  24949. %@NL@%
  24950.     return FALSE;%@NL@%
  24951. }%@NL@%
  24952. %@NL@%
  24953. %@NL@%
  24954. %@NL@%
  24955. %@NL@%
  24956. %@AB@%/************************************************************************%@NL@%
  24957. %@AB@%*%@NL@%
  24958. %@AB@%*   SwapLong%@NL@%
  24959. %@AB@%*%@NL@%
  24960. %@AB@%************************************************************************/%@AE@%%@NL@%
  24961. %@NL@%
  24962. VOID%@NL@%
  24963. SwapLong(pl1, pl2)%@NL@%
  24964. PLONG pl1, pl2;%@NL@%
  24965. {%@NL@%
  24966.     LONG lTmp;%@NL@%
  24967. %@NL@%
  24968.     lTmp = *pl1;%@NL@%
  24969.     *pl1 = *pl2;%@NL@%
  24970.     *pl2 = lTmp;%@NL@%
  24971. }%@NL@%
  24972. %@NL@%
  24973. %@NL@%
  24974. %@NL@%
  24975. %@NL@%
  24976. %@AB@%/************************************************************************%@NL@%
  24977. %@AB@%*%@NL@%
  24978. %@AB@%*   DragPelSize%@NL@%
  24979. %@AB@%*%@NL@%
  24980. %@AB@%*   Set the dimensions of a fat pel by dragging a rectangle%@NL@%
  24981. %@AB@%*   on the screen.%@NL@%
  24982. %@AB@%*%@NL@%
  24983. %@AB@%************************************************************************/%@AE@%%@NL@%
  24984. %@NL@%
  24985. VOID%@NL@%
  24986. DragPelSize(hwnd, pt)%@NL@%
  24987. HWND hwnd;%@NL@%
  24988. POINTS pt;%@NL@%
  24989. {%@NL@%
  24990.     TRACKINFO ti;%@NL@%
  24991. %@NL@%
  24992.     WinSendMsg(global.hwndFrame, WM_QUERYTRACKINFO, (MPARAM)TF_MOVE, (MPARAM)&ti);%@NL@%
  24993. %@NL@%
  24994.     ti.cxBorder   = 1;%@NL@%
  24995.     ti.cyBorder   = 1;%@NL@%
  24996.     ti.rclTrack.xLeft        = (LONG)pt.x;%@NL@%
  24997.     ti.rclTrack.yBottom = (LONG)pt.y;%@NL@%
  24998.     ti.rclTrack.xRight        = (LONG)pt.x;%@NL@%
  24999.     ti.rclTrack.yTop        = (LONG)pt.y;%@NL@%
  25000.     ti.fs = TF_RIGHT | TF_TOP;%@NL@%
  25001.     ti.ptlMinTrackSize.x = 1L;%@NL@%
  25002.     ti.ptlMinTrackSize.y = 1L;%@NL@%
  25003. %@NL@%
  25004.     if (WinTrackRect(hwnd, NULL, &ti))%@NL@%
  25005.     {%@NL@%
  25006.         global.cxFatPel = (ti.rclTrack.xRight - ti.rclTrack.xLeft)  ;%@NL@%
  25007.         global.cyFatPel = (ti.rclTrack.yTop   - ti.rclTrack.yBottom);%@NL@%
  25008. %@NL@%
  25009.         if (global.cxFatPel < 1L)%@NL@%
  25010.             global.cxFatPel = 1L;%@NL@%
  25011. %@NL@%
  25012.         if (global.cyFatPel < 1L)%@NL@%
  25013.             global.cyFatPel = 1L;%@NL@%
  25014. %@NL@%
  25015.         global.cxHalfFatPel = global.cxFatPel / 2L;%@NL@%
  25016.         global.cyHalfFatPel = global.cyFatPel / 2L;%@NL@%
  25017. %@NL@%
  25018.         UpdateSurfaceDims();%@NL@%
  25019.     }%@NL@%
  25020. }%@NL@%
  25021. %@NL@%
  25022. %@NL@%
  25023. %@NL@%
  25024. %@NL@%
  25025. %@AB@%/************************************************************************%@NL@%
  25026. %@AB@%*%@NL@%
  25027. %@AB@%*   Close%@NL@%
  25028. %@AB@%*%@NL@%
  25029. %@AB@%************************************************************************/%@AE@%%@NL@%
  25030. %@NL@%
  25031. VOID%@NL@%
  25032. Close(hwnd)%@NL@%
  25033. HWND hwnd;%@NL@%
  25034. {%@NL@%
  25035.     if (global.hptrDragSize)%@NL@%
  25036.         WinDestroyPointer(global.hptrDragSize);%@NL@%
  25037.     WinPostMsg(hwnd, WM_QUIT, 0L, 0L);%@NL@%
  25038. }%@NL@%
  25039. %@NL@%
  25040. %@NL@%
  25041. %@NL@%
  25042. %@NL@%
  25043. %@AB@%/************************************************************************%@NL@%
  25044. %@AB@%*%@NL@%
  25045. %@AB@%*   Command%@NL@%
  25046. %@AB@%*%@NL@%
  25047. %@AB@%*   Dispatches menu commands to the proper handlers.%@NL@%
  25048. %@AB@%*%@NL@%
  25049. %@AB@%************************************************************************/%@AE@%%@NL@%
  25050.                    %@NL@%
  25051. %@AI@%#define %@AE@%UPDATE_MENU_BOOL(var, val)                                \ %@NL@%
  25052.         {                                                        \%@NL@%
  25053.             TOGGLE_BOOL((var));                                 \%@NL@%
  25054.             TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var));        \%@NL@%
  25055.         }%@NL@%
  25056. %@NL@%
  25057. %@AI@%#define %@AE@%UPDATE_MENU_LIST(var, val)                                \ %@NL@%
  25058.         {                                                        \%@NL@%
  25059.             UNCHECK_MENU_ITEM(global.hwndFrame, (var));         \%@NL@%
  25060.             (var) = (val);                                        \%@NL@%
  25061.             CHECK_MENU_ITEM(global.hwndFrame, (var));                \%@NL@%
  25062.         }%@NL@%
  25063. %@NL@%
  25064. VOID%@NL@%
  25065. Command(hwnd, id)%@NL@%
  25066. HWND hwnd;%@NL@%
  25067. USHORT id;%@NL@%
  25068. {%@NL@%
  25069.     BOOL fRedraw = FALSE;%@NL@%
  25070.     USHORT fsCmd = IGNORED;%@NL@%
  25071. %@NL@%
  25072. %@NL@%
  25073.     switch (id)%@NL@%
  25074.     {%@NL@%
  25075.     case IDM_SAVE:%@NL@%
  25076.         SaveWindowToFile(hwnd);%@NL@%
  25077.         break;%@NL@%
  25078. %@NL@%
  25079.     case IDM_ABOUT:%@NL@%
  25080.         WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)AboutDlg, (HMODULE) NULL,%@NL@%
  25081.                        IDR_ABOUTDLG, NULL );%@NL@%
  25082.         break;%@NL@%
  25083. %@NL@%
  25084.     case IDM_REDRAW:%@NL@%
  25085.         fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;%@NL@%
  25086.         break;%@NL@%
  25087. %@NL@%
  25088.     case IDM_SETPELSIZE:%@NL@%
  25089.         {%@NL@%
  25090.             LONG cxFatPel, cyFatPel;%@NL@%
  25091. %@NL@%
  25092.             cxFatPel = global.cxFatPel;%@NL@%
  25093.             cyFatPel = global.cyFatPel;%@NL@%
  25094. %@NL@%
  25095.             if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)PelSizeDlg, (HMODULE) NULL,%@NL@%
  25096.                            IDR_PELSIZEDLG, NULL ))%@NL@%
  25097.             {%@NL@%
  25098.                 if ((cxFatPel == global.cxFatPel) &&%@NL@%
  25099.                     (cyFatPel == global.cyFatPel))%@NL@%
  25100.                     fsCmd = CLEAR_BACKGROUND;%@NL@%
  25101.                 else%@NL@%
  25102.                     fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;%@NL@%
  25103.                 fRedraw = TRUE;%@NL@%
  25104.             }%@NL@%
  25105.         }%@NL@%
  25106.         break;%@NL@%
  25107. %@NL@%
  25108.     case IDM_DRAGPELSIZE:%@NL@%
  25109.         global.fDraggingPelSize = TRUE;%@NL@%
  25110.         break;%@NL@%
  25111. %@NL@%
  25112.     case IDM_RENDEREDOBJ:%@NL@%
  25113.         UPDATE_MENU_BOOL(global.fDisplayRenderedObj, IDM_RENDEREDOBJ);%@NL@%
  25114.         fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;%@NL@%
  25115.         fRedraw = TRUE;%@NL@%
  25116.         break;%@NL@%
  25117. %@NL@%
  25118.     case IDM_MATHOBJ:%@NL@%
  25119.         UPDATE_MENU_BOOL(global.fDisplayMathObj, IDM_MATHOBJ);%@NL@%
  25120.         fsCmd = CLEAR_BACKGROUND;%@NL@%
  25121.         fRedraw = TRUE;%@NL@%
  25122.         break;%@NL@%
  25123. %@NL@%
  25124.     case IDM_CTLPOINTS:%@NL@%
  25125.         UPDATE_MENU_BOOL(global.fDisplayControlPoints, IDM_CTLPOINTS);%@NL@%
  25126.         fsCmd = CLEAR_BACKGROUND;%@NL@%
  25127.         fRedraw = TRUE;%@NL@%
  25128.         break;%@NL@%
  25129. %@NL@%
  25130.     case IDM_CROSSHAIRS:%@NL@%
  25131.         UPDATE_MENU_BOOL(global.fDisplayCrossHairs, IDM_CROSSHAIRS);%@NL@%
  25132.         fsCmd = CLEAR_BACKGROUND;%@NL@%
  25133.         fRedraw = TRUE;%@NL@%
  25134.         break;%@NL@%
  25135. %@NL@%
  25136.     case IDM_PELBORDER:%@NL@%
  25137.         UPDATE_MENU_BOOL(global.fDisplayPelBorder, IDM_PELBORDER);%@NL@%
  25138.         fsCmd = CLEAR_BACKGROUND;%@NL@%
  25139.         fRedraw = TRUE;%@NL@%
  25140.         break;%@NL@%
  25141. %@NL@%
  25142.     case IDM_ROUNDPOINTS:%@NL@%
  25143.         UPDATE_MENU_BOOL(global.fRoundControlPoints, IDM_ROUNDPOINTS);%@NL@%
  25144.         fsCmd = CLEAR_BACKGROUND;%@NL@%
  25145.         fRedraw = TRUE;%@NL@%
  25146.         break;%@NL@%
  25147. %@NL@%
  25148.     case IDM_AUTOREDRAW:%@NL@%
  25149.         UPDATE_MENU_BOOL(global.fAutoRedraw, IDM_AUTOREDRAW);%@NL@%
  25150.         break;%@NL@%
  25151. %@NL@%
  25152.     case IDM_NOPRIM:%@NL@%
  25153.     case IDM_POLYLINE:%@NL@%
  25154.     case IDM_POLYFILLET:%@NL@%
  25155.     case IDM_POLYSPLINE:%@NL@%
  25156.     case IDM_POINTARC:%@NL@%
  25157.         UPDATE_MENU_LIST(global.usCurPrim, id);%@NL@%
  25158.         fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;%@NL@%
  25159.         fRedraw = TRUE;%@NL@%
  25160.         break;%@NL@%
  25161. %@NL@%
  25162.     case IDM_SETCOLORS:%@NL@%
  25163.         if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)ColorsDlg, (HMODULE) NULL,%@NL@%
  25164.                        IDR_COLORSDLG, NULL ))%@NL@%
  25165.         {%@NL@%
  25166.             fsCmd = CLEAR_BACKGROUND|RENDER_MATH_OBJ;%@NL@%
  25167.             fRedraw = TRUE;%@NL@%
  25168.         }%@NL@%
  25169.         break;%@NL@%
  25170. %@NL@%
  25171.     case IDM_EDITPELCOLORS:%@NL@%
  25172.         UPDATE_MENU_BOOL(global.fEditPelColors, IDM_EDITPELCOLORS);%@NL@%
  25173.         break;%@NL@%
  25174. %@NL@%
  25175.     case IDM_CLEARALL:%@NL@%
  25176.         global.cptl = 0L;%@NL@%
  25177.         fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;%@NL@%
  25178.         fRedraw = TRUE;%@NL@%
  25179.         break;%@NL@%
  25180.     }%@NL@%
  25181. %@NL@%
  25182.     if ((global.fAutoRedraw && fRedraw) || (id == IDM_REDRAW))%@NL@%
  25183.     {%@NL@%
  25184.         HPS hps;%@NL@%
  25185. %@NL@%
  25186.         hps = WinGetPS(hwnd);%@NL@%
  25187.         global.usMix = FM_OVERPAINT;%@NL@%
  25188.         Paint(hps, fsCmd);%@NL@%
  25189.         WinReleasePS(hps);%@NL@%
  25190.     }%@NL@%
  25191. }%@NL@%
  25192. %@NL@%
  25193. %@NL@%
  25194. %@NL@%
  25195. %@NL@%
  25196. %@AB@%/************************************************************************%@NL@%
  25197. %@AB@%*%@NL@%
  25198. %@AB@%*   Paint%@NL@%
  25199. %@AB@%*%@NL@%
  25200. %@AB@%************************************************************************/%@AE@%%@NL@%
  25201. %@NL@%
  25202. VOID%@NL@%
  25203. Paint(hps, fsCmd)%@NL@%
  25204. HPS  hps;%@NL@%
  25205. USHORT fsCmd;%@NL@%
  25206. {%@NL@%
  25207.     HRGN hrgn, hrgnClipOld, hrgnT;%@NL@%
  25208. %@NL@%
  25209. %@NL@%
  25210.     %@AB@%/* Clear the unused part of the client rectangle to a hatch pattern. */%@AE@%%@NL@%
  25211.     if (fsCmd & CLEAR_BACKGROUND)%@NL@%
  25212.         EraseBackground(hps);%@NL@%
  25213. %@NL@%
  25214. %@NL@%
  25215.     %@AB@%/* Set up the color mode as the user has requested */%@AE@%%@NL@%
  25216. %@NL@%
  25217.     if (global.fRGB)%@NL@%
  25218.     {%@NL@%
  25219.         GpiCreateLogColorTable(hps, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL);%@NL@%
  25220.         if (global.hpsFat)%@NL@%
  25221.         {%@NL@%
  25222.             GpiCreateLogColorTable(global.hpsFat, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL);%@NL@%
  25223.             GpiCreateLogColorTable(global.hpsFatShadow, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL);%@NL@%
  25224.         }%@NL@%
  25225.     }%@NL@%
  25226.     else%@NL@%
  25227.         if (global.hpsFat)%@NL@%
  25228.         {%@NL@%
  25229.             GpiCreateLogColorTable(global.hpsFat, LCOL_RESET, LCOLF_INDRGB, 0L, 0L, NULL);%@NL@%
  25230.             GpiCreateLogColorTable(global.hpsFatShadow, LCOL_RESET, LCOLF_INDRGB, 0L, 0L, NULL);%@NL@%
  25231.             global.clrBlackIndex = GpiQueryColorIndex(hps, 0L, 0x000000L);%@NL@%
  25232.         }%@NL@%
  25233. %@NL@%
  25234. %@NL@%
  25235.     if (global.usPelShape == IDD_CIRCLE)%@NL@%
  25236.     {%@NL@%
  25237.         ARCPARAMS arcp;%@NL@%
  25238. %@NL@%
  25239.         arcp.lP = global.cxFatPel / 2L;%@NL@%
  25240.         arcp.lQ = global.cyFatPel / 2L;%@NL@%
  25241.         arcp.lR = 0L;%@NL@%
  25242.         arcp.lS = 0L;%@NL@%
  25243. %@NL@%
  25244.         GpiSetArcParams(hps, &arcp);%@NL@%
  25245.     }%@NL@%
  25246. %@NL@%
  25247. %@NL@%
  25248.     %@AB@%/* set clipping rectangle to the fatbit surface */%@AE@%%@NL@%
  25249. %@NL@%
  25250.     if ((hrgn = GpiCreateRegion(hps, 1L, &global.rcl)) != HRGN_ERROR)%@NL@%
  25251.         GpiSetClipRegion(hps, hrgn, &hrgnClipOld);%@NL@%
  25252. %@NL@%
  25253. %@NL@%
  25254.     if (fsCmd & CLEAR_BACKGROUND)%@NL@%
  25255.     {%@NL@%
  25256.         DrawGrid(hps);%@NL@%
  25257. %@NL@%
  25258.         if (global.hpsFatShadow)%@NL@%
  25259.         {%@NL@%
  25260.             AREABUNDLE ab;%@NL@%
  25261. %@NL@%
  25262.             %@AB@%/* clear shadow fatpel surface to background color */%@AE@%%@NL@%
  25263.             ab.lColor = global.clrField;%@NL@%
  25264.             GpiSetAttrs(global.hpsFatShadow, PRIM_AREA, ABB_COLOR, 0L, &ab);%@NL@%
  25265.             GpiBitBlt(global.hpsFatShadow, NULL, 2L, (PPOINTL)&global.rclFat, ROP_PATCOPY,(ULONG) 0);%@NL@%
  25266.         }%@NL@%
  25267.     }%@NL@%
  25268. %@NL@%
  25269.     if (global.fDisplayRenderedObj && !(fsCmd & OVERRIDE_RENDERED_OBJ))%@NL@%
  25270.         DisplayRenderedPels(hps, fsCmd);%@NL@%
  25271. %@NL@%
  25272.     if (global.fDisplayControlPoints)%@NL@%
  25273.     {%@NL@%
  25274.         %@AB@%/* when rubberbanding with the rendered obj, newly drawn fatpels%@NL@%
  25275. %@AB@%         * can wipe out stationary control point markers, so we have to%@NL@%
  25276. %@AB@%         * redraw them all each time%@NL@%
  25277. %@AB@%         */%@AE@%%@NL@%
  25278. %@NL@%
  25279.         if (global.fDisplayRenderedObj || (fsCmd & CLEAR_BACKGROUND))%@NL@%
  25280.             DisplayControlPoints(hps, global.cptl, global.pptl, global.usMix);%@NL@%
  25281.         else if (global.sPtGrabbed != NO_POINT)%@NL@%
  25282.             %@AB@%/* draw just the control point that moved */%@AE@%%@NL@%
  25283.             DisplayControlPoints(hps, 1L, global.pptl+global.sPtGrabbed, global.usMix);%@NL@%
  25284.     }%@NL@%
  25285. %@NL@%
  25286.     if (global.fDisplayMathObj)%@NL@%
  25287.         DisplayMathematicalObject(hps, global.usMix);%@NL@%
  25288. %@NL@%
  25289.     %@AB@%/* delete the clip region we set up */%@AE@%%@NL@%
  25290. %@NL@%
  25291.     if (hrgnClipOld != HRGN_ERROR)%@NL@%
  25292.         GpiSetClipRegion(hps, hrgnClipOld, &hrgnT);%@NL@%
  25293.     if (hrgn != HRGN_ERROR)%@NL@%
  25294.         GpiDestroyRegion(hps, hrgn);%@NL@%
  25295. }%@NL@%
  25296. %@NL@%
  25297. %@NL@%
  25298. %@NL@%
  25299. %@NL@%
  25300. %@AB@%/************************************************************************%@NL@%
  25301. %@AB@%*%@NL@%
  25302. %@AB@%*   DisplayMathematicalObject%@NL@%
  25303. %@AB@%*%@NL@%
  25304. %@AB@%************************************************************************/%@AE@%%@NL@%
  25305. %@NL@%
  25306. VOID%@NL@%
  25307. DisplayMathematicalObject(hps, usMix)%@NL@%
  25308. HPS hps;%@NL@%
  25309. USHORT usMix;%@NL@%
  25310. {%@NL@%
  25311.     PPOINTL pptl;%@NL@%
  25312.     LINEBUNDLE lb;%@NL@%
  25313. %@NL@%
  25314.     if (global.cptl > 0)%@NL@%
  25315.     {%@NL@%
  25316.         if (global.fRoundControlPoints)%@NL@%
  25317.         {%@NL@%
  25318.             RoundControlPoints(hps, global.cptl, global.pptl, global.pptlTmp,%@NL@%
  25319.                                global.cxFatPel, global.cyFatPel);%@NL@%
  25320.             pptl = global.pptlTmp;%@NL@%
  25321.         }%@NL@%
  25322.         else%@NL@%
  25323.             pptl = global.pptl;%@NL@%
  25324. %@NL@%
  25325.         %@AB@%/* draw line */%@AE@%%@NL@%
  25326.         lb.lColor    = global.clrMathObj;%@NL@%
  25327.         lb.usMixMode = usMix;%@NL@%
  25328.         GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR|LBB_MIX_MODE, 0L, &lb);%@NL@%
  25329.         DrawPrimitive(hps, global.cptl, pptl);%@NL@%
  25330.     }%@NL@%
  25331. }%@NL@%
  25332. %@NL@%
  25333. %@NL@%
  25334. %@NL@%
  25335. %@NL@%
  25336. %@AB@%/************************************************************************%@NL@%
  25337. %@AB@%*%@NL@%
  25338. %@AB@%*   DisplayControlPoints%@NL@%
  25339. %@AB@%*%@NL@%
  25340. %@AB@%************************************************************************/%@AE@%%@NL@%
  25341. %@NL@%
  25342. VOID%@NL@%
  25343. DisplayControlPoints(hps, cptl, pptl, usMix)%@NL@%
  25344. HPS hps;%@NL@%
  25345. LONG cptl;%@NL@%
  25346. PPOINTL pptl;%@NL@%
  25347. USHORT usMix;%@NL@%
  25348. {%@NL@%
  25349.     PPOINTL pptlT;%@NL@%
  25350.     MARKERBUNDLE mb;%@NL@%
  25351. %@NL@%
  25352.     if (cptl > 0)%@NL@%
  25353.     {%@NL@%
  25354.         if (global.fRoundControlPoints)%@NL@%
  25355.         {%@NL@%
  25356.             RoundControlPoints(hps, cptl, pptl, global.pptlTmp,%@NL@%
  25357.                                global.cxFatPel, global.cyFatPel);%@NL@%
  25358.             pptlT = global.pptlTmp;%@NL@%
  25359.         }%@NL@%
  25360.         else%@NL@%
  25361.             pptlT = pptl;%@NL@%
  25362. %@NL@%
  25363. %@NL@%
  25364.         mb.lColor    = global.clrControlPoints;%@NL@%
  25365.         mb.usMixMode = usMix;%@NL@%
  25366.         mb.usSymbol  = global.usControlPointSymbol;%@NL@%
  25367.         GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR|MBB_MIX_MODE|MBB_SYMBOL, 0L, &mb);%@NL@%
  25368. %@NL@%
  25369.         GpiPolyMarker(hps, cptl, pptlT);%@NL@%
  25370.     }%@NL@%
  25371. }%@NL@%
  25372. %@NL@%
  25373. %@NL@%
  25374. %@NL@%
  25375. %@NL@%
  25376. %@AB@%/************************************************************************%@NL@%
  25377. %@AB@%*%@NL@%
  25378. %@AB@%*   EraseBackground%@NL@%
  25379. %@AB@%*%@NL@%
  25380. %@AB@%*   Erase the unused part of the window to a hatch pattern.%@NL@%
  25381. %@AB@%*%@NL@%
  25382. %@AB@%************************************************************************/%@AE@%%@NL@%
  25383. %@NL@%
  25384. VOID%@NL@%
  25385. EraseBackground(hps)%@NL@%
  25386. HPS hps;%@NL@%
  25387. {%@NL@%
  25388.     RECTL rclClient, rclT;%@NL@%
  25389.     AREABUNDLE ab;%@NL@%
  25390. %@NL@%
  25391. %@NL@%
  25392.     WinQueryWindowRect(global.hwnd, &rclClient);%@NL@%
  25393. %@NL@%
  25394.     ab.lColor          = CLR_BLACK;%@NL@%
  25395.     ab.lBackColor = CLR_WHITE;%@NL@%
  25396.     ab.usSymbol   = PATSYM_DIAG1;%@NL@%
  25397.     GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR|ABB_BACK_COLOR|ABB_SYMBOL,%@NL@%
  25398.                 0L, (PBUNDLE)&ab);%@NL@%
  25399. %@NL@%
  25400.     if (global.rcl.yTop < rclClient.yTop)%@NL@%
  25401.     {%@NL@%
  25402.         rclT.xLeft   = rclClient.xLeft;%@NL@%
  25403.         rclT.yBottom = global.rcl.yBottom;%@NL@%
  25404.         rclT.xRight  = rclClient.xRight;%@NL@%
  25405.         rclT.yTop    = rclClient.yTop;%@NL@%
  25406.         GpiBitBlt(hps, NULL, 2L, (PPOINTL)&rclT, ROP_PATCOPY, (ULONG) 0);%@NL@%
  25407.     }%@NL@%
  25408. %@NL@%
  25409.     if (global.rcl.xRight < rclClient.xRight)%@NL@%
  25410.     {%@NL@%
  25411.         rclT.xLeft   = global.rcl.xRight;%@NL@%
  25412.         rclT.yBottom = rclClient.yBottom;%@NL@%
  25413.         rclT.xRight  = rclClient.xRight;%@NL@%
  25414.         rclT.yTop    = global.rcl.yTop;%@NL@%
  25415.         GpiBitBlt(hps, NULL, 2L, (PPOINTL)&rclT, ROP_PATCOPY, (ULONG) 0);%@NL@%
  25416.     }%@NL@%
  25417. %@NL@%
  25418.     ab.usSymbol   = PATSYM_SOLID;%@NL@%
  25419.     GpiSetAttrs(hps, PRIM_AREA, ABB_SYMBOL, 0L, (PBUNDLE)&ab);%@NL@%
  25420. }%@NL@%
  25421. %@NL@%
  25422. %@NL@%
  25423. %@NL@%
  25424. %@NL@%
  25425. %@AB@%/************************************************************************%@NL@%
  25426. %@AB@%*%@NL@%
  25427. %@AB@%*   DrawGrid%@NL@%
  25428. %@AB@%*%@NL@%
  25429. %@AB@%************************************************************************/%@AE@%%@NL@%
  25430. %@NL@%
  25431. VOID%@NL@%
  25432. DrawGrid(hps)%@NL@%
  25433. HPS  hps;%@NL@%
  25434. {%@NL@%
  25435.     AREABUNDLE ab;%@NL@%
  25436.     POINTL ptl;%@NL@%
  25437.     POINTL aptl[3];%@NL@%
  25438. %@NL@%
  25439. %@NL@%
  25440.     %@AB@%/* clear fatpel surface to background color */%@AE@%%@NL@%
  25441.     ab.lColor = global.clrInterstice;%@NL@%
  25442.     GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR, 0L, &ab);%@NL@%
  25443.     GpiBitBlt(hps, NULL, 2L, (PPOINTL)&global.rcl, ROP_PATCOPY, (ULONG) 0);%@NL@%
  25444. %@NL@%
  25445. %@NL@%
  25446.     %@AB@%/* draw one pel in lower left corner */%@AE@%%@NL@%
  25447. %@NL@%
  25448.     ptl.x = global.cxFatPel / 2L;%@NL@%
  25449.     ptl.y = global.cyFatPel / 2L;%@NL@%
  25450.     DrawOneFatPel(hps, &ptl, global.clrField);%@NL@%
  25451. %@NL@%
  25452. %@NL@%
  25453.     %@AB@%/* blt up first column then across -- we don't have to worry%@NL@%
  25454. %@AB@%     * about the edges because a clip region has been setup to do that.%@NL@%
  25455. %@AB@%     */%@AE@%%@NL@%
  25456. %@NL@%
  25457.     aptl[0].x = 0L;%@NL@%
  25458.     aptl[0].y = global.cyFatPel;%@NL@%
  25459.     aptl[1].x = global.cxFatPel;%@NL@%
  25460.     aptl[2].x = 0L;%@NL@%
  25461.     aptl[2].y = 0L;%@NL@%
  25462. %@NL@%
  25463.     while (aptl[0].y <= global.rcl.yTop)%@NL@%
  25464.     {%@NL@%
  25465.         aptl[1].y  = aptl[0].y + aptl[0].y;%@NL@%
  25466.         GpiBitBlt(hps, hps, 3L, aptl, ROP_SRCCOPY, (LONG)NULL);%@NL@%
  25467.         aptl[0].y += aptl[1].y - aptl[0].y;%@NL@%
  25468.     }%@NL@%
  25469. %@NL@%
  25470.     aptl[0].x = global.cxFatPel;%@NL@%
  25471.     aptl[0].y = 0L;%@NL@%
  25472.     aptl[1].y = global.rcl.yTop;%@NL@%
  25473.     aptl[2].x = 0L;%@NL@%
  25474.     aptl[2].y = 0L;%@NL@%
  25475. %@NL@%
  25476.     while (aptl[0].x <= global.rcl.xRight)%@NL@%
  25477.     {%@NL@%
  25478.         aptl[1].x  = aptl[0].x + aptl[0].x;%@NL@%
  25479.         GpiBitBlt(hps, hps, 3L, aptl, ROP_SRCCOPY, (LONG)NULL);%@NL@%
  25480.         aptl[0].x += aptl[1].x - aptl[0].x;%@NL@%
  25481.     }%@NL@%
  25482. }%@NL@%
  25483. %@NL@%
  25484. %@NL@%
  25485. %@NL@%
  25486. %@NL@%
  25487. %@AB@%/************************************************************************%@NL@%
  25488. %@AB@%*%@NL@%
  25489. %@AB@%*   DisplayRenderedPels%@NL@%
  25490. %@AB@%*%@NL@%
  25491. %@AB@%************************************************************************/%@AE@%%@NL@%
  25492. %@NL@%
  25493. VOID%@NL@%
  25494. DisplayRenderedPels(hps, fsCmd)%@NL@%
  25495. HPS hps;%@NL@%
  25496. USHORT fsCmd;%@NL@%
  25497. {%@NL@%
  25498.     LINEBUNDLE lb;%@NL@%
  25499.     AREABUNDLE ab;%@NL@%
  25500.     POINTL aptl[3];%@NL@%
  25501. %@NL@%
  25502.     %@AB@%/*        Call GPI to draw the current primitive into the small bitmap,%@NL@%
  25503. %@AB@%     *        then fatbit it to the display.%@NL@%
  25504. %@AB@%     */%@AE@%%@NL@%
  25505. %@NL@%
  25506.     if (global.hbmFat)%@NL@%
  25507.     {%@NL@%
  25508.         if (fsCmd & CLEAR_FAT_BITMAP)%@NL@%
  25509.         {%@NL@%
  25510.             %@AB@%/* clear fatpel surface to background color */%@AE@%%@NL@%
  25511.             ab.lColor = global.clrField;%@NL@%
  25512.             GpiSetAttrs(global.hpsFat, PRIM_AREA, ABB_COLOR, 0L, &ab);%@NL@%
  25513.             GpiBitBlt(global.hpsFat, NULL, 2L, (PPOINTL)&global.rclFat, ROP_PATCOPY, (ULONG) 0);%@NL@%
  25514.         }%@NL@%
  25515. %@NL@%
  25516.         if (fsCmd & RENDER_MATH_OBJ)%@NL@%
  25517.         {%@NL@%
  25518.             if (global.cptl > 0)%@NL@%
  25519.             {%@NL@%
  25520.                 %@AB@%/* draw line */%@AE@%%@NL@%
  25521.                 lb.lColor = global.clrRenderedObj;%@NL@%
  25522.                 GpiSetAttrs(global.hpsFat, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  25523.                 GpiSetModelTransformMatrix(global.hpsFat, 9L,%@NL@%
  25524.                                           &global.matlf, TRANSFORM_REPLACE);%@NL@%
  25525.                 DrawPrimitive(global.hpsFat, global.cptl, global.pptl);%@NL@%
  25526.                 GpiSetModelTransformMatrix(global.hpsFat, 0L, NULL, TRANSFORM_REPLACE);%@NL@%
  25527.             }%@NL@%
  25528.         }%@NL@%
  25529. %@NL@%
  25530.         %@AB@%/* xor the new rendered bitmap into the shadow bitmap */%@AE@%%@NL@%
  25531.         *((PRECTL)&aptl[0]) = global.rclFat;%@NL@%
  25532.         aptl[2].x = 0L;%@NL@%
  25533.         aptl[2].y = 0L;%@NL@%
  25534.         GpiBitBlt(global.hpsFatShadow, global.hpsFat, 3L, aptl, ROP_SRCINVERT, (ULONG) 0);%@NL@%
  25535. %@NL@%
  25536.         %@AB@%/* fatbit object to the display */%@AE@%%@NL@%
  25537.         DrawFatPels(hps);%@NL@%
  25538. %@NL@%
  25539.         %@AB@%/* get the new shadow bitmap */%@AE@%%@NL@%
  25540.         GpiBitBlt(global.hpsFatShadow, global.hpsFat, 3L, aptl, ROP_SRCCOPY, (ULONG) 0);%@NL@%
  25541.     }%@NL@%
  25542. }%@NL@%
  25543. %@NL@%
  25544. %@NL@%
  25545. %@NL@%
  25546. %@NL@%
  25547. %@AB@%/************************************************************************%@NL@%
  25548. %@AB@%*%@NL@%
  25549. %@AB@%*   DrawFatPels%@NL@%
  25550. %@AB@%*%@NL@%
  25551. %@AB@%************************************************************************/%@AE@%%@NL@%
  25552. %@NL@%
  25553. VOID%@NL@%
  25554. DrawFatPels(hps)%@NL@%
  25555. HPS hps;%@NL@%
  25556. {%@NL@%
  25557.     POINTL ptl, ptlCenter;%@NL@%
  25558.     LONG i, j;%@NL@%
  25559.     COLOR clr;%@NL@%
  25560. %@NL@%
  25561. %@NL@%
  25562.     %@AB@%/* if the pel size is 1,1, then just blt the small bitmap to the%@NL@%
  25563. %@AB@%     * display.%@NL@%
  25564. %@AB@%     */%@AE@%%@NL@%
  25565. %@NL@%
  25566.     if ((global.cxFatPel == 1L) && (global.cyFatPel == 1L))%@NL@%
  25567.     {%@NL@%
  25568.         POINTL aptl[3];%@NL@%
  25569. %@NL@%
  25570.         *((PRECTL)&aptl[0]) = global.rcl;%@NL@%
  25571.         aptl[2].x = 0L;%@NL@%
  25572.         aptl[2].y = 0L;%@NL@%
  25573.         GpiBitBlt(hps, global.hpsFat, 3L, aptl, ROP_SRCCOPY, 0L);%@NL@%
  25574. %@NL@%
  25575.         return;%@NL@%
  25576.     }%@NL@%
  25577. %@NL@%
  25578.     for (i = 0; i < global.rclFat.xRight; ++i)%@NL@%
  25579.         for (j = 0; j < global.rclFat.yTop; ++j)%@NL@%
  25580.         {%@NL@%
  25581.             ptl.x = i;%@NL@%
  25582.             ptl.y = j;%@NL@%
  25583. %@NL@%
  25584.             clr = GpiQueryPel(global.hpsFatShadow, &ptl);%@NL@%
  25585.             if ((global.fRGB && (clr != 0x000000L)) ||%@NL@%
  25586.                (!global.fRGB && (clr != global.clrBlackIndex)))%@NL@%
  25587.             {%@NL@%
  25588.                 clr = GpiQueryPel(global.hpsFat, &ptl);%@NL@%
  25589.                 ptlCenter.x = (i * global.cxFatPel) + global.cxHalfFatPel;%@NL@%
  25590.                 ptlCenter.y = (j * global.cyFatPel) + global.cyHalfFatPel;%@NL@%
  25591.                 DrawOneFatPel(hps, &ptlCenter, clr);%@NL@%
  25592.             }%@NL@%
  25593.         }%@NL@%
  25594. }%@NL@%
  25595. %@NL@%
  25596. %@NL@%
  25597. %@NL@%
  25598. %@NL@%
  25599. %@AB@%/************************************************************************%@NL@%
  25600. %@AB@%*%@NL@%
  25601. %@AB@%*   DrawOneFatPel%@NL@%
  25602. %@AB@%*%@NL@%
  25603. %@AB@%************************************************************************/%@AE@%%@NL@%
  25604. %@NL@%
  25605. VOID%@NL@%
  25606. DrawOneFatPel(hps, pptl, clr)%@NL@%
  25607. HPS hps;%@NL@%
  25608. PPOINTL pptl;%@NL@%
  25609. COLOR clr;%@NL@%
  25610. {%@NL@%
  25611.     POINTL ptl;%@NL@%
  25612.     LINEBUNDLE lb;%@NL@%
  25613.     AREABUNDLE ab;%@NL@%
  25614. %@NL@%
  25615. %@NL@%
  25616.     if (global.fDisplayPelBorder || global.fDisplayCrossHairs)%@NL@%
  25617.     {%@NL@%
  25618.         lb.lColor = global.clrCrossHair;%@NL@%
  25619.         GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);%@NL@%
  25620.     }%@NL@%
  25621. %@NL@%
  25622.     ab.lColor = clr;%@NL@%
  25623.     GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR, 0L, &ab);%@NL@%
  25624. %@NL@%
  25625. %@NL@%
  25626.     switch (global.usPelShape)%@NL@%
  25627.     {%@NL@%
  25628.     case IDD_SQUARE:%@NL@%
  25629.         {%@NL@%
  25630.             POINTL ptlT;%@NL@%
  25631.             ULONG flCmd;%@NL@%
  25632. %@NL@%
  25633.             if (global.fDisplayPelBorder)%@NL@%
  25634.                 flCmd = DRO_OUTLINEFILL;%@NL@%
  25635.             else%@NL@%
  25636.                 flCmd = DRO_FILL;%@NL@%
  25637. %@NL@%
  25638.             ptlT.x = pptl->x - global.cxHalfFatPel;%@NL@%
  25639.             ptlT.y = pptl->y - global.cyHalfFatPel;%@NL@%
  25640.             GpiSetCurrentPosition(hps, &ptlT);%@NL@%
  25641.             ptlT.x = pptl->x + global.cxHalfFatPel;%@NL@%
  25642.             ptlT.y = pptl->y + global.cyHalfFatPel;%@NL@%
  25643.             GpiBox(hps, flCmd, &ptlT, 0L, 0L);%@NL@%
  25644.         }%@NL@%
  25645.         break;%@NL@%
  25646. %@NL@%
  25647.     case IDD_DIAMOND:%@NL@%
  25648.         {%@NL@%
  25649.             POINTL aptlT[4];%@NL@%
  25650.             ULONG flCmd;%@NL@%
  25651. %@NL@%
  25652.             if (global.fDisplayPelBorder)%@NL@%
  25653.                 flCmd = BA_BOUNDARY;%@NL@%
  25654.             else%@NL@%
  25655.                 flCmd = 0L;%@NL@%
  25656. %@NL@%
  25657.             aptlT[0].x = pptl->x;%@NL@%
  25658.             aptlT[0].y = pptl->y - global.cyHalfFatPel;%@NL@%
  25659.             aptlT[1].x = pptl->x - global.cxHalfFatPel;%@NL@%
  25660.             aptlT[1].y = pptl->y;%@NL@%
  25661.             aptlT[2].x = pptl->x;%@NL@%
  25662.             aptlT[2].y = pptl->y + global.cyHalfFatPel;%@NL@%
  25663.             aptlT[3].x = pptl->x + global.cxHalfFatPel;%@NL@%
  25664.             aptlT[3].y = pptl->y;%@NL@%
  25665. %@NL@%
  25666.             GpiSetCurrentPosition(hps, &aptlT[3]);%@NL@%
  25667.             GpiBeginArea(hps, flCmd);%@NL@%
  25668.             GpiPolyLine(hps, 4L, aptlT);%@NL@%
  25669.             GpiEndArea(hps);%@NL@%
  25670.         }%@NL@%
  25671. %@NL@%
  25672.         break;%@NL@%
  25673. %@NL@%
  25674.     case IDD_CIRCLE:%@NL@%
  25675.         {%@NL@%
  25676.             ULONG flCmd;%@NL@%
  25677. %@NL@%
  25678.             if (global.fDisplayPelBorder)%@NL@%
  25679.                 flCmd = DRO_OUTLINEFILL;%@NL@%
  25680.             else%@NL@%
  25681.                 flCmd = DRO_FILL;%@NL@%
  25682. %@NL@%
  25683.             GpiSetCurrentPosition(hps, pptl);%@NL@%
  25684.             GpiFullArc(hps, flCmd, 0x10000L);%@NL@%
  25685.         }%@NL@%
  25686.         break;%@NL@%
  25687.     }%@NL@%
  25688. %@NL@%
  25689. %@NL@%
  25690.     if (global.fDisplayCrossHairs)%@NL@%
  25691.     {%@NL@%
  25692.         %@AB@%/* draw cross in center of pel */%@AE@%%@NL@%
  25693. %@NL@%
  25694.         ptl.x = pptl->x - global.cxHalfFatPel;%@NL@%
  25695.         ptl.y = pptl->y;%@NL@%
  25696.         GpiSetCurrentPosition(hps, &ptl);%@NL@%
  25697.         ptl.x = pptl->x + global.cxHalfFatPel;%@NL@%
  25698.         GpiPolyLine(hps, 1L, &ptl);%@NL@%
  25699. %@NL@%
  25700.         ptl.x = pptl->x;%@NL@%
  25701.         ptl.y = pptl->y - global.cyHalfFatPel;%@NL@%
  25702.         GpiSetCurrentPosition(hps, &ptl);%@NL@%
  25703.         ptl.y = pptl->y + global.cyHalfFatPel;%@NL@%
  25704.         GpiPolyLine(hps, 1L, &ptl);%@NL@%
  25705.     }%@NL@%
  25706. }%@NL@%
  25707. %@NL@%
  25708. %@NL@%
  25709. %@NL@%
  25710. %@NL@%
  25711. %@AB@%/************************************************************************%@NL@%
  25712. %@AB@%*%@NL@%
  25713. %@AB@%*   RoundControlPoints%@NL@%
  25714. %@AB@%*%@NL@%
  25715. %@AB@%************************************************************************/%@AE@%%@NL@%
  25716. %@NL@%
  25717. VOID%@NL@%
  25718. RoundControlPoints(hps, cptl, pptl1, pptl2, cx, cy)%@NL@%
  25719. HPS hps;%@NL@%
  25720. LONG cptl;%@NL@%
  25721. PPOINTL pptl1;%@NL@%
  25722. PPOINTL pptl2;%@NL@%
  25723. LONG cx;%@NL@%
  25724. LONG cy;%@NL@%
  25725. {%@NL@%
  25726.     LONG cx2, cy2;%@NL@%
  25727.     LONG i;%@NL@%
  25728.     MATRIXLF matlf;%@NL@%
  25729. %@NL@%
  25730. %@NL@%
  25731.     %@AB@%/* copy the input buffer to the output/scratch buffer */%@AE@%%@NL@%
  25732.     for (i = 0; i < cptl; ++i)%@NL@%
  25733.         pptl2[i] = pptl1[i];%@NL@%
  25734. %@NL@%
  25735. %@NL@%
  25736.     %@AB@%/* set the transform, transform the points to device space (i.e. to%@NL@%
  25737. %@AB@%     * hpsFat dimensions), then restore the original transform%@NL@%
  25738. %@AB@%     */%@AE@%%@NL@%
  25739.     GpiQueryModelTransformMatrix(hps, 9L, &matlf);%@NL@%
  25740.     GpiSetModelTransformMatrix(hps, 9L, &global.matlf, TRANSFORM_REPLACE);%@NL@%
  25741.     GpiConvert(hps, CVTC_WORLD, CVTC_DEVICE, cptl, pptl2);%@NL@%
  25742.     GpiSetModelTransformMatrix(hps, 9L, &matlf, TRANSFORM_REPLACE);%@NL@%
  25743. %@NL@%
  25744. %@NL@%
  25745.     %@AB@%/* position each point in the center of its fatpel */%@AE@%%@NL@%
  25746. %@NL@%
  25747.     cx2 = cx / 2L;%@NL@%
  25748.     cy2 = cy / 2L;%@NL@%
  25749. %@NL@%
  25750.     for (i = 0; i < cptl; ++i, ++pptl2)%@NL@%
  25751.     {%@NL@%
  25752.         pptl2->x = pptl2->x * cx + cx2;%@NL@%
  25753.         pptl2->y = pptl2->y * cy + cy2;%@NL@%
  25754.     }%@NL@%
  25755. }%@NL@%
  25756. %@NL@%
  25757. %@NL@%
  25758. %@NL@%
  25759. %@NL@%
  25760. %@AB@%/************************************************************************%@NL@%
  25761. %@AB@%*%@NL@%
  25762. %@AB@%*   ComputeTransform%@NL@%
  25763. %@AB@%*%@NL@%
  25764. %@AB@%************************************************************************/%@AE@%%@NL@%
  25765. %@NL@%
  25766. VOID%@NL@%
  25767. ComputeTransform(prcl1, prcl2)%@NL@%
  25768. PRECTL prcl1;%@NL@%
  25769. PRECTL prcl2;%@NL@%
  25770. {%@NL@%
  25771.     LONG xExt1, yExt1;%@NL@%
  25772.     LONG xExt2, yExt2;%@NL@%
  25773.     FIXED xScale, yScale;%@NL@%
  25774. %@NL@%
  25775. %@NL@%
  25776.     xExt1 = prcl1->xRight - prcl1->xLeft;%@NL@%
  25777.     yExt1 = prcl1->yTop   - prcl1->yBottom;%@NL@%
  25778.     xExt2 = prcl2->xRight - prcl2->xLeft;%@NL@%
  25779.     yExt2 = prcl2->yTop   - prcl2->yBottom;%@NL@%
  25780. %@NL@%
  25781. %@NL@%
  25782.     %@AB@%/* If the rectangles are of exactly the same dimensions, then%@NL@%
  25783. %@AB@%     * set the unity transform.  If not, compute the x and y scale%@NL@%
  25784. %@AB@%     * factors.  Note that in world coordinates rectangles are%@NL@%
  25785. %@AB@%     * inclusive-inclusive, whereas in device coordinates they are%@NL@%
  25786. %@AB@%     * inclusive-exclusive.  The extents of the destination are%@NL@%
  25787. %@AB@%     * therefore one pel too large as computed, so we subtract one%@NL@%
  25788. %@AB@%     * in the scale factor computation.%@NL@%
  25789. %@AB@%     */%@AE@%%@NL@%
  25790. %@NL@%
  25791.     if (xExt1 == xExt2)%@NL@%
  25792.         xScale = 0x10000L;%@NL@%
  25793.     else%@NL@%
  25794.         xScale = ((xExt2-1L) * 0x10000L) / xExt1;%@NL@%
  25795. %@NL@%
  25796.     if (yExt1 == yExt2)%@NL@%
  25797.         yScale = 0x10000L;%@NL@%
  25798.     else%@NL@%
  25799.         yScale = ((yExt2-1L) * 0x10000L) / yExt1;%@NL@%
  25800. %@NL@%
  25801. %@NL@%
  25802.     %@AB@%/* store the transform matrix for easy access */%@AE@%%@NL@%
  25803. %@NL@%
  25804.     global.matlf.fxM11 = xScale;%@NL@%
  25805.     global.matlf.fxM12 = 0L;%@NL@%
  25806.     global.matlf. lM13 = 0L;%@NL@%
  25807.     global.matlf.fxM21 = 0L;%@NL@%
  25808.     global.matlf.fxM22 = yScale;%@NL@%
  25809.     global.matlf. lM23 = 0L;%@NL@%
  25810.     global.matlf. lM31 = 0L;%@NL@%
  25811.     global.matlf. lM32 = 0L;%@NL@%
  25812.     global.matlf. lM33 = 1L;%@NL@%
  25813. }%@NL@%
  25814. %@NL@%
  25815. %@NL@%
  25816. %@NL@%
  25817. %@NL@%
  25818. %@AB@%/************************************************************************%@NL@%
  25819. %@AB@%*%@NL@%
  25820. %@AB@%*   DrawPrimitive%@NL@%
  25821. %@AB@%*%@NL@%
  25822. %@AB@%************************************************************************/%@AE@%%@NL@%
  25823. %@NL@%
  25824. VOID%@NL@%
  25825. DrawPrimitive(hps, cptl, pptl)%@NL@%
  25826. HPS hps;%@NL@%
  25827. LONG cptl;%@NL@%
  25828. PPOINTL pptl;%@NL@%
  25829. {%@NL@%
  25830.     switch (global.usCurPrim)%@NL@%
  25831.     {%@NL@%
  25832.     case IDM_NOPRIM:%@NL@%
  25833.         break;%@NL@%
  25834. %@NL@%
  25835.     case IDM_POLYLINE:%@NL@%
  25836.         GpiSetCurrentPosition(hps, pptl);%@NL@%
  25837.         GpiPolyLine(hps, cptl-1L, pptl + 1);%@NL@%
  25838.         break;%@NL@%
  25839. %@NL@%
  25840.     case IDM_POLYFILLET:%@NL@%
  25841.         if (cptl >= 3L)%@NL@%
  25842.         {%@NL@%
  25843.             GpiSetCurrentPosition(hps, pptl);%@NL@%
  25844.             GpiPolyFillet(hps, cptl-1L, pptl + 1);%@NL@%
  25845.         }%@NL@%
  25846.         break;%@NL@%
  25847. %@NL@%
  25848.     case IDM_POLYSPLINE:%@NL@%
  25849.         if (cptl >= 4L)%@NL@%
  25850.         {%@NL@%
  25851.             LONG cptSlack;    %@AB@%/* # points in pptl not usable by PolySpline */%@AE@%%@NL@%
  25852. %@NL@%
  25853.             cptSlack = ((cptl-1L) % 3) + 1;%@NL@%
  25854.             GpiSetCurrentPosition( hps, pptl );%@NL@%
  25855.             GpiPolySpline( hps, cptl-cptSlack, pptl+1 );%@NL@%
  25856.         }%@NL@%
  25857.         break;%@NL@%
  25858. %@NL@%
  25859.     case IDM_POINTARC:%@NL@%
  25860.         if (cptl >= 3L)%@NL@%
  25861.         {%@NL@%
  25862.             GpiSetCurrentPosition( hps, pptl );%@NL@%
  25863.             GpiPointArc( hps, pptl+1 );%@NL@%
  25864.         }%@NL@%
  25865.         break;%@NL@%
  25866.     }%@NL@%
  25867. }%@NL@%
  25868. %@NL@%
  25869. %@NL@%
  25870. %@NL@%
  25871. %@NL@%
  25872. %@AB@%/************************************************************************%@NL@%
  25873. %@AB@%*%@NL@%
  25874. %@AB@%*   UpdateSurfaceDims%@NL@%
  25875. %@AB@%*%@NL@%
  25876. %@AB@%************************************************************************/%@AE@%%@NL@%
  25877. %@NL@%
  25878. VOID%@NL@%
  25879. UpdateSurfaceDims()%@NL@%
  25880. {%@NL@%
  25881.     SIZEL size;%@NL@%
  25882.     BITMAPINFOHEADER bminfo;%@NL@%
  25883.     AREABUNDLE ab;%@NL@%
  25884. %@NL@%
  25885. %@NL@%
  25886.     WinQueryWindowRect(global.hwnd, &global.rcl);%@NL@%
  25887. %@NL@%
  25888.     %@AB@%/* compute size of small surface */%@AE@%%@NL@%
  25889.     global.rclFat.xLeft   = 0L;%@NL@%
  25890.     global.rclFat.yBottom = 0L;%@NL@%
  25891.     global.rclFat.xRight  = global.rcl.xRight / global.cxFatPel;%@NL@%
  25892.     global.rclFat.yTop          = global.rcl.yTop   / global.cyFatPel;%@NL@%
  25893. %@NL@%
  25894.     %@AB@%/* compute size of fatpel version of small surface */%@AE@%%@NL@%
  25895.     global.rcl.xLeft   = 0L;%@NL@%
  25896.     global.rcl.yBottom = 0L;%@NL@%
  25897.     global.rcl.xRight  = global.rclFat.xRight * global.cxFatPel;%@NL@%
  25898.     global.rcl.yTop    = global.rclFat.yTop   * global.cyFatPel;%@NL@%
  25899. %@NL@%
  25900.     ComputeTransform(&global.rcl, &global.rclFat);%@NL@%
  25901. %@NL@%
  25902.     if ((global.rclFat.xRight <= global.rclFatBM.xRight) &&%@NL@%
  25903.         (global.rclFat.yTop   <= global.rclFatBM.yTop))%@NL@%
  25904.         return;%@NL@%
  25905. %@NL@%
  25906. %@NL@%
  25907. %@NL@%
  25908.     %@AB@%/* The new fatbits surface doesn't fit in the bitmap, so we%@NL@%
  25909. %@AB@%     * have to make a new one.        If we don't have a DC or PS, make%@NL@%
  25910. %@AB@%     * those before making the bitmap.        If we do have a bitmap,%@NL@%
  25911. %@AB@%     * delete it before making the new one.%@NL@%
  25912. %@AB@%     */%@AE@%%@NL@%
  25913. %@NL@%
  25914.     global.rclFatBM = global.rclFat;%@NL@%
  25915. %@NL@%
  25916.     if (global.hbmFat)%@NL@%
  25917.     {%@NL@%
  25918.         GpiSetBitmap(global.hpsFat, NULL);%@NL@%
  25919.         GpiDeleteBitmap(global.hbmFat);%@NL@%
  25920.         GpiSetBitmap(global.hpsFatShadow, NULL);%@NL@%
  25921.         GpiDeleteBitmap(global.hbmFatShadow);%@NL@%
  25922.     }%@NL@%
  25923. %@NL@%
  25924.     if (!global.hdcFat)%@NL@%
  25925.     {%@NL@%
  25926.         global.hdcFat = DevOpenDC(global.hab, OD_MEMORY, "*", 0L, NULL, NULL);%@NL@%
  25927.         if (!global.hdcFat)%@NL@%
  25928.             goto usd_error;%@NL@%
  25929. %@NL@%
  25930.         global.hdcFatShadow = DevOpenDC(global.hab, OD_MEMORY, "*", 0L, NULL, NULL);%@NL@%
  25931.         if (!global.hdcFatShadow)%@NL@%
  25932.             goto usd_error;%@NL@%
  25933.     }%@NL@%
  25934. %@NL@%
  25935.     if (!global.hpsFat)%@NL@%
  25936.     {%@NL@%
  25937.         size.cx = 0L;%@NL@%
  25938.         size.cy = 0L;%@NL@%
  25939.         global.hpsFat = GpiCreatePS(global.hab, global.hdcFat, &size,%@NL@%
  25940.                                  PU_PELS|GPIT_MICRO|GPIA_ASSOC);%@NL@%
  25941.         if (!global.hpsFat)%@NL@%
  25942.             goto usd_error;%@NL@%
  25943. %@NL@%
  25944.         global.hpsFatShadow = GpiCreatePS(global.hab, global.hdcFatShadow, &size,%@NL@%
  25945.                                  PU_PELS|GPIT_MICRO|GPIA_ASSOC);%@NL@%
  25946.         if (!global.hpsFatShadow)%@NL@%
  25947.             goto usd_error;%@NL@%
  25948.     }%@NL@%
  25949. %@NL@%
  25950.     %@AB@%/* create bitmap with maximum color resolution (24-bit color) */%@AE@%%@NL@%
  25951.     bminfo.cbFix = sizeof(BITMAPINFOHEADER);%@NL@%
  25952.     bminfo.cx = (USHORT) (global.rclFatBM.xRight - global.rclFatBM.xLeft);%@NL@%
  25953.     bminfo.cy = (USHORT) (global.rclFatBM.yTop         - global.rclFatBM.yBottom);%@NL@%
  25954.     bminfo.cPlanes   = 1L;%@NL@%
  25955.     bminfo.cBitCount = 24L;%@NL@%
  25956.     global.hbmFat = GpiCreateBitmap(global.hpsFat, &bminfo, 0L, 0L, 0L);%@NL@%
  25957.     if (!global.hbmFat)%@NL@%
  25958.         goto usd_error;%@NL@%
  25959.     GpiSetBitmap(global.hpsFat, global.hbmFat);%@NL@%
  25960. %@NL@%
  25961.     %@AB@%/* create a shadow bitmap of the one we just created */%@AE@%%@NL@%
  25962.     bminfo.cbFix = sizeof(BITMAPINFOHEADER);%@NL@%
  25963.     bminfo.cx = (USHORT) (global.rclFatBM.xRight - global.rclFatBM.xLeft);%@NL@%
  25964.     bminfo.cy = (USHORT) (global.rclFatBM.yTop         - global.rclFatBM.yBottom);%@NL@%
  25965.     bminfo.cPlanes   = 1L;%@NL@%
  25966.     bminfo.cBitCount = 24L;%@NL@%
  25967.     global.hbmFatShadow = GpiCreateBitmap(global.hpsFatShadow, &bminfo, 0L, 0L, 0L);%@NL@%
  25968.     if (!global.hbmFat)%@NL@%
  25969.         goto usd_error;%@NL@%
  25970.     GpiSetBitmap(global.hpsFatShadow, global.hbmFatShadow);%@NL@%
  25971. %@NL@%
  25972.     %@AB@%/* clear bitmap surface to field color */%@AE@%%@NL@%
  25973.     ab.lColor = global.clrField;%@NL@%
  25974.     GpiSetAttrs(global.hpsFat, PRIM_AREA, ABB_COLOR, 0L, &ab);%@NL@%
  25975.     GpiBitBlt(global.hpsFat, NULL, 2L, (PPOINTL)&global.rclFat, ROP_PATCOPY, (ULONG) 0);%@NL@%
  25976. %@NL@%
  25977.     return;%@NL@%
  25978. %@NL@%
  25979. %@NL@%
  25980. %@AB@%/* error exit point */%@AE@%%@NL@%
  25981. %@NL@%
  25982. usd_error:%@NL@%
  25983.     if (global.hpsFat)%@NL@%
  25984.         GpiDestroyPS(global.hpsFat);%@NL@%
  25985.     if (global.hpsFatShadow)%@NL@%
  25986.         GpiDestroyPS(global.hpsFatShadow);%@NL@%
  25987.     if (global.hdcFat)%@NL@%
  25988.         DevCloseDC(global.hdcFat);%@NL@%
  25989.     if (global.hdcFatShadow)%@NL@%
  25990.         DevCloseDC(global.hdcFatShadow);%@NL@%
  25991. %@NL@%
  25992.     global.hpsFat        = NULL;%@NL@%
  25993.     global.hdcFat        = NULL;%@NL@%
  25994.     global.hpsFatShadow = NULL;%@NL@%
  25995.     global.hdcFatShadow = NULL;%@NL@%
  25996. }%@NL@%
  25997. %@NL@%
  25998. %@NL@%
  25999. %@NL@%
  26000. %@NL@%
  26001. %@AB@%/************************************************************************%@NL@%
  26002. %@AB@%*%@NL@%
  26003. %@AB@%*   AboutDlg%@NL@%
  26004. %@AB@%*%@NL@%
  26005. %@AB@%*   Process messages for the About box.%@NL@%
  26006. %@AB@%*%@NL@%
  26007. %@AB@%************************************************************************/%@AE@%%@NL@%
  26008. %@NL@%
  26009. ULONG CALLBACK%@NL@%
  26010. AboutDlg(hwnd, usMsg, mp1, mp2)%@NL@%
  26011. HWND   hwnd;%@NL@%
  26012. USHORT usMsg;%@NL@%
  26013. MPARAM mp1;%@NL@%
  26014. MPARAM mp2;%@NL@%
  26015. {%@NL@%
  26016.     switch (usMsg)%@NL@%
  26017.     {%@NL@%
  26018.     case WM_COMMAND:%@NL@%
  26019.         if (SHORT1FROMMP(mp1) == DID_OK)%@NL@%
  26020.             WinDismissDlg(hwnd, TRUE);%@NL@%
  26021.         else%@NL@%
  26022.             return FALSE;%@NL@%
  26023.         break;%@NL@%
  26024. %@NL@%
  26025.     default:%@NL@%
  26026.         return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);%@NL@%
  26027.     }%@NL@%
  26028.     return FALSE;%@NL@%
  26029. }%@NL@%
  26030. %@NL@%
  26031. %@NL@%
  26032. %@NL@%
  26033. %@NL@%
  26034. %@AB@%/************************************************************************%@NL@%
  26035. %@AB@%*%@NL@%
  26036. %@AB@%*   PelSizeDlg%@NL@%
  26037. %@AB@%*%@NL@%
  26038. %@AB@%*   Process messages for the Pel Size dialog box.%@NL@%
  26039. %@AB@%*%@NL@%
  26040. %@AB@%************************************************************************/%@AE@%%@NL@%
  26041. %@NL@%
  26042. ULONG CALLBACK%@NL@%
  26043. PelSizeDlg(hwnd, usMsg, mp1, mp2)%@NL@%
  26044. HWND   hwnd;%@NL@%
  26045. USHORT usMsg;%@NL@%
  26046. MPARAM mp1;%@NL@%
  26047. MPARAM mp2;%@NL@%
  26048. {%@NL@%
  26049.     BOOL fRet = FALSE;%@NL@%
  26050. %@NL@%
  26051.     switch (usMsg)%@NL@%
  26052.     {%@NL@%
  26053.     case WM_INITDLG:%@NL@%
  26054.         MySetWindowLong(hwnd, IDD_PELWIDTH,  global.cxFatPel);%@NL@%
  26055.         MySetWindowLong(hwnd, IDD_PELHEIGHT, global.cyFatPel);%@NL@%
  26056.         WinSendDlgItemMsg(hwnd, global.usPelShape,%@NL@%
  26057.                           BM_SETCHECK, (MPARAM)TRUE, 0L);%@NL@%
  26058.         return FALSE;%@NL@%
  26059.         break;%@NL@%
  26060. %@NL@%
  26061.     case WM_COMMAND:%@NL@%
  26062.         switch (SHORT1FROMMP(mp1))%@NL@%
  26063.         {%@NL@%
  26064.         case IDD_OK:%@NL@%
  26065.             global.cxFatPel = MyGetWindowLong(hwnd, IDD_PELWIDTH);%@NL@%
  26066.             global.cyFatPel = MyGetWindowLong(hwnd, IDD_PELHEIGHT);%@NL@%
  26067. %@NL@%
  26068.             if (global.cxFatPel < 1L)%@NL@%
  26069.                 global.cxFatPel = 1L;%@NL@%
  26070. %@NL@%
  26071.             if (global.cyFatPel < 1L)%@NL@%
  26072.                 global.cyFatPel = 1L;%@NL@%
  26073. %@NL@%
  26074.             global.cxHalfFatPel = global.cxFatPel / 2L;%@NL@%
  26075.             global.cyHalfFatPel = global.cyFatPel / 2L;%@NL@%
  26076. %@NL@%
  26077.             global.usPelShape = SHORT1FROMMR( WinSendDlgItemMsg(hwnd, IDD_SQUARE,%@NL@%
  26078.                                    BM_QUERYCHECKINDEX, 0L, 0L) + IDD_SQUARE);%@NL@%
  26079. %@NL@%
  26080. %@NL@%
  26081.             UpdateSurfaceDims();%@NL@%
  26082. %@NL@%
  26083.             fRet = TRUE;%@NL@%
  26084. %@NL@%
  26085.             %@AB@%/* fall through to some common code */%@AE@%%@NL@%
  26086. %@NL@%
  26087.         case IDD_CANCEL:%@NL@%
  26088.             WinDismissDlg(hwnd, fRet);%@NL@%
  26089.             break;%@NL@%
  26090. %@NL@%
  26091.         default:%@NL@%
  26092.             return FALSE;%@NL@%
  26093.         }%@NL@%
  26094.         break;%@NL@%
  26095. %@NL@%
  26096.     default:%@NL@%
  26097.         return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);%@NL@%
  26098.     }%@NL@%
  26099.     return FALSE;%@NL@%
  26100. }%@NL@%
  26101. %@NL@%
  26102. %@NL@%
  26103. %@NL@%
  26104. %@NL@%
  26105. %@AB@%/************************************************************************%@NL@%
  26106. %@AB@%*%@NL@%
  26107. %@AB@%*   ColorsDlg%@NL@%
  26108. %@AB@%*%@NL@%
  26109. %@AB@%*   Process messages for the Set Colors dialog box.%@NL@%
  26110. %@AB@%*%@NL@%
  26111. %@AB@%************************************************************************/%@AE@%%@NL@%
  26112. %@NL@%
  26113. ULONG CALLBACK%@NL@%
  26114. ColorsDlg(hwnd, usMsg, mp1, mp2)%@NL@%
  26115. HWND   hwnd;%@NL@%
  26116. USHORT usMsg;%@NL@%
  26117. MPARAM mp1;%@NL@%
  26118. MPARAM mp2;%@NL@%
  26119. {%@NL@%
  26120.     BOOL fRet = FALSE;%@NL@%
  26121.     BOOL fRGB;%@NL@%
  26122.     COLOR clrMathObj;%@NL@%
  26123.     COLOR clrRenderedObj;%@NL@%
  26124.     COLOR clrField;%@NL@%
  26125.     COLOR clrCrossHair;%@NL@%
  26126.     COLOR clrInterstice;%@NL@%
  26127.     COLOR clrControlPoints;%@NL@%
  26128. %@NL@%
  26129.     switch (usMsg)%@NL@%
  26130.     {%@NL@%
  26131.     case WM_INITDLG:%@NL@%
  26132.         if (global.fRGB)%@NL@%
  26133.         {%@NL@%
  26134.             MySetWindowLongHex(hwnd, IDD_MATHOBJ,     global.clrMathObj);%@NL@%
  26135.             MySetWindowLongHex(hwnd, IDD_RENDEREDOBJ, global.clrRenderedObj);%@NL@%
  26136.             MySetWindowLongHex(hwnd, IDD_FIELD,             global.clrField);%@NL@%
  26137.             MySetWindowLongHex(hwnd, IDD_CROSSHAIRS,  global.clrCrossHair);%@NL@%
  26138.             MySetWindowLongHex(hwnd, IDD_INTERSTICE,  global.clrInterstice);%@NL@%
  26139.             MySetWindowLongHex(hwnd, IDD_CTLPOINTS,   global.clrControlPoints);%@NL@%
  26140.         }%@NL@%
  26141.         else%@NL@%
  26142.         {%@NL@%
  26143.             MySetWindowLong   (hwnd, IDD_MATHOBJ,     global.clrMathObj);%@NL@%
  26144.             MySetWindowLong   (hwnd, IDD_RENDEREDOBJ, global.clrRenderedObj);%@NL@%
  26145.             MySetWindowLong   (hwnd, IDD_FIELD,             global.clrField);%@NL@%
  26146.             MySetWindowLong   (hwnd, IDD_CROSSHAIRS,  global.clrCrossHair);%@NL@%
  26147.             MySetWindowLong   (hwnd, IDD_INTERSTICE,  global.clrInterstice);%@NL@%
  26148.             MySetWindowLong   (hwnd, IDD_CTLPOINTS,   global.clrControlPoints);%@NL@%
  26149.         }%@NL@%
  26150.         WinSendDlgItemMsg(hwnd, IDD_RGB, BM_SETCHECK, MPFROM2SHORT(global.fRGB,0), 0L);%@NL@%
  26151.         return FALSE;%@NL@%
  26152.         break;%@NL@%
  26153. %@NL@%
  26154.     case WM_CONTROL:%@NL@%
  26155.         if ((SHORT1FROMMP(mp1) == IDD_RGB) && (SHORT2FROMMP(mp1)== BN_CLICKED))%@NL@%
  26156.         {%@NL@%
  26157.             fRGB = !SHORT1FROMMR(WinSendDlgItemMsg(hwnd, IDD_RGB, BM_QUERYCHECK, 0L, 0L));%@NL@%
  26158.             WinSendDlgItemMsg(hwnd, IDD_RGB, BM_SETCHECK, MPFROM2SHORT(fRGB,0), 0L);%@NL@%
  26159. %@NL@%
  26160.             clrMathObj             = MyGetWindowLong(hwnd, IDD_MATHOBJ);%@NL@%
  26161.             clrRenderedObj   = MyGetWindowLong(hwnd, IDD_RENDEREDOBJ);%@NL@%
  26162.             clrField             = MyGetWindowLong(hwnd, IDD_FIELD);%@NL@%
  26163.             clrCrossHair     = MyGetWindowLong(hwnd, IDD_CROSSHAIRS);%@NL@%
  26164.             clrInterstice    = MyGetWindowLong(hwnd, IDD_INTERSTICE);%@NL@%
  26165.             clrControlPoints = MyGetWindowLong(hwnd, IDD_CTLPOINTS);%@NL@%
  26166. %@NL@%
  26167.             if (fRGB)%@NL@%
  26168.             {%@NL@%
  26169.                 HPS hps;%@NL@%
  26170. %@NL@%
  26171.                 %@AB@%/* for each color, get rgb value from index */%@AE@%%@NL@%
  26172. %@NL@%
  26173.                 hps = WinGetPS(hwnd);%@NL@%
  26174. %@NL@%
  26175.                 clrMathObj         = GpiQueryRGBColor(hps, 0L, clrMathObj);%@NL@%
  26176.                 clrRenderedObj         = GpiQueryRGBColor(hps, 0L, clrRenderedObj);%@NL@%
  26177.                 clrField         = GpiQueryRGBColor(hps, 0L, clrField);%@NL@%
  26178.                 clrCrossHair         = GpiQueryRGBColor(hps, 0L, clrCrossHair);%@NL@%
  26179.                 clrInterstice         = GpiQueryRGBColor(hps, 0L, clrInterstice);%@NL@%
  26180.                 clrControlPoints = GpiQueryRGBColor(hps, 0L, clrControlPoints);%@NL@%
  26181. %@NL@%
  26182.                 WinReleasePS(hps);%@NL@%
  26183. %@NL@%
  26184.                 MySetWindowLongHex(hwnd, IDD_MATHOBJ,         clrMathObj);%@NL@%
  26185.                 MySetWindowLongHex(hwnd, IDD_RENDEREDOBJ, clrRenderedObj);%@NL@%
  26186.                 MySetWindowLongHex(hwnd, IDD_FIELD,         clrField);%@NL@%
  26187.                 MySetWindowLongHex(hwnd, IDD_CROSSHAIRS,  clrCrossHair);%@NL@%
  26188.                 MySetWindowLongHex(hwnd, IDD_INTERSTICE,  clrInterstice);%@NL@%
  26189.                 MySetWindowLongHex(hwnd, IDD_CTLPOINTS,         clrControlPoints);%@NL@%
  26190.             }%@NL@%
  26191.             else%@NL@%
  26192.             {%@NL@%
  26193.                 HPS hps;%@NL@%
  26194. %@NL@%
  26195.                 %@AB@%/* for each color, get nearest index value from rgb */%@AE@%%@NL@%
  26196. %@NL@%
  26197.                 hps = WinGetPS(hwnd);%@NL@%
  26198. %@NL@%
  26199.                 clrMathObj         = GpiQueryColorIndex(hps, 0L, clrMathObj);%@NL@%
  26200.                 clrRenderedObj         = GpiQueryColorIndex(hps, 0L, clrRenderedObj);%@NL@%
  26201.                 clrField         = GpiQueryColorIndex(hps, 0L, clrField);%@NL@%
  26202.                 clrCrossHair         = GpiQueryColorIndex(hps, 0L, clrCrossHair);%@NL@%
  26203.                 clrInterstice         = GpiQueryColorIndex(hps, 0L, clrInterstice);%@NL@%
  26204.                 clrControlPoints = GpiQueryColorIndex(hps, 0L, clrControlPoints);%@NL@%
  26205. %@NL@%
  26206.                 WinReleasePS(hps);%@NL@%
  26207. %@NL@%
  26208.                 MySetWindowLong   (hwnd, IDD_MATHOBJ,         clrMathObj);%@NL@%
  26209.                 MySetWindowLong   (hwnd, IDD_RENDEREDOBJ, clrRenderedObj);%@NL@%
  26210.                 MySetWindowLong   (hwnd, IDD_FIELD,         clrField);%@NL@%
  26211.                 MySetWindowLong   (hwnd, IDD_CROSSHAIRS,  clrCrossHair);%@NL@%
  26212.                 MySetWindowLong   (hwnd, IDD_INTERSTICE,  clrInterstice);%@NL@%
  26213.                 MySetWindowLong   (hwnd, IDD_CTLPOINTS,         clrControlPoints);%@NL@%
  26214.             }%@NL@%
  26215.         }%@NL@%
  26216.         return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);%@NL@%
  26217.         break;%@NL@%
  26218. %@NL@%
  26219.     case WM_COMMAND:%@NL@%
  26220.         switch (SHORT1FROMMP(mp1))%@NL@%
  26221.         {%@NL@%
  26222.         case IDD_OK:%@NL@%
  26223.             global.clrMathObj            = MyGetWindowLong(hwnd, IDD_MATHOBJ);%@NL@%
  26224.             global.clrRenderedObj   = MyGetWindowLong(hwnd, IDD_RENDEREDOBJ);%@NL@%
  26225.             global.clrField            = MyGetWindowLong(hwnd, IDD_FIELD);%@NL@%
  26226.             global.clrCrossHair     = MyGetWindowLong(hwnd, IDD_CROSSHAIRS);%@NL@%
  26227.             global.clrInterstice    = MyGetWindowLong(hwnd, IDD_INTERSTICE);%@NL@%
  26228.             global.clrControlPoints = MyGetWindowLong(hwnd, IDD_CTLPOINTS);%@NL@%
  26229. %@NL@%
  26230.             global.fRGB = SHORT1FROMMR(WinSendDlgItemMsg(hwnd, IDD_RGB, BM_QUERYCHECK, 0L, 0L));%@NL@%
  26231. %@NL@%
  26232.             fRet = TRUE;%@NL@%
  26233. %@NL@%
  26234.             %@AB@%/* fall through to some common code */%@AE@%%@NL@%
  26235. %@NL@%
  26236.         case IDD_CANCEL:%@NL@%
  26237.             WinDismissDlg(hwnd, fRet);%@NL@%
  26238.             break;%@NL@%
  26239. %@NL@%
  26240.         default:%@NL@%
  26241.             return FALSE;%@NL@%
  26242.         }%@NL@%
  26243.         break;%@NL@%
  26244. %@NL@%
  26245.     default:%@NL@%
  26246.         return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);%@NL@%
  26247.     }%@NL@%
  26248.     return FALSE;%@NL@%
  26249. }%@NL@%
  26250. %@NL@%
  26251.             %@NL@%
  26252. %@NL@%
  26253. %@NL@%
  26254. %@AB@%/************************************************************************%@NL@%
  26255. %@AB@%*%@NL@%
  26256. %@AB@%*   MySetWindowLong%@NL@%
  26257. %@AB@%*%@NL@%
  26258. %@AB@%*   Sets the given control id to the value specified.%@NL@%
  26259. %@AB@%*%@NL@%
  26260. %@AB@%************************************************************************/%@AE@%%@NL@%
  26261. %@NL@%
  26262. VOID%@NL@%
  26263. MySetWindowLong(hWnd, id, num)%@NL@%
  26264. HWND hWnd;%@NL@%
  26265. USHORT id;%@NL@%
  26266. LONG num;%@NL@%
  26267. {%@NL@%
  26268.     char szStr[CCHSTR];%@NL@%
  26269. %@NL@%
  26270.     sprintf((NPCH)szStr, "%ld", num);%@NL@%
  26271.     WinSetWindowText(WinWindowFromID(hWnd, id), (PCH)szStr);%@NL@%
  26272. }%@NL@%
  26273. %@NL@%
  26274. %@NL@%
  26275. %@NL@%
  26276. %@NL@%
  26277. %@AB@%/************************************************************************%@NL@%
  26278. %@AB@%*%@NL@%
  26279. %@AB@%*   MySetWindowLongHex%@NL@%
  26280. %@AB@%*%@NL@%
  26281. %@AB@%*   Sets the given control id to the value specified, in hexadecimal%@NL@%
  26282. %@AB@%*   notation.%@NL@%
  26283. %@AB@%*%@NL@%
  26284. %@AB@%************************************************************************/%@AE@%%@NL@%
  26285. %@NL@%
  26286. VOID%@NL@%
  26287. MySetWindowLongHex(hWnd, id, num)%@NL@%
  26288. HWND hWnd;%@NL@%
  26289. USHORT id;%@NL@%
  26290. LONG num;%@NL@%
  26291. {%@NL@%
  26292.     char szStr[CCHSTR];%@NL@%
  26293. %@NL@%
  26294.     sprintf((NPCH)szStr, "0x%06lX", num);%@NL@%
  26295.     WinSetWindowText(WinWindowFromID(hWnd, id), (PCH)szStr);%@NL@%
  26296. }%@NL@%
  26297. %@NL@%
  26298. %@NL@%
  26299. %@NL@%
  26300. %@NL@%
  26301. %@AB@%/************************************************************************%@NL@%
  26302. %@AB@%*%@NL@%
  26303. %@AB@%*   MyGetWindowLong%@NL@%
  26304. %@AB@%*%@NL@%
  26305. %@AB@%*   Returns the value from the given control id.%@NL@%
  26306. %@AB@%*%@NL@%
  26307. %@AB@%************************************************************************/%@AE@%%@NL@%
  26308. %@NL@%
  26309. LONG%@NL@%
  26310. MyGetWindowLong(hWnd, id)%@NL@%
  26311. HWND hWnd;%@NL@%
  26312. USHORT id;%@NL@%
  26313. {%@NL@%
  26314.     char szStr[CCHSTR];%@NL@%
  26315.     LONG num;%@NL@%
  26316. %@NL@%
  26317.     WinQueryWindowText(WinWindowFromID(hWnd, id), CCHSTR, (PCH)szStr);%@NL@%
  26318. %@NL@%
  26319.     if (strchr(szStr, 'x'))%@NL@%
  26320.         sscanf((NPCH)szStr, "0x%lx", &num);%@NL@%
  26321.     else if (strchr(szStr, 'X'))%@NL@%
  26322.         sscanf((NPCH)szStr, "0X%lx", &num);%@NL@%
  26323.     else%@NL@%
  26324.         sscanf((NPCH)szStr, "%ld", &num);%@NL@%
  26325. %@NL@%
  26326.     return num;%@NL@%
  26327. }%@NL@%
  26328. %@NL@%
  26329. %@NL@%
  26330. %@NL@%
  26331. %@NL@%
  26332. %@AB@%/************************************************************************%@NL@%
  26333. %@AB@%*%@NL@%
  26334. %@AB@%*   SaveWindowToFile%@NL@%
  26335. %@AB@%*%@NL@%
  26336. %@AB@%*   Copy the bits from the client rectangle (actually, just the fatpel%@NL@%
  26337. %@AB@%*   area) into a bitmap, then save that bitmap.%@NL@%
  26338. %@AB@%*%@NL@%
  26339. %@AB@%************************************************************************/%@AE@%%@NL@%
  26340. %@NL@%
  26341. VOID%@NL@%
  26342. SaveWindowToFile(hwnd)%@NL@%
  26343. HWND hwnd;%@NL@%
  26344. {%@NL@%
  26345.     BITMAPINFOHEADER bminfo;%@NL@%
  26346.     HBITMAP hbm;%@NL@%
  26347.     HPS hps;%@NL@%
  26348.     POINTL aptl[3];%@NL@%
  26349. %@NL@%
  26350.     %@AB@%/* create bitmap in display's favorite format */%@AE@%%@NL@%
  26351.     bminfo.cbFix = sizeof(BITMAPINFOHEADER);%@NL@%
  26352.     bminfo.cx = (USHORT) (global.rcl.xRight - global.rcl.xLeft);%@NL@%
  26353.     bminfo.cy = (USHORT) (global.rcl.yTop   - global.rcl.yBottom);%@NL@%
  26354.     bminfo.cPlanes   = 0L;%@NL@%
  26355.     bminfo.cBitCount = 0L;%@NL@%
  26356.     if (hbm = GpiCreateBitmap(global.hpsFat, &bminfo, 0L, 0L, 0L))%@NL@%
  26357.     {%@NL@%
  26358.         %@AB@%/* select it into the small bitmap's PS */%@AE@%%@NL@%
  26359.         GpiSetBitmap(global.hpsFat, hbm);%@NL@%
  26360. %@NL@%
  26361.         %@AB@%/* GpiBitBlt from the window to the bitmap */%@AE@%%@NL@%
  26362.         hps = WinGetPS(hwnd);%@NL@%
  26363. %@NL@%
  26364.         *((PRECTL)&aptl[0]) = global.rcl;%@NL@%
  26365.         aptl[2].x = 0L;%@NL@%
  26366.         aptl[2].y = 0L;%@NL@%
  26367.         GpiBitBlt(global.hpsFat, hps, 3L, aptl, ROP_SRCCOPY, 0L);%@NL@%
  26368. %@NL@%
  26369.         WinReleasePS(hps);%@NL@%
  26370. %@NL@%
  26371.         %@AB@%/* save the bitmap */%@AE@%%@NL@%
  26372.         WriteFile(hwnd, global.hpsFat);%@NL@%
  26373.     }%@NL@%
  26374. %@NL@%
  26375.     %@AB@%/* deselect the bitmap and delete it */%@AE@%%@NL@%
  26376.     GpiSetBitmap(global.hpsFat, global.hbmFat);%@NL@%
  26377.     if (hbm)%@NL@%
  26378.         GpiDeleteBitmap(hbm);%@NL@%
  26379. }%@NL@%
  26380. %@NL@%
  26381. %@NL@%
  26382. %@NL@%
  26383. %@NL@%
  26384. %@AB@%/************************************************************************%@NL@%
  26385. %@AB@%*%@NL@%
  26386. %@AB@%*   WriteFile%@NL@%
  26387. %@AB@%*%@NL@%
  26388. %@AB@%*   Calls the OpenDlg's DlgFile function to ask the user what file name to%@NL@%
  26389. %@AB@%*   save under.%@NL@%
  26390. %@AB@%*%@NL@%
  26391. %@AB@%************************************************************************/%@AE@%%@NL@%
  26392. %@NL@%
  26393. VOID%@NL@%
  26394. WriteFile(hwnd, hps)%@NL@%
  26395. HWND hwnd;%@NL@%
  26396. HPS hps;%@NL@%
  26397. {%@NL@%
  26398.     HFILE hfile;%@NL@%
  26399.     DLF dlf;%@NL@%
  26400.     BITMAPINFOHEADER bmih;%@NL@%
  26401. %@NL@%
  26402.     dlf.rgbAction        = DLG_SAVEDLG;%@NL@%
  26403.     dlf.rgbFlags        = 0;%@NL@%
  26404.     dlf.phFile                = &hfile;%@NL@%
  26405.     dlf.pszExt                = "";%@NL@%
  26406.     dlf.pszAppName        = "FatPel";%@NL@%
  26407.     dlf.pszInstructions = NULL;%@NL@%
  26408.     dlf.szFileName[0]        = '\0';%@NL@%
  26409.     dlf.szOpenFile[0]        = '\0';%@NL@%
  26410.     dlf.pszTitle        = "Save Bitmap";%@NL@%
  26411. %@NL@%
  26412. %@NL@%
  26413.     switch (DlgFile(hwnd,&dlf))%@NL@%
  26414.     {%@NL@%
  26415.     case TDF_ERRMEM:%@NL@%
  26416.     case TDF_INVALID:%@NL@%
  26417.         MyMessageBox(hwnd, "Error opening file.");%@NL@%
  26418.         break;%@NL@%
  26419. %@NL@%
  26420.     case TDF_NOSAVE:%@NL@%
  26421.         break;%@NL@%
  26422. %@NL@%
  26423.     default:%@NL@%
  26424.         bmih.cbFix     = sizeof(BITMAPINFOHEADER);%@NL@%
  26425.         bmih.cx        = (USHORT) global.rcl.xRight;%@NL@%
  26426.         bmih.cy        = (USHORT) global.rcl.yTop;%@NL@%
  26427.         bmih.cPlanes   = 0L;%@NL@%
  26428.         bmih.cBitCount = 0L;%@NL@%
  26429. %@NL@%
  26430.         if (!WriteBMP(hfile, hps, &bmih))%@NL@%
  26431.             MyMessageBox(hwnd, "Error writing file.");%@NL@%
  26432.     }%@NL@%
  26433. }%@NL@%
  26434. %@NL@%
  26435. %@NL@%
  26436. %@NL@%
  26437. %@NL@%
  26438. %@AB@%/************************************************************************%@NL@%
  26439. %@AB@%*%@NL@%
  26440. %@AB@%*   WriteBMP%@NL@%
  26441. %@AB@%*%@NL@%
  26442. %@AB@%*   Write the bitmap out to a BMP format file.        Write the file%@NL@%
  26443. %@AB@%*   header first, then the bitmap bits.  Space for the header%@NL@%
  26444. %@AB@%*   and the bits is allocated.        Huge bitmaps are supported.%@NL@%
  26445. %@AB@%*   Free up memory and close the file before leaving.  The file%@NL@%
  26446. %@AB@%*   will have been opened by the time this function is called,%@NL@%
  26447. %@AB@%*   and the file handle will be in the *pdlf structure.%@NL@%
  26448. %@AB@%*%@NL@%
  26449. %@AB@%************************************************************************/%@AE@%%@NL@%
  26450. %@NL@%
  26451. BOOL%@NL@%
  26452. WriteBMP(hfile, hps, pbmih)%@NL@%
  26453. HFILE hfile;%@NL@%
  26454. HPS hps;                 %@AB@%/* hps from which to get bitmap bits.           */%@AE@%%@NL@%
  26455. PBITMAPINFOHEADER pbmih; %@AB@%/* Bitmap information.                    */%@AE@%%@NL@%
  26456. {%@NL@%
  26457.     ULONG cScans;%@NL@%
  26458.     ULONG ulSize;         %@AB@%/* Number of bytes occupied by bitmap bits.             */%@AE@%%@NL@%
  26459.     USHORT cSegs;         %@AB@%/* Number of 64K segments in ulSize.                     */%@AE@%%@NL@%
  26460.     USHORT cbExtra;         %@AB@%/* Bytes in last segment of ulSize.                     */%@AE@%%@NL@%
  26461.     SEL selBits;         %@AB@%/* Base selector to bitmap bits.                     */%@AE@%%@NL@%
  26462.     USHORT hugeshift;         %@AB@%/* Segment index shift value.                             */%@AE@%%@NL@%
  26463.     USHORT cbBMHdr;         %@AB@%/* Size of bitmap header.                             */%@AE@%%@NL@%
  26464.     PBITMAPFILEHEADER pbfh; %@AB@%/* Pointer to private copy of bitmap info data.        */%@AE@%%@NL@%
  26465.     USHORT cbWrite1;         %@AB@%/* Number of bytes to write first call to DosWrite  */%@AE@%%@NL@%
  26466.     USHORT cbWrite2;         %@AB@%/* Number of bytes to write second call to DosWrite */%@AE@%%@NL@%
  26467.     USHORT cbWritten;         %@AB@%/* Number of bytes written by DosWrite.             */%@AE@%%@NL@%
  26468.     BOOL fRet = FALSE;         %@AB@%/* Function return code.                             */%@AE@%%@NL@%
  26469.     int i;                 %@AB@%/* Generic loop index.                              */%@AE@%%@NL@%
  26470.     struct%@NL@%
  26471.     {%@NL@%
  26472.         LONG cPlanes;%@NL@%
  26473.         LONG cBitCount;%@NL@%
  26474.     } bmFmt;%@NL@%
  26475. %@NL@%
  26476. %@NL@%
  26477.     %@AB@%/*******************************************************************%@NL@%
  26478. %@AB@%    * If the bitmap was created with either 0 planes or 0 bits per%@NL@%
  26479. %@AB@%    * pixel, then query the format to write with.  By asking for just%@NL@%
  26480. %@AB@%    * one format (two LONGs, or one instance of structure of bmFmt),%@NL@%
  26481. %@AB@%    * we'll get the device's favored format.%@NL@%
  26482. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26483. %@NL@%
  26484.     if ((pbmih->cPlanes == 0) || (pbmih->cBitCount == 0))%@NL@%
  26485.     {%@NL@%
  26486.         if (!GpiQueryDeviceBitmapFormats(hps, 2L, (PLONG)&bmFmt))%@NL@%
  26487.             goto lfwrite_error_close_file;%@NL@%
  26488.     }%@NL@%
  26489.     else%@NL@%
  26490.     {%@NL@%
  26491.         bmFmt.cPlanes        = pbmih->cPlanes;%@NL@%
  26492.         bmFmt.cBitCount = pbmih->cBitCount;%@NL@%
  26493.     }%@NL@%
  26494. %@NL@%
  26495. %@NL@%
  26496.     %@AB@%/*******************************************************************%@NL@%
  26497. %@AB@%    * Determine size of bitmap header.        The header consists of a%@NL@%
  26498. %@AB@%    * a fixed-size part and a variable-length color table.  The%@NL@%
  26499. %@AB@%    * latter has  2^cBitCount  entries, each of which is sizeof(RGB)%@NL@%
  26500. %@AB@%    * bytes long.  The exception is when cBitCount is 24, in which%@NL@%
  26501. %@AB@%    * case the color table is omitted because the pixels are direct%@NL@%
  26502. %@AB@%    * rgb values.%@NL@%
  26503. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26504. %@NL@%
  26505.     i = (int) bmFmt.cBitCount;%@NL@%
  26506.     if (i == 24)%@NL@%
  26507.         cbBMHdr = 0;%@NL@%
  26508.     else%@NL@%
  26509.         for (cbBMHdr = sizeof(RGB); i > 0; --i)%@NL@%
  26510.             cbBMHdr *= 2;%@NL@%
  26511.     cbBMHdr += sizeof(BITMAPFILEHEADER);%@NL@%
  26512. %@NL@%
  26513. %@NL@%
  26514.     %@AB@%/*******************************************************************%@NL@%
  26515. %@AB@%    * Copy structure from input to work buffer.  The call to%@NL@%
  26516. %@AB@%    * GpiQueryBitmapBits will have write-access to this, so we won't%@NL@%
  26517. %@AB@%    * let it have the user's data.%@NL@%
  26518. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26519. %@NL@%
  26520.     pbfh = 0;%@NL@%
  26521.     if (DosAllocSeg(cbBMHdr, ((PUSHORT)&pbfh)+1, 0))%@NL@%
  26522.         goto lfwrite_error_close_file;%@NL@%
  26523.     pbfh->bmp = *pbmih;%@NL@%
  26524.     if ((pbmih->cPlanes == 0) || (pbmih->cBitCount))%@NL@%
  26525.     {%@NL@%
  26526.         pbfh->bmp.cPlanes   = (USHORT) bmFmt.cPlanes;%@NL@%
  26527.         pbfh->bmp.cBitCount = (USHORT) bmFmt.cBitCount;%@NL@%
  26528.     }%@NL@%
  26529. %@NL@%
  26530. %@NL@%
  26531.     %@AB@%/*******************************************************************%@NL@%
  26532. %@AB@%    * Allocate space for the bitmap bits -- all of them at once.%@NL@%
  26533. %@AB@%    * The extra ULONG casts are there to force all the arithmetic%@NL@%
  26534. %@AB@%    * to be done in 32 bits.%@NL@%
  26535. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26536. %@NL@%
  26537.     ulSize = (%@NL@%
  26538.                (%@NL@%
  26539.                  (%@NL@%
  26540.                    (ULONG)pbfh->bmp.cBitCount%@NL@%
  26541.                    * (ULONG)pbfh->bmp.cx%@NL@%
  26542.                    + 31L%@NL@%
  26543.                  ) / 32L%@NL@%
  26544.                ) * (ULONG)pbfh->bmp.cPlanes * 4L%@NL@%
  26545.              ) * (ULONG)pbfh->bmp.cy;%@NL@%
  26546. %@NL@%
  26547.     cSegs   = (USHORT)(ulSize/0x10000L);%@NL@%
  26548.     cbExtra = (USHORT)(ulSize%0x10000L);%@NL@%
  26549.     if (DosAllocHuge(cSegs, cbExtra, (PSEL)&selBits, 0, 0))%@NL@%
  26550.         goto lfwrite_error_free_header;%@NL@%
  26551.     if (DosGetHugeShift(&hugeshift))%@NL@%
  26552.         goto lfwrite_error_free_bits;%@NL@%
  26553. %@NL@%
  26554. %@NL@%
  26555.     %@AB@%/*******************************************************************%@NL@%
  26556. %@AB@%    * Tell GPI to give us the bits. The function returns the number%@NL@%
  26557. %@AB@%    * of scan lines of the bitmap that were copied.  We want all of%@NL@%
  26558. %@AB@%    * them at once.%@NL@%
  26559. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26560. %@NL@%
  26561.     cScans = GpiQueryBitmapBits( hps%@NL@%
  26562.                                , 0L%@NL@%
  26563.                                , (ULONG)pbfh->bmp.cy%@NL@%
  26564.                                , (PBYTE)MAKEP(selBits, 0)%@NL@%
  26565.                                , (PBITMAPINFO)&pbfh->bmp);%@NL@%
  26566.     if (cScans != pbfh->bmp.cy)  %@AB@%/* compare with original number of scans */%@AE@%%@NL@%
  26567.         goto lfwrite_error_free_bits;%@NL@%
  26568. %@NL@%
  26569. %@NL@%
  26570.     %@AB@%/*******************************************************************%@NL@%
  26571. %@AB@%    * Fill in the extra header fields and write the header out to%@NL@%
  26572. %@AB@%    * the file.%@NL@%
  26573. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26574. %@NL@%
  26575.     pbfh->usType    = 0x4D42;                  %@AB@%/* 'MB' */%@AE@%%@NL@%
  26576.     pbfh->cbSize    = ulSize + cbBMHdr;%@NL@%
  26577.     pbfh->xHotspot  = pbfh->bmp.cx / 2;%@NL@%
  26578.     pbfh->yHotspot  = pbfh->bmp.cy / 2;%@NL@%
  26579.     pbfh->offBits   = cbBMHdr;%@NL@%
  26580. %@NL@%
  26581.     if (DosWrite( hfile%@NL@%
  26582.                 , (PVOID)pbfh%@NL@%
  26583.                 , cbBMHdr%@NL@%
  26584.                 , &cbWritten))%@NL@%
  26585.         goto lfwrite_error_free_bits;%@NL@%
  26586.     if (cbWritten != cbBMHdr)%@NL@%
  26587.         goto lfwrite_error_free_bits;%@NL@%
  26588. %@NL@%
  26589. %@NL@%
  26590.     %@AB@%/*******************************************************************%@NL@%
  26591. %@AB@%    * Write the bits out to the file. The DosWrite function allows a%@NL@%
  26592. %@AB@%    * maximum of 64K-1 bytes written at a time.  We get around this%@NL@%
  26593. %@AB@%    * by writing two 32K chunks for each 64K segment, and writing the%@NL@%
  26594. %@AB@%    * last segment in one piece.%@NL@%
  26595. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26596. %@NL@%
  26597.     for (i = 0; i <= (SHORT) cSegs; ++i)%@NL@%
  26598.     {%@NL@%
  26599.         if (i < (SHORT) cSegs)%@NL@%
  26600.         {%@NL@%
  26601.             %@AB@%/* This segment is 64K bytes long, so split it up. */%@AE@%%@NL@%
  26602.             cbWrite1 = 0x8000;%@NL@%
  26603.             cbWrite2 = 0x8000;%@NL@%
  26604.         }%@NL@%
  26605.         else%@NL@%
  26606.         {%@NL@%
  26607.             %@AB@%/* This segment is less than 64K bytes long, so write it all. */%@AE@%%@NL@%
  26608.             cbWrite1 = cbExtra;%@NL@%
  26609.             cbWrite2 = 0;%@NL@%
  26610.         }%@NL@%
  26611. %@NL@%
  26612.         %@AB@%/* There's a possibility that cbExtra will be 0, so check%@NL@%
  26613. %@AB@%         * to avoid an unnecessary system call.%@NL@%
  26614. %@AB@%         */%@AE@%%@NL@%
  26615.         if (cbWrite1 > 0)%@NL@%
  26616.         {%@NL@%
  26617.             if (DosWrite( hfile%@NL@%
  26618.                         , (PVOID)MAKEP(selBits+(i<<hugeshift), 0)%@NL@%
  26619.                         , cbWrite1%@NL@%
  26620.                         , &cbWritten))%@NL@%
  26621.                 goto lfwrite_error_free_bits;%@NL@%
  26622.             if (cbWrite1 != cbWritten)%@NL@%
  26623.                 goto lfwrite_error_free_bits;%@NL@%
  26624.         }%@NL@%
  26625. %@NL@%
  26626.         %@AB@%/* This will always be skipped on the last partial segment. */%@AE@%%@NL@%
  26627.         if (cbWrite2 > 0)%@NL@%
  26628.         {%@NL@%
  26629.             if (DosWrite( hfile%@NL@%
  26630.                         , (PVOID)MAKEP(selBits+(i<<hugeshift), cbWrite1)%@NL@%
  26631.                         , cbWrite2%@NL@%
  26632.                         , &cbWritten))%@NL@%
  26633.                 goto lfwrite_error_free_bits;%@NL@%
  26634.             if (cbWrite2 != cbWritten)%@NL@%
  26635.                 goto lfwrite_error_free_bits;%@NL@%
  26636.         }%@NL@%
  26637.     }%@NL@%
  26638. %@NL@%
  26639.     fRet = TRUE;     %@AB@%/* The bits are on the disk. */%@AE@%%@NL@%
  26640. %@NL@%
  26641. %@NL@%
  26642.     %@AB@%/*******************************************************************%@NL@%
  26643. %@AB@%    * Close the file, free the buffer space and leave.        This is a%@NL@%
  26644. %@AB@%    * common exit point from the function.  Since the same cleanup%@NL@%
  26645. %@AB@%    * operations need to be performed for such a large number of%@NL@%
  26646. %@AB@%    * possible error conditions, this is concise way to do the right%@NL@%
  26647. %@AB@%    * thing.%@NL@%
  26648. %@AB@%    *******************************************************************/%@AE@%%@NL@%
  26649. %@NL@%
  26650. lfwrite_error_free_bits:%@NL@%
  26651.     DosFreeSeg(selBits);%@NL@%
  26652. lfwrite_error_free_header:%@NL@%
  26653.     DosFreeSeg(*((PUSHORT)&pbfh+1));%@NL@%
  26654. lfwrite_error_close_file:%@NL@%
  26655.     DosClose(hfile);%@NL@%
  26656.     return fRet;%@NL@%
  26657. }%@NL@%
  26658. %@NL@%
  26659. %@NL@%
  26660. %@NL@%
  26661. %@NL@%
  26662. %@AB@%/************************************************************************%@NL@%
  26663. %@AB@%*%@NL@%
  26664. %@AB@%*   MyMessageBox%@NL@%
  26665. %@AB@%*%@NL@%
  26666. %@AB@%*   Displays a message box with the given string.  To simplify matters,%@NL@%
  26667. %@AB@%*   the box will always have the same title ("FatPel"), will always%@NL@%
  26668. %@AB@%*   have a single button ("Ok"), will always have an exclamation point%@NL@%
  26669. %@AB@%*   icon, and will always be application modal.%@NL@%
  26670. %@AB@%*%@NL@%
  26671. %@AB@%************************************************************************/%@AE@%%@NL@%
  26672. %@NL@%
  26673. VOID%@NL@%
  26674. MyMessageBox(hWnd, sz)%@NL@%
  26675. HWND hWnd;%@NL@%
  26676. PSZ sz;%@NL@%
  26677. {%@NL@%
  26678.     static char *szTitle = "FatPel Application";%@NL@%
  26679. %@NL@%
  26680.     WinMessageBox(HWND_DESKTOP, hWnd, sz, szTitle, 0,%@NL@%
  26681.                   MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);%@NL@%
  26682. }%@NL@%
  26683. %@NL@%
  26684. %@NL@%
  26685. %@2@%%@AH@%FDIR.C%@AE@%%@EH@%%@NL@%
  26686. %@AS@%CD-ROM Disc Path:   \SAMPCODE\OS2SDK\OS2SDK12\FDIR\FDIR.C%@AE@%%@NL@%
  26687. %@NL@%
  26688. %@AB@%/*************************************************************%@NL@%
  26689. %@AB@%%@NL@%
  26690. %@AB@% This sample code demonstrates conversion from longnames to 8.3 and how%@NL@%
  26691. %@AB@% to determine the longname from the EA of a FAT file.%@NL@%
  26692. %@AB@% Should be compiled with the Large model.%@NL@%
  26693. %@AB@%%@NL@%
  26694. %@AB@% Written by Jeff Johnson 6/20/89%@NL@%
  26695. %@AB@%%@NL@%
  26696. %@AB@% This code was written to demonstrate two new features of OS/2 V1.2:%@NL@%
  26697. %@AB@% 1) How to convert long filenames to the appropriate 8.3 names.%@NL@%
  26698. %@AB@% 2) How to find a file's longname on a FAT system by checking its EA.%@NL@%
  26699. %@AB@%%@NL@%
  26700. %@AB@% Procedures in this file:%@NL@%
  26701. %@AB@%   main()             Does the main directory program calling support modules%@NL@%
  26702. %@AB@%   Convert_to_8dot3() Converts a longname to 8.3 name%@NL@%
  26703. %@AB@%   ParsePathName()    Breaks a full path into its 3 components%@NL@%
  26704. %@AB@%   QueryLongname()    Gets the .LONGNAME EA for a given file%@NL@%
  26705. %@AB@%   QueryIFS()         Determines the IFS type of a drive%@NL@%
  26706. %@AB@%%@NL@%
  26707. %@AB@%**************************************************************/%@AE@%%@NL@%
  26708. %@NL@%
  26709. %@AI@%#define %@AE@%INCL_DOSFILEMGR %@NL@%
  26710. %@AI@%#define %@AE@%INCL_BASE %@NL@%
  26711. %@AI@%#include %@AE@%<os2.h> %@NL@%
  26712. %@NL@%
  26713. %@AI@%#include %@AE@%<string.h> %@NL@%
  26714. %@AI@%#include %@AE@%<malloc.h> %@NL@%
  26715. %@AI@%#include %@AE@%<stdio.h> %@NL@%
  26716. %@NL@%
  26717. %@AI@%#define %@AE@%FAT  0 %@NL@%
  26718. %@AI@%#define %@AE@%HPFS 1 %@NL@%
  26719. %@AI@%#define %@AE@%GetInfoLevel1 0x0001 %@NL@%
  26720. %@AI@%#define %@AE@%GetInfoLevel3 0x0003 %@NL@%
  26721. %@NL@%
  26722. VOID Convert_to_8dot3(CHAR *,CHAR *);%@NL@%
  26723. VOID ParsePathName(CHAR *,CHAR *,CHAR *,CHAR *);%@NL@%
  26724. VOID QueryLongname(CHAR *,CHAR *);%@NL@%
  26725. VOID QueryIFS(CHAR *,PUSHORT,PUSHORT);%@NL@%
  26726. %@NL@%
  26727. %@NL@%
  26728. %@AB@%/*%@NL@%
  26729. %@AB@% * Function name: main()%@NL@%
  26730. %@AB@% *%@NL@%
  26731. %@AB@% * Parameters:  argc, argv.  If the user places a file spec on the command%@NL@%
  26732. %@AB@% *              line it is used to select/filter the directory listing.%@NL@%
  26733. %@AB@% *              Otherwise, the default directory is listed.%@NL@%
  26734. %@AB@% *%@NL@%
  26735. %@AB@% * Returns: Always exits with 0.%@NL@%
  26736. %@AB@% *%@NL@%
  26737. %@AB@% * Purpose: main() coordinates the directory process by calling the%@NL@%
  26738. %@AB@% *          appropriate setup routines, then handling the DosFindNext%@NL@%
  26739. %@AB@% *          loop for each file.%@NL@%
  26740. %@AB@% *%@NL@%
  26741. %@AB@% * Usage/Warnings:  Very little error checking is done as the code is written%@NL@%
  26742. %@AB@% *                  to demonstrate longname conversion/EA reading, not as%@NL@%
  26743. %@AB@% *                  a finished app.%@NL@%
  26744. %@AB@% *%@NL@%
  26745. %@AB@% * Calls: ParsePathName(), QueryIFS(), Convert_to_8dot3(), QueryLongname()%@NL@%
  26746. %@AB@% */%@AE@%%@NL@%
  26747. %@NL@%
  26748. main (int argc, char *argv[])%@NL@%
  26749. {%@NL@%
  26750.     USHORT uRetval,hdir=0xffff,SearchCount=1;%@NL@%
  26751.     PFILEFINDBUF pfbuf;%@NL@%
  26752.     char szDrive[3],szPath[260],szFilename[CCHMAXPATH],szFullPath[CCHMAXPATH];%@NL@%
  26753.     USHORT ifsloc,ifsname;%@NL@%
  26754.     char *szFilePtr,szLongName[260];%@NL@%
  26755. %@NL@%
  26756.     if(argc<2)%@NL@%
  26757.         ParsePathName("",szDrive,szPath,szFilename);%@NL@%
  26758.     else%@NL@%
  26759.         ParsePathName(argv[1],szDrive,szPath,szFilename);%@NL@%
  26760. %@NL@%
  26761.     if(strlen(szFilename) == 0)%@NL@%
  26762.         strcpy(szFilename,"*");%@NL@%
  26763. %@NL@%
  26764.     strcpy(szFullPath,szDrive);%@NL@%
  26765.     strcat(szFullPath,szPath);%@NL@%
  26766.     szFilePtr = szFullPath + strlen(szFullPath);%@NL@%
  26767.     strcat(szFullPath,szFilename);%@NL@%
  26768. %@NL@%
  26769.     QueryIFS(szDrive,&ifsloc,&ifsname);%@NL@%
  26770. %@NL@%
  26771.     if(ifsname != FAT && ifsname != HPFS)%@NL@%
  26772.     {%@NL@%
  26773.         printf("Unrecognized file system.\n");%@NL@%
  26774.         return 0;%@NL@%
  26775.     }%@NL@%
  26776. %@NL@%
  26777.     if(ifsname == FAT)%@NL@%
  26778.         printf("FAT -> HPFS directory listing\n");%@NL@%
  26779.     else%@NL@%
  26780.         printf("HPFS -> FAT directory listing\n");%@NL@%
  26781. %@NL@%
  26782. %@NL@%
  26783.     pfbuf = (PFILEFINDBUF) malloc(sizeof(FILEFINDBUF));%@NL@%
  26784.     uRetval=DosFindFirst(szFullPath,(PHDIR) &hdir,FILE_DIRECTORY,%@NL@%
  26785.                          pfbuf,sizeof(FILEFINDBUF),&SearchCount,0L);%@NL@%
  26786. %@NL@%
  26787.     if(uRetval)%@NL@%
  26788.     {%@NL@%
  26789.         printf("No files found.\n");%@NL@%
  26790.         return 0;%@NL@%
  26791.     }%@NL@%
  26792. %@NL@%
  26793.     do%@NL@%
  26794.     {%@NL@%
  26795.         if(ifsname == FAT)%@NL@%
  26796.         {%@NL@%
  26797.             strcpy(szFilePtr,pfbuf->achName);  %@AB@%/* Drop in name after path */%@AE@%%@NL@%
  26798. %@NL@%
  26799.             QueryLongname(szFullPath,szLongName);%@NL@%
  26800. %@NL@%
  26801.             if(strlen(szLongName) == 0)%@NL@%
  26802.                 printf("%s\n",pfbuf->achName);%@NL@%
  26803.             else%@NL@%
  26804.                 printf("%s\n",szLongName);%@NL@%
  26805.         }%@NL@%
  26806.         else   %@AB@%/* It's HPFS */%@AE@%%@NL@%
  26807.         {%@NL@%
  26808.             Convert_to_8dot3(pfbuf->achName,szFilename);%@NL@%
  26809.             printf("%s\n",szFilename);%@NL@%
  26810.         }%@NL@%
  26811.     } while(!(uRetval=DosFindNext(hdir,pfbuf,%@NL@%
  26812.                                   sizeof(FILEFINDBUF),&SearchCount)));%@NL@%
  26813. }%@NL@%
  26814. %@NL@%
  26815. %@NL@%
  26816. %@AB@%/*%@NL@%
  26817. %@AB@% * Function name: Convert_to_8dot3()%@NL@%
  26818. %@AB@% *%@NL@%
  26819. %@AB@% * Parameters:  szLong points to the input long file name.%@NL@%
  26820. %@AB@% *              szFat points to a return buffer for the FAT compatible name.%@NL@%
  26821. %@AB@% *%@NL@%
  26822. %@AB@% * Returns: VOID. The converted string is placed in szFat buffer.%@NL@%
  26823. %@AB@% *%@NL@%
  26824. %@AB@% * Purpose: Converts a HPFS longname to the standard 8.3 name.  This is%@NL@%
  26825. %@AB@% *          done as follows:  The extension is the first 3 characters after%@NL@%
  26826. %@AB@% *          the last dot, no extension if there are no dots.  The file stem%@NL@%
  26827. %@AB@% *          is at most 8 character and is taken from the beginning of the%@NL@%
  26828. %@AB@% *          longname string, replacing all dots with underscores.%@NL@%
  26829. %@AB@% *%@NL@%
  26830. %@AB@% * Usage/Warnings:  Should be bulletproof.  Exception code included to allow%@NL@%
  26831. %@AB@% *                  the special file name '..' through.%@NL@%
  26832. %@AB@% *%@NL@%
  26833. %@AB@% * Calls:%@NL@%
  26834. %@AB@% */%@AE@%%@NL@%
  26835. %@NL@%
  26836. VOID Convert_to_8dot3(CHAR *szLong,CHAR *szFat)%@NL@%
  26837. {%@NL@%
  26838.     USHORT usStemMaxLen; %@AB@%/* Holds the max size the 8 char base can be */%@AE@%%@NL@%
  26839.     USHORT cnt;%@NL@%
  26840.     CHAR   szStem[9],szExt[4];  %@AB@%/* Holds the Stem and Extension */%@AE@%%@NL@%
  26841.     CHAR   *szLastDot;          %@AB@%/* Pointer to the last dot */%@AE@%%@NL@%
  26842. %@NL@%
  26843.     if(!strcmp(szLong,"..")) %@AB@%/* Allow the predecessor file to pass thru */%@AE@%%@NL@%
  26844.     {%@NL@%
  26845.         strcpy(szFat,"..");%@NL@%
  26846.         return;%@NL@%
  26847.     }%@NL@%
  26848. %@NL@%
  26849.     szLastDot = strrchr(szLong,'.'); %@AB@%/* Find the last period */%@AE@%%@NL@%
  26850. %@NL@%
  26851.     if(szLastDot)  %@AB@%/* There is at least one period */%@AE@%%@NL@%
  26852.     {%@NL@%
  26853.         strncpy(szExt,szLastDot+1,3);       %@AB@%/* 1st 3 chars after . are ext */%@AE@%%@NL@%
  26854.         szExt[3]=0;%@NL@%
  26855.         usStemMaxLen = szLastDot - szLong;  %@AB@%/* Max stem is everything b4 . */%@AE@%%@NL@%
  26856.     }%@NL@%
  26857.     else%@NL@%
  26858.     {%@NL@%
  26859.         *szExt = 0;                         %@AB@%/* No extension */%@AE@%%@NL@%
  26860.         usStemMaxLen = strlen(szLong);      %@AB@%/* Stem can be whole string */%@AE@%%@NL@%
  26861.     }%@NL@%
  26862. %@NL@%
  26863.     if(usStemMaxLen>8)                      %@AB@%/* Limit stem to 8 chars */%@AE@%%@NL@%
  26864.         usStemMaxLen = 8;%@NL@%
  26865. %@NL@%
  26866.     for(cnt=0;cnt<usStemMaxLen;cnt++)       %@AB@%/* Copy in chars to form stem */%@AE@%%@NL@%
  26867.     {%@NL@%
  26868.         switch(szLong[cnt])%@NL@%
  26869.         {%@NL@%
  26870.             case '.':                       %@AB@%/* Convert .'s to _'s */%@AE@%%@NL@%
  26871.                 szStem[cnt] = '_';%@NL@%
  26872.                 break;%@NL@%
  26873.             default:                        %@AB@%/* Copy all other chars */%@AE@%%@NL@%
  26874.                 szStem[cnt] = szLong[cnt];%@NL@%
  26875.                 break;%@NL@%
  26876.         }%@NL@%
  26877.     }%@NL@%
  26878.     szStem[cnt] = 0;%@NL@%
  26879. %@NL@%
  26880.     %@AB@%/* Put it all together */%@AE@%%@NL@%
  26881.     strcpy(szFat,szStem);%@NL@%
  26882.     strcat(szFat,".");%@NL@%
  26883.     strcat(szFat,szExt);%@NL@%
  26884. }%@NL@%
  26885. %@NL@%
  26886. %@NL@%
  26887. %@AB@%/*%@NL@%
  26888. %@AB@% * Function name: ParsePathName()%@NL@%
  26889. %@AB@% *%@NL@%
  26890. %@AB@% * Parameters:  szFullPath points to the input full path name.%@NL@%
  26891. %@AB@% *              szDrive points to the return buffer for the drive letter.%@NL@%
  26892. %@AB@% *              szPath points to the return buffer for the path.%@NL@%
  26893. %@AB@% *              szFilename points to the return buffer for the Filename.%@NL@%
  26894. %@AB@% *%@NL@%
  26895. %@AB@% * Returns: VOID. The converted string is placed in last 3 passed params.%@NL@%
  26896. %@AB@% *%@NL@%
  26897. %@AB@% * Purpose: Break a full path string and break it into its three components.%@NL@%
  26898. %@AB@% *          If the passed string doesn't have a drive, the current letter is%@NL@%
  26899. %@AB@% *          fetched an placed in the return buffer.  The same is true for%@NL@%
  26900. %@AB@% *          the path buffer.%@NL@%
  26901. %@AB@% *%@NL@%
  26902. %@AB@% * Usage/Warnings:  Error checking should be done on the DOS calls.%@NL@%
  26903. %@AB@% *%@NL@%
  26904. %@AB@% * Calls:%@NL@%
  26905. %@AB@% */%@AE@%%@NL@%
  26906. %@NL@%
  26907. VOID ParsePathName(CHAR *szFullPath,CHAR *szDrive,CHAR *szPath,CHAR *szFilename)%@NL@%
  26908. {%@NL@%
  26909.     CHAR *szBack;          %@AB@%/* Used to find last backslach */%@AE@%%@NL@%
  26910.     USHORT usPathLen;      %@AB@%/* Holds the length of the path part of string */%@AE@%%@NL@%
  26911. %@NL@%
  26912.     *szPath = *szFilename = 0;%@NL@%
  26913. %@NL@%
  26914.     %@AB@%/* Do the Drive letter */%@AE@%%@NL@%
  26915.     if(*(szFullPath+1)==':')           %@AB@%/* If there is a drive letter */%@AE@%%@NL@%
  26916.     {%@NL@%
  26917.         szDrive[0] = *szFullPath;%@NL@%
  26918. %@NL@%
  26919.         szFullPath += 2;%@NL@%
  26920.     }%@NL@%
  26921.     else                               %@AB@%/* We take the default */%@AE@%%@NL@%
  26922.     {%@NL@%
  26923.         USHORT dno;  %@AB@%/* Drive number */%@AE@%%@NL@%
  26924.         ULONG  dmap; %@AB@%/* Map of available drives */%@AE@%%@NL@%
  26925. %@NL@%
  26926.         DosQCurDisk((PUSHORT) &dno,(PULONG) &dmap);%@NL@%
  26927.         *szDrive = (CHAR)( dno + 'A'-1);%@NL@%
  26928.     }%@NL@%
  26929.     szDrive[1] = ':';          %@AB@%/* Add the colon */%@AE@%%@NL@%
  26930.     szDrive[2] = (CHAR) 0;%@NL@%
  26931. %@NL@%
  26932.     %@AB@%/* Now do the path */%@AE@%%@NL@%
  26933.     szBack = strrchr(szFullPath,'\\');%@NL@%
  26934.     if(szBack)                         %@AB@%/* There is at least 1 backslash */%@AE@%%@NL@%
  26935.     {%@NL@%
  26936.        usPathLen = szBack - szFullPath + 1;%@NL@%
  26937.        strncpy(szPath,szFullPath,usPathLen);   %@AB@%/* Copy path */%@AE@%%@NL@%
  26938.        szPath[usPathLen] = (CHAR) 0;%@NL@%
  26939.     }%@NL@%
  26940.     else%@NL@%
  26941.     {%@NL@%
  26942.        *szPath = (CHAR) 0;%@NL@%
  26943.        szBack  = szFullPath-1;  %@AB@%/* Points 1 char before the file name */%@AE@%%@NL@%
  26944.     }%@NL@%
  26945. %@NL@%
  26946.     %@AB@%/* Finally do the file name */%@AE@%%@NL@%
  26947.     strcpy(szFilename,szBack+1);%@NL@%
  26948. }%@NL@%
  26949. %@NL@%
  26950. %@NL@%
  26951. %@AB@%/*%@NL@%
  26952. %@AB@% * Function name: QueryLongname()%@NL@%
  26953. %@AB@% *%@NL@%
  26954. %@AB@% * Parameters:  szfile points to the file to be queried.%@NL@%
  26955. %@AB@% *              szLong points to the return buffer for the long filename.%@NL@%
  26956. %@AB@% *%@NL@%
  26957. %@AB@% * Returns: VOID. The converted string is placed in last 3 passed params.%@NL@%
  26958. %@AB@% *%@NL@%
  26959. %@AB@% * Purpose: Looks for an EA named .LONGNAME attached to szfile.  If found,%@NL@%
  26960. %@AB@% *          it places the EA value in the return buffer.%@NL@%
  26961. %@AB@% *%@NL@%
  26962. %@AB@% * Usage/Warnings:  Routine assumes that the EA format is LP ASCII which%@NL@%
  26963. %@AB@% *                  is what the specs required, but probably the exception%@NL@%
  26964. %@AB@% *                  handling should be a bit tighter.  Return buf should be%@NL@%
  26965. %@AB@% *                  at least CCHMAXPATH long to accomodate max length names.%@NL@%
  26966. %@AB@% *                  Note also that no check is made to prevent overwriting%@NL@%
  26967. %@AB@% *                  the end of the return buffer.%@NL@%
  26968. %@AB@% *%@NL@%
  26969. %@AB@% * Calls:%@NL@%
  26970. %@AB@% */%@AE@%%@NL@%
  26971. %@NL@%
  26972. VOID QueryL