home *** CD-ROM | disk | FTP | other *** search
Text File | 2013-11-08 | 2.9 MB | 90,571 lines |
Text Truncated. Only the first 1MB is shown below. Download the file for the complete contents.
- OS/2 v1.2 Sample Code
-
-
- ACCEL.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\ACCEL\ACCEL.C
-
- /*
- * ACCEL.C -- Sample demonstrating calls included with INCL_WINACCELERATORS
- *
- * Overview:
- * Accelerators are used to reduce the number of keystrokes needed to
- * execute a command (hence "accelerating" a user's processing time)
- *
- * Strategy:
- * This application allows the user to experiment with various setting
- * by popping up a dialog box in which the user can specify an accelerator.
- * One possible modification to this program is to have the user hit the
- * desired key sequence, and to use KbdCharIn() to figure out what the key
- * sequence is, and then set the accelerator. Another is to implement the
- * "Delete" operation, by perhaps listing the accelerators in a list box.
- * This wasn't done primarily because that would require reorganization
- * (compression) of the accelerator table: it could not be easily done with
- * a WinDeleteAccel call (because such a call does not exist).
- */
- #define INCL_WINACCELERATORS
- #define INCL_WINBUTTONS // Needed for checkboxe
- #define INCL_WINDIALOGS
- #define INCL_WINMESSAGEMGR
- #define INCL_WINFRAMEMGR // for SC_MINIMIZE constant
- #define INCL_WINWINDOWMGR
- #include <os2.h>
-
- #include <malloc.h> // Needed for dynamic memory alloc
- #include <stdio.h> // Needed for sscanf() call
- #include "accel.h" // Needed for resource IDs
- /*
- * Globals
- */
- char ach[8]; // Temporary: used to store Key:
- char szAppName[] = "ACCEL.EXE";
- char szClassName[] = "Accelerator";
- char szMessage[] = " - Accelerator Table Example";
- int cbSize; // Size of Accel. Table in bytes
- int iTemp; // Used to store Key: value,
- void *pTemp; // Used so free() won't give warn
- HAB hab;
- HACCEL haccSystem; // Handle to system accelera
- HACCEL haccTable; // Handle to app-local accelt
- HMQ hmqAccel;
- HWND hwndAccel; // Client window
- HWND hwndAccelFrame; // Frame window
- PACCELTABLE pacctTable; // Points to table with ACCEL e
- /*
- Macros
- */
- #define Message(s) WinMessageBox(HWND_DESKTOP, HWND_DESKTOP, s, \
- szAppName, 0, MB_OK | MB_ICONEXCLAMATION)
- #define Check(b) WinSendDlgItemMsg(hwndDlg, b, \
- BM_SETCHECK, MPFROMSHORT(1), 0L)
- #define Checked(b) WinSendDlgItemMsg(hwndDlg, b, BM_QUERYCHECK, 0L, 0L)
- /*
- Internals
- */
- BOOL InitializeAccelTable(void);
- /*
- * Main routine...initializes window and message queue
- */
- void cdecl main(void) {
- QMSG qmsg;
- ULONG ctldata;
-
- /* Initialize a PM application */
- hab = WinInitialize(0);
- hmqAccel = WinCreateMsgQueue(hab, 0);
-
- /* Register the main window's class */
- if (!WinRegisterClass(hab, szClassName, AccelWndProc, CS_SIZEREDRAW, 0))
- return;
- /*
- Create the window
- We create it without an accelerator table, but we'll load one later
- */
- ctldata = FCF_STANDARD & ~FCF_ACCELTABLE;
- hwndAccelFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, &ctldata,
- szClassName, szMessage, WS_VISIBLE, (HMODULE) NULL, IDR_ACCEL, &hwndA
- WinShowWindow(hwndAccelFrame, TRUE);
- /*
- Load the accelerator tables
- */
- if (!InitializeAccelTable()) {
- Message("Accelerator table not initialized!");
- return;
- }
-
- /* Poll messages from event queue */
- while(WinGetMsg(hab, (PQMSG)&qmsg, (HWND)NULL, 0, 0))
- WinDispatchMsg(hab, (PQMSG)&qmsg);
-
- /* Clean up */
- if (!WinDestroyAccelTable(haccTable))
- Message("Could not destroy ACCELTABLE");
- WinDestroyWindow(hwndAccelFrame);
- WinDestroyMsgQueue(hmqAccel);
- WinTerminate(hab);
- }
-
- MRESULT CALLBACK AccelWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- /*
- * This routine processes WM_PAINT. It passes
- * everything else to the Default Window Procedure.
- */
- HPS hPS;
- RECTL rcl;
-
- switch (msg) {
-
- case WM_HELP:
- /* If WM_HELP, pop up Help dialog box */
- WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, (HMODULE) NULL, IDD_H
- break;
-
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
-
- /* On most WM_COMMAND messages, give the About... box */
- case IDM_ABOUT:
- WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc,
- (HMODULE) NULL, IDD_ABOUT, NULL);
- break;
-
- /* Create your own accelerator dialog */
- case IDM_CREATE:
- WinDlgBox(HWND_DESKTOP, hwnd, CreateDlgProc,
- (HMODULE) NULL, IDD_CREATE, NULL);
-
- default: break;
- }
- break;
-
- case WM_PAINT:
- /* Open the presentation space */
- hPS = WinBeginPaint(hwnd, NULL, &rcl);
-
- /* Fill the background with Dark Blue */
- WinFillRect(hPS, &rcl, CLR_DARKBLUE);
-
- /* Finish painting */
- WinEndPaint(hPS);
- break;
-
- default: return WinDefWindowProc(hwnd, msg, mp1, mp2); break;
- }
- return 0L;
- }
-
- MRESULT CALLBACK AboutDlgProc(hwndDlg, msg, mp1, mp2)
- /*
- About... dialog procedure
- */
- HWND hwndDlg;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hwndDlg, TRUE);
- default: break;
- }
- default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
- MRESULT CALLBACK CreateDlgProc(hwndDlg, msg, mp1, mp2)
- /*
- Create Accelerator dialog procedure
- */
- HWND hwndDlg;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch(msg) {
- case WM_INITDLG:
- /* Set the defaults */
- Check(IDD_CHAR); Check(IDD_CMD);
- break;
-
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK:
- /* Get the accelerator table (allocate an extra space) */
- cbSize = WinCopyAccelTable(haccTable, NULL, 0);
- pTemp = (void *) malloc(cbSize + sizeof(ACCEL));
- pacctTable = (PACCELTABLE) pTemp;
- cbSize = WinCopyAccelTable(haccTable, pacctTable, cbSize)
-
- #define accNew pacctTable->aaccel[pacctTable->cAccel]
-
- /*
- Command:
- if SYSCOMMAND, make the window minimize.
- if HELP, we'll pop up a dialog box.
- otherwise, pop up the About... dialog box.
- */
- if (Checked(IDD_SYSCMD)) accNew.cmd = SC_MINIMIZE;
- else accNew.cmd = IDM_ABOUT;
-
- /* Get the states from the dialog box */
- accNew.fs = 0;
- if (Checked(IDD_ALT)) accNew.fs |= AF_ALT;
- if (Checked(IDD_CHAR)) accNew.fs |= AF_CHAR;
- if (Checked(IDD_CONTROL)) accNew.fs |= AF_CONTROL;
- if (Checked(IDD_FHELP)) accNew.fs |= AF_HELP;
- if (Checked(IDD_LONEKEY)) accNew.fs |= AF_LONEKEY;
- if (Checked(IDD_SCANCODE)) accNew.fs |= AF_SCANCOD
- if (Checked(IDD_SHIFT)) accNew.fs |= AF_SHIFT;
- if (Checked(IDD_SYSCMD)) accNew.fs |= AF_SYSCOMMAN
- if (Checked(IDD_VKEY)) accNew.fs |= AF_VIRTUALKEY;
-
- /* Get the key to be defined */
- WinQueryDlgItemText(hwndDlg, IDD_ENTRY, 8, ach);
- if (('0' <= ach[0]) && (ach[0] <= '9')) {
- sscanf(ach, "%i", &iTemp);
- accNew.key = (USHORT) iTemp;
- }
- else accNew.key = (USHORT) ach[0];
-
- /* Increment the count of accelerator records */
- pacctTable->cAccel++;
-
- /* Cleanup, then create a new accelerator table */
- WinDestroyAccelTable(haccTable);
- haccTable = WinCreateAccelTable(hab, pacctTable);
-
- /* Set the new accelerator table, and clean up */
- WinSetAccelTable(hab, haccTable, hwndAccelFrame);
- free(pTemp);
-
- case DID_CANCEL:
- WinDismissDlg(hwndDlg, TRUE);
-
- default: break;
- }
- default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
- BOOL InitializeAccelTable(void) {
- /*
- Initialize the accelerator table by loading it from the
- resource file. Note that you can load an accelerator
- table from a DLL, if you change the NULL parameter.
- The system accelerator table is accessible after this
- call: one possible use for this would be a List...
- dialog box, which would list all system & app. accelerators.
- */
- haccSystem = WinQueryAccelTable(hab, NULL);
- haccTable = WinLoadAccelTable(hab, 0, IDR_ACCEL);
- return WinSetAccelTable(hab, haccTable, hwndAccelFrame);
- }
-
-
- APP.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\MDI\APP.C
-
- /***************************************************************************\
- * app.c - MDI Sample application
- *
- * Created by Microsoft Corporation, 1989
- *
- \***************************************************************************/
-
- #define INCL_WINSYS
- #define INCL_WINCOMMON
- #define INCL_WINMESSAGEMGR
- #define INCL_WINPOINTERS
- #define INCL_WININPUT
- #define INCL_WINMENUS
- #define INCL_WINFRAMEMGR
- #define INCL_WINWINDOWMGR
- #define INCL_WINRECTANGLES
- #define INCL_WINHEAP
- #define INCL_WINSCROLLBARS
- #define INCL_GPIPRIMITIVES
-
- #include <os2.h>
- #include "app.h"
- #include "appdata.h"
- #include "mdi.h"
- #include "mdidata.h"
-
-
- /*
- Function prototypes
- */
- BOOL AppInit(VOID);
- BOOL MDIInit(VOID);
- VOID AppTerminate(VOID);
- VOID MDITerminate(VOID);
- BOOL AppNewDocument(USHORT, PSZ);
- VOID TrackSplitbars(HWND, USHORT, SHORT, SHORT);
- VOID MDIDesktopSize(HWND, MPARAM, MPARAM);
- VOID MDIDesktopSetFocus(HWND, MPARAM);
- VOID MDIDesktopActivateDoc(SHORT idMenuitem);
- BOOL AppNewDocument(USHORT, PSZ);
- NPDOC MDINewDocument(USHORT fsStyle, PSZ pszClassName);
- VOID MDISetInitialDocPos(HWND hwndNewFrame);
-
- VOID AddToWindowMenu(NPDOC);
-
-
-
- int cdecl main(void)
- {
- QMSG qmsg;
- /*
- * Initialize the application globals
- * and create the main window.
- */
- if (AppInit() == FALSE) {
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- return(0);
- }
-
- /*
- * Initialize the MDI globals etc..
- */
- if (MDIInit() == FALSE) {
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- return(0);
- }
-
- /*
- * Create an initial, untitled document.
- */
- AppNewDocument(DS_HORZSPLITBAR | DS_VERTSPLITBAR, szDocClass);
-
- while (WinGetMsg(NULL, (PQMSG)&qmsg, NULL, 0, 0)) {
- WinDispatchMsg(NULL, (PQMSG)&qmsg);
- }
-
- /*
- * Do the clean-up of the MDI code.
- */
- MDITerminate();
-
- /*
- * Do the clean-up of the Application.
- */
- AppTerminate();
-
- DosExit(EXIT_PROCESS, 0);
- }
-
-
- MRESULT EXPENTRY MDIWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- HPS hps;
- RECTL rclPaint, rclWindow;
- POINTL ptlPatternRef;
-
- switch (msg) {
-
- case WM_PAINT:
- hps = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);
-
- /*
- * Set the pattern to be at the top-left
- * since we're top-left aligning the bits.
- */
- WinQueryWindowRect(hwnd, (PRECTL)&rclWindow);
- ptlPatternRef.x = rclWindow.xLeft;
- ptlPatternRef.y = rclWindow.yTop;
- GpiSetPatternRefPoint(hps, &ptlPatternRef);
-
- WinFillRect(hps, &rclPaint, SYSCLR_APPWORKSPACE);
-
- WinEndPaint(hps);
- break;
-
- #if 0
- case WM_SIZE:
-
- /* HACK -- only reposition the windows if it is not going to or comin
- from a minimized position, it would be better to what
- WM_WINDOWPOSCHANGED and pay attention to the fs fields of the SWP
- structure */
-
- if ( SHORT1FROMMP(mp1) && SHORT2FROMMP(mp1) &&
- SHORT1FROMMP(mp2) && SHORT2FROMMP(mp2) ) {
- MDIDesktopSize ( hwnd, mp1, mp2 );
- }
- break;
-
- #else
- case WM_SIZE:
- MDIDesktopSize ( hwnd, mp1, mp2 );
- break;
- #endif
-
- case WM_SETFOCUS:
- MDIDesktopSetFocus(hwnd, mp2);
- break;
-
- case WM_COMMAND:
- switch (SHORT1FROMMP(mp1)) {
-
- /*
- * Pass these accelerators onto the active document's
- * frame so it can process it.
- *
- * These are the CMD_ values from the document system
- * menu.
- */
- case CMD_DOCRESTORE:
- WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_RESTORE, mp2)
- break;
-
- case CMD_DOCNEXT:
- WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_NEXT, mp2);
- break;
-
- case CMD_DOCMINIMIZE:
- WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_MINIMIZE, mp2
- break;
-
- case CMD_DOCCLOSE:
- WinSendMsg(hwndActiveDoc, WM_SYSCOMMAND, (MPARAM)SC_CLOSE, mp2);
- break;
-
- case CMD_DOCSPLIT:
- /*
- * Call TrackSplitbars() with -1 for xMouse to tell
- * it to reposition the pointer to where the
- * splitbars currently are.
- */
- WinSetPointer(HWND_DESKTOP, hptrHVSplit);
- TrackSplitbars(WinWindowFromID(hwndActiveDoc, FID_CLIENT),
- SPS_VERT | SPS_HORZ, -1, -1);
- WinSetPointer(HWND_DESKTOP, hptrArrow);
- break;
-
- case CMD_NEW:
- if (AppNewDocument(DS_HORZSPLITBAR | DS_VERTSPLITBAR, szDocClass)
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- break;
-
- case CMD_CLOSE:
- /*
- * Close the active document.
- */
- if (hwndActiveDoc)
- WinSendMsg(hwndActiveDoc, WM_CLOSE, 0L, 0L);
- break;
-
- case CMD_ABOUT:
- /*
- * Put up the About... dialog box
- */
- WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, NULL, IDD_ABOUT, NULL
- break;
-
- case CMD_EXIT:
- WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
- break;
-
- case CMD_ARRANGETILED:
- ArrangeWindows(AWP_TILED);
- break;
-
- case CMD_ARRANGECASCADED:
- ArrangeWindows(AWP_CASCADED);
- break;
-
- default:
- /*
- * The means a window title was selected from
- * the window menu. Have the MDI code activate
- * the correct window based on the menuitem ID.
- *
- * WARNING: Be sure to keep you applications
- * menuitem IDs < CMD_WINDOWITEMS.
- */
-
- /* MULTIPLEMENU */
- /* Also in here we need to pass document unique WM_COMMAND
- messages on down to the document's client procs */
-
- if (SHORT1FROMMP(mp1) >= CMD_WINDOWITEMS)
- MDIDesktopActivateDoc(SHORT1FROMMP(mp1));
- break;
- }
- break;
-
- default:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
-
- return (0L);
- }
-
-
- BOOL AppNewDocument(USHORT fsStyle, PSZ pszClassName)
- {
- register NPDOC npdocNew;
- HWND hwndFrame, hwndClient;
- HWND hwndHScroll, hwndVScroll;
-
- npdocNew = MDINewDocument(fsStyle, pszClassName);
-
- npdocNew->clrBackground = clrNext++;
- if (clrNext > CLR_PALEGRAY)
- clrNext = CLR_BACKGROUND;
-
- hwndFrame = npdocNew->hwndFrame;
- hwndClient = WinWindowFromID(hwndFrame, FID_CLIENT);
-
- /*
- * Setup the scrollbars.
- */
- hwndHScroll = WinWindowFromID(hwndFrame, FID_HORZSCROLL);
- WinSendMsg(hwndHScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),
- MPFROM2SHORT(0, 600));
- hwndHScroll = WinWindowFromID(hwndFrame, ID_HORZSCROLL2);
- WinSendMsg(hwndHScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),
- MPFROM2SHORT(0, 600));
-
- hwndVScroll = WinWindowFromID(hwndFrame, FID_VERTSCROLL);
- WinSendMsg(hwndVScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),
- MPFROM2SHORT(0, 600));
- hwndVScroll = WinWindowFromID(hwndFrame, ID_VERTSCROLL2);
- WinSendMsg(hwndVScroll, SBM_SETSCROLLBAR, MPFROMSHORT(0),
- MPFROM2SHORT(0, 600));
-
- /*
- * Set the focus the client so the new window will be
- * active when we show it.
- */
- WinSetFocus(HWND_DESKTOP, hwndClient);
-
- AddToWindowMenu(npdocNew); /* Moved here from end of
- MdiNewDocument routine so that the doc has
- been activated, and therefore the main
- window has a menu before attempting to add
- the doc to the main window's menu */
-
-
- /*
- * Set the initial position of the frame window and make it visible.
- */
- MDISetInitialDocPos(hwndFrame);
-
- return (TRUE);
- }
-
- MRESULT EXPENTRY AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
- /*
- About... dialog procedure
- */
- {
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hDlg, TRUE); break;
- default: break;
- }
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
-
- APPDATA.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\MDI\APPDATA.C
-
-
- #define INCL_WINSYS
- #define INCL_WINCOMMON
- #define INCL_WINMESSAGEMGR
- #define INCL_WINACCELERATORS
- #define INCL_WINMENUS
- #define INCL_WINHEAP
- #define INCL_WINPOINTERS
-
- #include <os2.h>
- #include "app.h"
- #include "mdi.h"
-
- char szMDIClass[] = "PM MDI Sample App";
- char szDocClass[] = "PM MDI Document";
- USHORT cxBorder, cyBorder, cyHScroll, cxVScroll, cyVScrollArrow;
- USHORT cxScreen, cyScreen, cyIcon, cxByteAlign, cyByteAlign;
- USHORT cxSizeBorder, cySizeBorder;
- ULONG clrNext = CLR_BACKGROUND;
- LONG rglDevCaps[(CAPS_VERTICAL_FONT_RES - CAPS_FAMILY)];
-
- /* Main globals */
- HAB hab;
- HHEAP hHeap;
- HMQ hmqMDI;
- HWND hwndMDI, hwndMDIFrame;
- HWND hwndActiveDoc;
- FONTMETRICS fmSystemFont;
- NPDOC npdocFirst = NULL;
-
- /* Menu globals */
-
-
- HWND hwndSysMenu;
-
-
- APPDOC.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\MDI\APPDOC.C
-
- /*
- appdoc.c - MDI application
- Created by Microsoft Corporation, 1989
- */
- #define INCL_WINSYS
- #define INCL_WINCOMMON
- #define INCL_WINMESSAGEMGR
- #define INCL_WINFRAMEMGR
- #define INCL_WINPOINTERS
- #define INCL_WINMENUS
- #define INCL_WINWINDOWMGR
- #define INCL_WINACCELERATORS
- #define INCL_WININPUT
- #define INCL_WINHEAP
- #define INCL_WINSCROLLBARS
- #define INCL_WINRECTANGLES
- #define INCL_WINCOUNTRY
- #define INCL_GPIPRIMITIVES
- #define INCL_GPILOGCOLORTABLE
-
- #include <os2.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include "app.h"
- #include "appdata.h"
- #include "mdi.h"
- #include "mdidata.h"
-
- /* Function prototypes */
- VOID AppHScroll(HWND hwnd, MPARAM mp1, MPARAM mp2);
- VOID AppVScroll(HWND hwnd, MPARAM mp1, MPARAM mp2);
- VOID AppEraseBackground(HWND hwnd, HPS hps);
- VOID AppPaint(HWND hwnd);
- VOID MDIClose(HWND hwndClient);
- BOOL MDICreate(HWND);
- BOOL MDIDestroy(HWND);
- BOOL MDIActivate(HWND, BOOL);
-
- /*
- * The array of RGB values for the rounded
- * rectangles.
- */
- LONG aclrRGB[16] = {
- RGB_RED, RGB_WHITE, RGB_GREEN, RGB_BLACK,
- RGB_BLUE, RGB_WHITE, RGB_YELLOW, RGB_BLACK,
- RGB_CYAN, RGB_BLACK, RGB_PINK, RGB_BLACK,
- RGB_WHITE, RGB_PINK, RGB_BLACK, RGB_RED
- };
-
-
-
- MRESULT EXPENTRY DocWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
-
- switch (msg) {
-
- case WM_COMMAND:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
-
- case WM_CREATE:
- if (MDICreate(hwnd) == FALSE)
- return ( (MRESULT) TRUE);
- break;
-
- case WM_DESTROY:
- MDIDestroy(hwnd);
- break;
-
- case WM_CLOSE:
- MDIClose(hwnd);
- break;
-
- case WM_HSCROLL:
- AppHScroll(hwnd, mp1, mp2);
- break;
-
- case WM_VSCROLL:
- AppVScroll(hwnd, mp1, mp2);
- break;
-
- case WM_ERASEBACKGROUND:
- AppEraseBackground(hwnd, (HPS)mp1);
- break;
-
- case WM_PAINT:
- AppPaint(hwnd);
- break;
-
- case WM_ACTIVATE:
- MDIActivate(hwnd, (BOOL)SHORT1FROMMP(mp1));
- break;
-
- default:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
-
- return (0L);
- }
-
-
- VOID AppEraseBackground(HWND hwnd, HPS hps)
- {
- RECTL rclPaint;
- HWND hwndFrame, hwndClient;
- register NPDOC npdoc;
-
- npdoc = NPDOCFROMCLIENT(hwnd);
- hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
-
- /*
- * We know the main client is around so
- * go ahead and erase it.
- */
- WinQueryWindowRect(hwnd, &rclPaint);
- WinMapWindowPoints(hwnd, hwndFrame, (PPOINTL)&rclPaint, 2);
- WinFillRect(hps, &rclPaint, npdoc->clrBackground);
-
- /*
- * Now check to see which of the other client windows
- * are around and erase them.
- *
- * We do all this to avoid erasing the splitbars.
- */
- if (npdoc->fs & DF_SPLITVERT) {
-
- hwndClient = WinWindowFromID(hwndFrame, ID_CLIENT2);
- /*
- * If it became invisible due to the frame
- * window getting too small, then don't
- * bother drawing.
- */
- if (WinIsWindowVisible(hwndClient) != FALSE) {
- WinQueryWindowRect(hwndClient, &rclPaint);
- WinMapWindowPoints(hwndClient, hwndFrame,
- (PPOINTL)&rclPaint, 2);
- WinFillRect(hps, &rclPaint, npdoc->clrBackground);
- }
- }
-
- if (npdoc->fs & DF_SPLITHORZ) {
-
- hwndClient = WinWindowFromID(hwndFrame, ID_CLIENT3);
- if (WinIsWindowVisible(hwndClient) != FALSE) {
- WinQueryWindowRect(hwndClient, &rclPaint);
- WinMapWindowPoints(hwndClient, hwndFrame,
- (PPOINTL)&rclPaint, 2);
- WinFillRect(hps, &rclPaint, npdoc->clrBackground);
- }
- }
-
- /*
- * If we're split in both directions, then there's
- * a ID_CLIENT4 window.
- */
- if ((npdoc->fs & (DF_SPLITHORZ | DF_SPLITVERT)) ==
- (DF_SPLITHORZ | DF_SPLITVERT)) {
-
- hwndClient = WinWindowFromID(hwndFrame, ID_CLIENT4);
- if (WinIsWindowVisible(hwndClient) != FALSE) {
- WinQueryWindowRect(hwndClient, &rclPaint);
- WinMapWindowPoints(hwndClient, hwndFrame,
- (PPOINTL)&rclPaint, 2);
- WinFillRect(hps, &rclPaint, npdoc->clrBackground);
- }
- }
- }
-
-
- VOID AppHScroll(HWND hwnd, MPARAM mp1, MPARAM mp2)
- {
- HWND hwndFrame;
- NPDOC npdoc;
- RECTL rclPaintBottom, rclPaintTop;
- RECTL rclWindowBottom, rclWindowTop;
- HWND hwndClientBottom, hwndClientTop;
- HWND hwndScrollbar;
- register NPVIEW npviewBottom, npviewTop;
- SHORT posSlider, xOriginOld;
- USHORT cmd, idScrollbar;
-
- hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
- npdoc = NPDOCFROMCLIENT(hwnd);
-
- idScrollbar = SHORT1FROMMP(mp1);
-
- switch (idScrollbar) {
-
- case FID_HORZSCROLL:
- hwndClientTop = hwnd;
- if (npdoc->fs & DF_SPLITHORZ) {
- hwndClientBottom = WinWindowFromID(hwndFrame, ID_CLIENT3);
- } else {
- hwndClientBottom = NULL;
- }
- break;
-
- case ID_HORZSCROLL2:
- hwndClientTop = WinWindowFromID(hwndFrame, ID_CLIENT2);
- if (npdoc->fs & DF_SPLITHORZ) {
- hwndClientBottom = WinWindowFromID(hwndFrame, ID_CLIENT4);
- } else {
- hwndClientBottom = NULL;
- }
- break;
- }
-
- hwndScrollbar = WinWindowFromID(hwndFrame, idScrollbar);
-
- npviewTop = NPVIEWFROMCLIENT(hwndClientTop);
- WinQueryWindowRect(hwndClientTop, &rclWindowTop);
-
- if (hwndClientBottom != NULL) {
- npviewBottom = NPVIEWFROMCLIENT(hwndClientBottom);
- WinQueryWindowRect(hwndClientBottom, &rclWindowBottom);
- }
-
- posSlider = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERYPOS, NULL,
-
- cmd = SHORT2FROMMP(mp2);
- switch (cmd) {
-
- case SB_LINELEFT:
- posSlider -= 16;
- break;
-
- case SB_LINERIGHT:
- posSlider += 16;
- break;
-
- case SB_PAGELEFT:
- posSlider -= ((SHORT)rclWindowTop.xRight - 16);
- break;
-
- case SB_PAGERIGHT:
- posSlider += ((SHORT)rclWindowTop.xRight - 16);
- break;
-
- case SB_SLIDERPOSITION:
- posSlider = SHORT1FROMMP(mp2);
- break;
- }
-
- WinSendMsg(hwndScrollbar, SBM_SETPOS, MPFROMSHORT(posSlider), NULL);
-
- xOriginOld = npviewTop->xOrigin;
- npviewTop->xOrigin = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERYP
- WinScrollWindow(hwndClientTop, xOriginOld - npviewTop->xOrigin, 0,
- NULL, NULL, NULL, &rclPaintTop, NULL);
-
- if (hwndClientBottom != NULL) {
- xOriginOld = npviewBottom->xOrigin;
- npviewBottom->xOrigin = npviewTop->xOrigin;
- WinScrollWindow(hwndClientBottom, xOriginOld - npviewBottom->xOrigin,
- 0, NULL, NULL, NULL, &rclPaintBottom, NULL);
- }
-
- WinMapWindowPoints(hwndClientTop, hwndFrame, (PPOINTL)&rclPaintTop, 2);
- WinInvalidateRect(hwndFrame, &rclPaintTop, TRUE);
-
- if (hwndClientBottom != NULL) {
- WinMapWindowPoints(hwndClientBottom, hwndFrame, (PPOINTL)&rclPaintBot
- WinInvalidateRect(hwndFrame, &rclPaintBottom, TRUE);
- }
- }
-
-
- VOID AppVScroll(HWND hwnd, MPARAM mp1, MPARAM mp2)
- {
- HWND hwndFrame;
- NPDOC npdoc;
- RECTL rclPaintRight, rclPaintLeft;
- RECTL rclWindowRight, rclWindowLeft;
- HWND hwndClientRight, hwndClientLeft;
- HWND hwndScrollbar;
- register NPVIEW npviewRight, npviewLeft;
- SHORT posSlider, yOriginOld;
- USHORT cmd, idScrollbar;
-
- hwndFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
- npdoc = NPDOCFROMCLIENT(hwnd);
-
- idScrollbar = SHORT1FROMMP(mp1);
-
- switch (idScrollbar) {
-
- case FID_VERTSCROLL:
- hwndClientLeft = hwnd;
- if (npdoc->fs & DF_SPLITVERT) {
- hwndClientRight = WinWindowFromID(hwndFrame, ID_CLIENT2);
- } else {
- hwndClientRight = NULL;
- }
- break;
-
- case ID_VERTSCROLL2:
- hwndClientLeft = WinWindowFromID(hwndFrame, ID_CLIENT3);
- if (npdoc->fs & DF_SPLITVERT) {
- hwndClientRight = WinWindowFromID(hwndFrame, ID_CLIENT4);
- } else {
- hwndClientRight = NULL;
- }
- break;
- }
-
- hwndScrollbar = WinWindowFromID(hwndFrame, idScrollbar);
-
- npviewLeft = NPVIEWFROMCLIENT(hwndClientLeft);
- WinQueryWindowRect(hwndClientLeft, &rclWindowLeft);
-
- if (hwndClientRight != NULL) {
- npviewRight = NPVIEWFROMCLIENT(hwndClientRight);
- WinQueryWindowRect(hwndClientRight, &rclWindowRight);
- }
-
- posSlider = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERYPOS, NULL,
-
- cmd = SHORT2FROMMP(mp2);
- switch (cmd) {
-
- case SB_LINEUP:
- posSlider -= 16;
- break;
-
- case SB_LINEDOWN:
- posSlider += 16;
- break;
-
- case SB_PAGEUP:
- posSlider -= ((SHORT)rclWindowLeft.yTop - 16);
- break;
-
- case SB_PAGEDOWN:
- posSlider += ((SHORT)rclWindowLeft.yTop - 16);
- break;
-
- case SB_SLIDERPOSITION:
- posSlider = SHORT1FROMMP(mp2);
- break;
- }
-
- WinSendMsg(hwndScrollbar, SBM_SETPOS, MPFROMSHORT(posSlider), NULL);
-
- yOriginOld = npviewLeft->yOrigin;
- npviewLeft->yOrigin = (SHORT) (ULONG) WinSendMsg(hwndScrollbar, SBM_QUERY
- WinScrollWindow(hwndClientLeft, 0, npviewLeft->yOrigin - yOriginOld,
- NULL, NULL, NULL, &rclPaintLeft, NULL);
-
- if (hwndClientRight != NULL) {
- yOriginOld = npviewRight->yOrigin;
- npviewRight->yOrigin = npviewLeft->yOrigin;
- WinScrollWindow(hwndClientRight, 0, npviewRight->yOrigin - yOriginOld
- NULL, NULL, NULL, &rclPaintRight, NULL);
- }
-
- WinMapWindowPoints(hwndClientLeft, hwndFrame, (PPOINTL)&rclPaintLeft, 2);
- WinInvalidateRect(hwndFrame, &rclPaintLeft, TRUE);
-
- if (hwndClientRight != NULL) {
- WinMapWindowPoints(hwndClientRight, hwndFrame, (PPOINTL)&rclPaintRigh
- WinInvalidateRect(hwndFrame, &rclPaintRight, TRUE);
- }
- }
-
-
- VOID AppPaint(HWND hwnd)
- {
- HPS hps;
- RECTL rclPaint, rclWindow, rclTest, rclDst;
- POINTL ptl, ptlPatternRef;
- register NPVIEW npview;
- AREABUNDLE abnd;
- LONG clrStart, clrEnd, clrInc, clr;
- SHORT i, j;
-
- hps = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);
-
- /*
- * Go into RGB mode.
- */
- GpiCreateLogColorTable(hps, 0L, LCOLF_RGB, 0L, 0L, NULL);
-
- /*
- * Make rclPaint an inclusive-inclusive rectangle
- * since that's how GpiBox() will be output.
- */
- rclPaint.xLeft--;
- rclPaint.yBottom--;
-
- npview = NPVIEWFROMCLIENT(hwnd);
-
- /*
- * Set the pattern to be at the top-left
- * since we're top-left aligning the bits.
- */
- WinQueryWindowRect(hwnd, (PRECTL)&rclWindow);
- ptlPatternRef.x = rclWindow.xLeft - npview->xOrigin;
- ptlPatternRef.y = rclWindow.yTop + npview->yOrigin;
- GpiSetPatternRefPoint(hps, &ptlPatternRef);
-
- for (i = 0; i < 8; i++) {
-
- clr = clrStart = aclrRGB[i * 2];
- clrEnd = aclrRGB[(i * 2) + 1];
- clrInc = (clrEnd - clrStart) / 8;
-
- for (j = 0; j < 8; j++) {
- abnd.lColor = clr + (j * clrInc);
- GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR, 0L, (PBUNDLE)&abnd);
-
- /*
- * Only draw the box if it's going to
- * be visible in the update region.
- */
- WinSetRect(NULL, &rclTest, 10 + (i * 75),
- (SHORT)rclWindow.yTop - 75 - (j * 75), 75 + (i * 75),
- (SHORT)rclWindow.yTop - 10 - (j * 75));
-
- WinOffsetRect(NULL, &rclTest, -npview->xOrigin, npview->yOrigin);
-
- if (WinIntersectRect(NULL, &rclDst, &rclTest, &rclPaint)) {
-
- ptl.x = rclTest.xLeft;
- ptl.y = rclTest.yTop;
- GpiSetCurrentPosition(hps, (PPOINTL)&ptl);
-
- ptl.x = rclTest.xRight;
- ptl.y = rclTest.yBottom;
- GpiBox(hps, DRO_OUTLINEFILL, (PPOINTL)&ptl, 40L, 40L);
- }
- }
- }
-
- WinEndPaint(hps);
- }
-
-
- APPINIT.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\MDI\APPINIT.C
-
- /*
- mdiinit.c - MDI initialization funtions.
- Created by Microsoft Corporation, 1989
- */
- #define INCL_WINSYS
- #define INCL_WINCOMMON
- #define INCL_WINMESSAGEMGR
- #define INCL_WINPOINTERS
- #define INCL_WININPUT
- #define INCL_WINMENUS
- #define INCL_WINFRAMEMGR
- #define INCL_WINWINDOWMGR
- #define INCL_WINRECTANGLES
- #define INCL_WINHEAP
- #define INCL_GPIBITMAPS
- #define INCL_GPILCIDS
- #define INCL_DEV
-
- #include <os2.h>
- #include "app.h"
- #include "appdata.h"
- #include "mdi.h"
- #include "mdidata.h"
-
-
- /* Function prototypes */
- BOOL RegisterWindowClasses(VOID);
- VOID InitSysValues(VOID);
-
-
- BOOL AppInit(VOID)
- {
- ULONG ctlData;
- HPS hps;
- HDC hdc;
-
- hab = WinInitialize(0);
-
- hmqMDI = WinCreateMsgQueue(hab, 0);
-
- if (!RegisterWindowClasses())
- return(FALSE);
-
- ctlData = FCF_TITLEBAR | FCF_MINMAX | FCF_SIZEBORDER | FCF_SYSMENU |
- FCF_MENU | FCF_TASKLIST | FCF_SHELLPOSITION | FCF_ICON;
-
- hwndMDIFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
- (VOID FAR *)&ctlData, szMDIClass, (PSZ)NULL,
- WS_VISIBLE | WS_CLIPCHILDREN, NULL, IDR_MDI,
- (HWND FAR *)&hwndMDI);
-
-
- if (hwndMDIFrame == NULL)
- return(FALSE);
-
- /* MULTIPLEMENU */
-
- /* Remember the first menu so we can put it back when all the documents a
- closed */
- hwndFirstMenu=WinWindowFromID(hwndMDIFrame, FID_MENU);
-
- hHeap = WinCreateHeap(0, 0, 0, 0, 0, 0);
-
- if (hHeap == NULL)
- return(FALSE);
-
- hps = WinGetPS(hwndMDI);
-
- hdc = GpiQueryDevice(hps);
- DevQueryCaps(hdc, CAPS_FAMILY, CAPS_VERTICAL_FONT_RES, (PLONG)rglDevCaps)
-
- WinReleasePS(hps);
-
- InitSysValues();
-
- return(TRUE);
- }
-
-
- VOID InitSysValues(VOID)
- {
- cyTitlebar = (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
- cyIcon = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYICON);
-
- cxBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
- cyBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
-
- cxSizeBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER);
- cySizeBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER);
-
- cxByteAlign = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBYTEALIGN);
- cyByteAlign = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYBYTEALIGN);
-
- cxVScroll = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYHSCROLL);
- cyVScrollArrow = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYVSCROLLARROW
- cyHScroll = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXVSCROLL);
-
- cxScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
- cyScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
-
- cxMinmaxButton = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXMINMAXBUTTON
- }
-
-
- BOOL RegisterWindowClasses(VOID)
- {
- if (!WinRegisterClass(NULL, szMDIClass, (PFNWP)MDIWndProc,
- CS_SYNCPAINT, 0))
- return(FALSE);
-
- if (!WinRegisterClass(NULL, szDocClass, (PFNWP)DocWndProc,
- 0L, sizeof(NPVIEW)))
- return(FALSE);
-
- return(TRUE);
- }
-
-
- VOID AppTerminate(VOID)
- {
- WinDestroyWindow(hwndMDIFrame);
-
- WinDestroyHeap(hHeap);
-
- WinDestroyMsgQueue(hmqMDI);
-
- WinTerminate(hab);
- }
-
-
- ARRANGE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\MDI\ARRANGE.C
-
- /***************************************************************************\
- * ARRANGE.c - This file contains code to do window arrangment.
- *
- * Created by Microsoft Corporation, 1989
- \***************************************************************************/
-
- #define INCL_WINSYS
- #define INCL_WINCOMMON
- #define INCL_WINMESSAGEMGR
- #define INCL_WINPOINTERS
- #define INCL_WININPUT
- #define INCL_WINMENUS
- #define INCL_WINFRAMEMGR
- #define INCL_WINWINDOWMGR
- #define INCL_WINRECTANGLES
- #define INCL_WINHEAP
- #include <os2.h>
- #include "app.h"
- #include "appdata.h"
- #include "mdi.h"
- #include "mdidata.h"
-
-
- MINMAXFIX /* add hack to keep the min/max icons in sync with reality */
-
- /* internal function prototypes */
- BOOL SetTilePositions(PRECTL prc, SHORT cWnd, PSWP aswp);
- SHORT CeilSquareRoot(USHORT us);
- BOOL SetCascadePositions(PRECTL prc, SHORT cWnd, PSWP aswp);
- BOOL SetCascadeParams(PRECTL prc, SHORT *pxEdge, SHORT *pyEdge,
- SHORT *pxDelta, SHORT *pyDelta, SHORT *cMaxWnd);
- BOOL GetArrangeSwp(USHORT *, SWP *, USHORT *, SWP *);
- BOOL GetArrangeRectangle(PRECTL, BOOL);
- BOOL ArrangeIconPositions(USHORT, PSWP);
-
- /* internal constants */
- #define CASC_EDGE_NUM 2
- #define CASC_EDGE_DENOM 3
-
- /* local constants */
- #define ICON_PARK_NUM 5
- #define ICON_PARK_DENOM 3
- #define CLASS_NAME_LENGTH 8
-
- /***************************************************************************\
- * ArrangeWindowPositions
- *
- * This function sets positions for arranging windows nicely in a rectangle.
- * The hwnd field of each SWP structure should be set by the user, either
- * before or after calling this function. The function sets all other
- * fields. The SWP array can then be passed to WinSetMultWindowPos() to do
- * the physical arrangement. There are two arrangement styles available,
- * AWP_TILED and AWP_CASCADED.
- *
- * AWP_TILED:
- *
- * The tiles are generated by rows, top left (first) to bottom right (last).
- * Each row has the same number of tiles. The number of tiles in each
- * column will differ by at most one, with each column containing one fewer
- * tile to the left of the other columns.
- *
- * AWP_CASCADED:
- *
- * The windows are generated bottom right (first) to top left (last).
- *
- * Parameters:
- * prc: rectangle to contain the tiled windows
- * cWnd: number of windows to tile
- * aswp: array of SWP structures, one for each tile window
- * fStyle: the style to arrange the windows
- \***************************************************************************/
-
- BOOL ArrangeWindowPositions(PRECTL prc, SHORT cWnd, PSWP aswp, USHORT fStyle)
- {
- /* check validity of input rectangle */
- if ((prc->xRight - prc->xLeft < 1) || (prc->yTop - prc->yBottom < 1)) {
- return FALSE;
- }
-
- /* set window positions */
- switch (fStyle) {
- case AWP_TILED:
- return SetTilePositions(prc, cWnd, aswp);
- case AWP_CASCADED:
- return SetCascadePositions(prc, cWnd, aswp);
- default:
- return FALSE;
- }
- }
-
-
- /***************************************************************************\
- * SetTilePositions
- *
- * This function sets positions for tiling windows in a rectangle.
- *
- * NOTE:
- * There are a few subtleties to this code:
- *
- * The algorithm lays tiles in a modified NxN grid. It can be shown
- * that any positive number of tiles can be laid out in such a grid of
- * N columns so that each column has at least N-2 tiles and no column
- * has more than one tile more than any other. Proof left to the
- * interested reader.
- *
- * The tiles coordinates are not generated by stepping over a fixed
- * interval since this will not usually fill the rectangle completely.
- * Thus the offset at each step is calculated from the previous tile
- * to the correct fractional position within the whole rectangle.
- *
- * Since the last "row" of tiles may not have any members in the beginning
- * columns, these tiles are addressed differently in the SWP array to
- * account for the "missing" tiles.
- *
- * Parameters:
- * prc: rectangle to contain the tiled windows
- * cWnd: number of windows to tile the rectangle with
- * aswp: array of SWP structures, one for each tile window
- \***************************************************************************/
-
- BOOL SetTilePositions(PRECTL prc, SHORT cWnd, PSWP aswp)
- {
- register SHORT usRoot;
- register SHORT cExtras;
- SHORT iChange;
- SHORT cDiff;
- SHORT x, y, cx, cy;
- SHORT iRow, iCol;
-
- /* get grid dimensions */
- usRoot = CeilSquareRoot(cWnd);
- cExtras = usRoot * usRoot - cWnd;
-
- /* find column where number of rows increases and find initial
- difference of rows versus columns */
- if (cExtras >= usRoot) {
- iChange = cExtras - usRoot;
- cDiff = 2;
- } else {
- iChange = cExtras;
- cDiff = 1;
- }
-
- /* assign x coordinates */
- x = (SHORT)prc->xLeft;
- cx = 0;
- for (iCol = 0; iCol < usRoot; iCol++) {
- x += cx - cxBorder;
- cx = ((SHORT)prc->xLeft) +
- (((SHORT)(prc->xRight - prc->xLeft)) * (iCol + 1)) / usRoot -
- x + cxBorder;
- for (iRow = 0; iRow < usRoot - cDiff; iRow++) {
- aswp[iRow * usRoot + iCol].x = x;
- aswp[iRow * usRoot + iCol].cx = cx;
- aswp[iRow * usRoot + iCol].fs = SWP_SIZE | SWP_MOVE;
- }
- /* assign "extra" row */
- if (iCol >= iChange) {
- aswp[iRow * usRoot + iCol - iChange].x = x;
- aswp[iRow * usRoot + iCol - iChange].cx = cx;
- aswp[iRow * usRoot + iCol - iChange].fs = SWP_SIZE | SWP_MOVE;
- }
- }
-
- /* assign y coordinates, columns without extra row */
- y = (SHORT)prc->yBottom;
- cy = 0;
- for (iRow = usRoot - cDiff - 1; iRow >= 0; iRow--) {
- y += cy - cyBorder;
- cy = ((SHORT)prc->yBottom) +
- (((SHORT)(prc->yTop - prc->yBottom)) * (usRoot - cDiff - iRow))
- (usRoot - cDiff) - y + cyBorder;
- for (iCol = 0; iCol < iChange; iCol++) {
- aswp[iRow * usRoot + iCol].y = y;
- aswp[iRow * usRoot + iCol].cy = cy;
- }
- }
-
- /* assign y coordinates, columns with extra row */
- /* do last row first (different offsets) */
- y = (SHORT)prc->yBottom - cyBorder;
- cy = ((SHORT)(prc->yTop - prc->yBottom)) / (usRoot - cDiff + 1) +
- 2 * cyBorder;
- for (iCol = iChange; iCol < usRoot; iCol++) {
- aswp[usRoot * (usRoot - cDiff) + iCol - iChange].y = y;
- aswp[usRoot * (usRoot - cDiff) + iCol - iChange].cy = cy;
- }
- for (iRow = usRoot - cDiff - 1; iRow >= 0; iRow--) {
- y += cy - cyBorder;
- cy = ((SHORT)(prc->yBottom)) +
- (((SHORT)(prc->yTop - prc->yBottom)) * (usRoot - cDiff - iRow
- / (usRoot - cDiff + 1) - y + cyBorder;
- for (iCol = iChange; iCol < usRoot; iCol++) {
- aswp[iRow * usRoot + iCol].y = y;
- aswp[iRow * usRoot + iCol].cy = cy;
- }
- }
-
- return TRUE;
- }
-
-
- /***************************************************************************\
- * CeilSquareRoot
- *
- * This function returns the smallest integer greater or equal to the square
- * root of an unsigned 16 bit integer.
- *
- * Parameter:
- * us: value to take the root of
- \***************************************************************************/
-
- SHORT CeilSquareRoot(register USHORT us)
- {
- register SHORT i;
-
- /* prevent overflow of large numbers */
- if (us > 0xFE * 0xFE)
- return 0xFF;
-
- /* iterate up past root */
- for (i = 0; i*i < (SHORT) us; i++)
- ;
- return i;
- }
-
-
- /***************************************************************************\
- * SetCascadePositions
- *
- * This function sets positions for cascading windows in a rectangle.
- *
- * Parameters:
- * prc: rectangle to contain the cascaded windows
- * cWnd: number of windows to cascade
- * aswp: array of SWP structures, one for each cascaded window
- \***************************************************************************/
-
- BOOL SetCascadePositions(PRECTL prc, SHORT cWnd, PSWP aswp)
- {
- SHORT xEdge, yEdge;
- SHORT xDelta, yDelta;
- SHORT cMaxWnd;
- register SHORT x, y;
- SHORT i, j;
- RECTL rc;
-
- /* set cascade parameters */
- rc.xLeft = prc->xLeft - cxBorder;
- rc.xRight = prc->xRight + cyBorder;
- rc.yBottom = prc->yBottom - cyBorder;
- rc.yTop = prc->yTop + cyBorder;
- if (!SetCascadeParams((PRECTL)&rc, &xEdge, &yEdge, &xDelta, &yDelta,
- &cMaxWnd)) {
- return FALSE;
- }
-
- if (cWnd <= cMaxWnd) {
- /* only one run needed; move to top left corner */
- x = (SHORT)rc. xLeft;
- y = (SHORT)rc. yTop - yEdge;
- for (i = cWnd - 1; i >= 0; i--) {
- aswp[i].x = x;
- aswp[i].y = y;
- aswp[i].cx = xEdge;
- aswp[i].cy = yEdge;
- aswp[i].fs = SWP_SIZE | SWP_MOVE;
- x += xDelta;
- y -= yDelta;
- }
-
- } else {
-
- /* multiple runs necessary; start at bottom right, iterate up to
- top left */
-
- i = 0;
-
- while (i < cWnd) {
-
- /* even run */
- x = ((SHORT)rc. xLeft) + (cMaxWnd-1) * xDelta;
- y = ((SHORT)rc. yTop) - yEdge - (cMaxWnd-1) * yDelta;
- for (j = 0; j < cMaxWnd; j++) {
- aswp[i].x = x;
- aswp[i].y = y;
- aswp[i].cx = xEdge;
- aswp[i].cy = yEdge;
- aswp[i].fs = SWP_SIZE | SWP_MOVE;
- x -= xDelta;
- y += yDelta;
- if (++i >= cWnd)
- break;
- }
-
- if (i >= cWnd)
- break;
-
- /* odd run, offset by half delta y, one and one half delta x */
- x = ((SHORT)rc. xLeft) + (cMaxWnd-1) * xDelta + xDelta/2;
- y = ((SHORT)rc. yTop) - yEdge - (cMaxWnd-1) * yDelta + yDelta/2;
- for (j = 0; j < cMaxWnd - 1; j++) {
- aswp[i].x = x;
- aswp[i].y = y;
- aswp[i].cx = xEdge;
- aswp[i].cy = yEdge;
- aswp[i].fs = SWP_SIZE | SWP_MOVE;
- x -= xDelta;
- y += yDelta;
- if (++i >= cWnd)
- break;
- }
- }
- }
-
- return TRUE;
- }
-
-
- /***************************************************************************\
- * SetCascadeParams
- *
- * This function sets parameters for cascading windows. The window edge
- * are based on a fraction CASC_EDGE_NUM/CASC_EDGE_DENOM of the rectangle.
- * The x delta is four system font characters across, the y delta is two
- * system lines high.
- *
- * Parameters:
- * prc: rectangle to contain the windows
- * pxEdge: width of the cascaded windows
- * pyEdge: height of the cascaded windows
- * pxDelta: x cascade offset
- * pyDelta: y cascade offset
- * pcMaxWnd: maximum number of windows in a cascade
- \***************************************************************************/
-
- BOOL SetCascadeParams(PRECTL prc, SHORT *pxEdge, SHORT *pyEdge, SHORT *pxDelt
- SHORT *pyDelta, SHORT *pcMaxWnd)
- {
- register SHORT xEdge, yEdge;
- SHORT xDelta, yDelta;
- SHORT cMaxWnd;
-
- /* get x and y deltas from system values */
- xDelta = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER)) +
- LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CXMINMAXBUTTON)) / 2
- yDelta = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CYSIZEBORDER)) +
- LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR))
- - cyBorder;
-
- /* get initial cut at yEdge using fraction */
- yEdge = (((SHORT)(prc->yTop - prc->yBottom)) * CASC_EDGE_NUM) /
- CASC_EDGE_DENOM;
-
- /* determine maximum number of deltas used per run */
- cMaxWnd = (((SHORT)(prc->yTop - prc->yBottom)) - yEdge) / yDelta;
-
- /* set x and y edges so full cascade will fill rectangle completely */
- xEdge = ((SHORT)(prc->xRight - prc->xLeft)) - xDelta/2 - cMaxWnd * xDelta
- yEdge = ((SHORT)(prc->yTop - prc->yBottom)) - cMaxWnd * yDelta;
-
- /* check that values are reasonable */
- if (cMaxWnd < 1 || xEdge < 1 || yEdge < 1) {
- return FALSE;
- }
-
- *pxEdge = xEdge;
- *pyEdge = yEdge;
- *pxDelta = xDelta;
- *pyDelta = yDelta;
- /* return cMaxWnd as the maximum number of windows in a cascade */
- *pcMaxWnd = cMaxWnd + 1;
-
- return TRUE;
- }
-
-
- /***************************************************************************\
- * ArrangeWindows
- *
- * This function arranges application document windows.
- *
- * Returns:
- * TRUE if successful
- * FALSE otherwise
- \***************************************************************************/
-
- BOOL ArrangeWindows(USHORT fStyle)
- {
- USHORT cswpWnd, cswpIcon;
- RECTL rcl;
- register BOOL fReturn = FALSE;
- SWP NEAR *npswpWnd;
- SWP NEAR *npswpIcon;
-
- npswpWnd = (SWP NEAR *) WinAllocMem(hHeap, sizeof(SWP) * cDocs);
- npswpIcon = (SWP NEAR *) WinAllocMem(hHeap, sizeof(SWP) * cDocs);
-
- GetArrangeSwp(&cswpWnd, npswpWnd, &cswpIcon, npswpIcon);
-
- GetArrangeRectangle((PRECTL)&rcl, (BOOL)cswpIcon);
-
- /* set window positions */
- if (!ArrangeWindowPositions((PRECTL)&rcl, cswpWnd, (PSWP)npswpWnd, fStyle
- !ArrangeIconPositions(cswpIcon, (PSWP)npswpIcon)) {
- goto ARRANGE_CLEANUP;
- }
-
- #if 1
- /* rearrange the windows */
- WinSetMultWindowPos(NULL, (PSWP)npswpWnd, cswpWnd);
- WinSetMultWindowPos(NULL, (PSWP)npswpIcon, cswpIcon);
- #endif
- fReturn = TRUE;
-
- ARRANGE_CLEANUP:
- WinFreeMem(hHeap, (NPBYTE)npswpWnd, sizeof(SWP) * cDocs);
- WinFreeMem(hHeap, (NPBYTE)npswpIcon, sizeof(SWP) * cDocs);
-
- return fReturn;
- }
-
- /***************************************************************************\
- * GetArrangeHandles
- *
- * This function generates the handles of all windows to be arranged and
- * creates an array of SWP structures containing those handles. Minimized
- * and non-minimized windows are separated. Non-frame, invisible and
- * non-sizeable windows are ignored.
- *
- * Parameter:
- * npcswpWnd: number of nonminimized windows found
- * npswpWnd: array of SWP structures for nonminimized windows
- * npcswpIcon: number of minimized windows found
- * npswpIcon: array of SWP structures for minimized windows
- *
- * Returns:
- * TRUE if successful
- * FALSE otherwise
- \***************************************************************************/
-
- BOOL GetArrangeSwp(USHORT *npcswpWnd, SWP *npswpWnd, USHORT *npcswpIcon,
- SWP *npswpIcon)
- {
- register USHORT cWnd, cIcon;
- ULONG ulStyle;
- HWND hwnd;
- register NPDOC npdoc;
-
- cWnd = 0;
- cIcon = 0;
-
- /* enumerate windows and selectively add them to the arrange lists */
- for (hwnd = WinQueryWindow(hwndMDI, QW_TOP, FALSE);
- hwnd;
- hwnd = WinQueryWindow(hwnd, QW_NEXT, FALSE)) {
-
- /* make sure the window is visible and owned by the app client window
- ulStyle = WinQueryWindowULong(hwnd, QWL_STYLE);
- if (WinQueryWindow(hwnd, QW_OWNER, FALSE) ||
- !(ulStyle & WS_VISIBLE)) {
- continue;
- }
-
- if (ulStyle & WS_MINIMIZED) {
- npswpIcon->hwnd = hwnd;
- npswpIcon++;
- cIcon++;
- } else {
- /* restore maximized windows */
- if (ulStyle & WS_MAXIMIZED) {
-
- #ifdef MINMAXFIX
- /* Bring the min/max buttons back to life for a moment so
- they stay in sync when the window is restored. Then put
- them back to the object window 07-Sep-1989 johnba
- */
-
- npdoc = NPDOCFROMCLIENT(WinWindowFromID(hwnd,FID_CLIENT));
- WinSetParent(npdoc->hwndMinmax, hwnd, FALSE);
- #endif
- WinSetWindowPos(hwnd, NULL, 0, 0, 0, 0, SWP_RESTORE );
- #ifdef MINMAXFIX
-
-
- if (hwndActiveDoc != hwnd) {
- WinSetParent(npdoc->hwndMinmax, HWND_OBJECT, FALSE);
- WinSendMsg(hwnd, WM_UPDATEFRAME, 0L, 0L);
- }
- #endif
- }
- npswpWnd->hwnd = hwnd;
- npswpWnd++;
- cWnd++;
- }
- }
-
- *npcswpWnd = cWnd;
- *npcswpIcon = cIcon;
- return TRUE;
- }
-
-
- /***************************************************************************\
- * GetArrangeRectangle
- *
- * This function determines the area in which task windows are arranged.
- *
- * Parameter:
- * prc: the generated area rectangle
- * fIconPark: specifies if room should be made for icon parking lot
- *
- * Returns:
- * TRUE if successful
- * FALSE otherwise
- \***************************************************************************/
-
- BOOL GetArrangeRectangle(PRECTL prc, BOOL fIconPark)
- {
- register USHORT yIcon;
- register SHORT cxBorderInset;
-
- /* get dimensions of desktop window */
- WinQueryWindowRect(hwndMDI, prc);
-
- cxBorderInset = (SHORT)(WinQuerySysValue(HWND_DESKTOP, SV_CXBYTEALIGN) -
- WinQuerySysValue(HWND_DESKTOP, SV_CXSIZEBORDER));
- WinInflateRect(NULL, prc, -cxBorderInset, -cxBorderInset *
- (cyBorder / cxBorder));
-
- if (fIconPark) {
- /* make room for single row of icon carpark */
- yIcon = LOUSHORT(WinQuerySysValue(HWND_DESKTOP, SV_CYICON));
- prc->yBottom += (yIcon * ICON_PARK_NUM) / ICON_PARK_DENOM;
- }
-
- return TRUE;
- }
-
- /***************************************************************************\
- * ArrangeIconPositions
- *
- * This function sets positions for minimized windows.
- *
- * Parameters:
- * cIcon: number of icons to position
- * aswp: array of SetWindowPos structures for those icons
- *
- * Returns:
- * TRUE if successful
- * FALSE otherwise
- \***************************************************************************/
-
- BOOL ArrangeIconPositions(USHORT cIcon, PSWP aswpIcon)
- {
- register USHORT i;
-
- for (i = 0; i < cIcon; i++) {
- aswpIcon[i].x = 0;
- aswpIcon[i].y = 0;
- aswpIcon[i].fs = SWP_MOVE;
- }
-
- return TRUE;
- }
-
-
- AVIO.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\BROWSE\AVBROWSE\AVIO.C
-
- /*
- avio.c -- AVIO action routines
-
- Implements scrollbars, sets up an AVIO Presentation Space
- */
- #define INCL_AVIO
- #define INCL_DEV
- #define INCL_VIO
- #define INCL_WINWINDOWMGR
- #define INCL_WINSYS
- #define INCL_WINMESSAGEMGR
- #define INCL_WINTRACKRECT
- #define INCL_WINFRAMEMGR
- #define INCL_WINSCROLLBARS
- #include <os2.h>
- <string.h> /* One strlen() call in the Blast() macro */
- "avio.h" /* Get Avio-prefixed routine prototypes */
- /*
- Constants
- */
- char Blank[2] = { 0x20, 0x07 }; /* <Space> + EGA white attribut
- /*
- Macros to make the code more readable
- */
- /* Upper and Lower Bound Calculations */
- #define Abs(a) (((a) > 0) ? (a) : (-(a)))
- #define Min(a,b) (((a) < (b)) ? (a) : (b))
- #define Max(a,b) (((a) > (b)) ? (a) : (b))
- #define LowerBound(pos, disp, lbound) Max(pos - disp, lbound)
- #define UpperBound(pos, disp, ubound) Min(pos + disp, ubound)
-
- /* Scroll Bar Abbreviations */
- #define DisableSB(hSB) WinSetParent(hSB, HWND_OBJECT, TRUE)
- #define EnableSB(hSB) WinSetParent(hSB, hWndFrame, TRUE)
- #define SetScroll(h, pos, max) \
- WinSendMsg(h, SBM_SETSCROLLBAR, MPFROM2SHORT(pos, 0), MPFROM2SHORT(0, max
-
- /* Scrollbar redraw macros */
- #define UpdateOn(c, hsb) if (!(++c)) WinEnableWindowUpdate(hsb, TRUE)
- #define UpdateOff(c, hsb) if (!(c--)) WinEnableWindowUpdate(hsb, FALSE
- #define UpdateFrame(sb) \
- WinSendMsg(hWndFrame, WM_UPDATEFRAME, MPFROMLONG(sb), 0L)
-
- /* Scrolling Macros */
- ClearScreen() ScrollUp(-1) /* Scroll up an "infinite" # lines *
- #define ScrollDown(n) VioScrollDn(0, 0, -1, -1, n, Blank, hVPS)
- #define ScrollUp(n) VioScrollUp(0, 0, -1, -1, n, Blank, hVPS)
-
- /* RectL -> SWP conversion macros */
- #define lcx(r) ((r.xRight - r.xLeft) + 1)
- #define lcy(r) ((r.yTop - r.yBottom) + 1)
-
- /* Miscellaneous macros */
- #define Blast(l, x, y) VioWrtCharStr(l, Min((SHORT) strlen(l), cxChScr
- #define CalcChars(sPg, sCh) \
- ((sCh) ? (Max(((sPg) / (sCh)), 0)) : 0)
- #define SetCellSize(h,w) VioSetDeviceCellSize(h, w, hVPS)
- #define Value(value) WinQuerySysValue(HWND_DESKTOP, value)
- /*
- File-Local Variables
- */
- HDC hDC; /* Device Context */
- HVPS hVPS; /* Virtual PS */
- int iTopLine; /* PS Line of window corner */
- int iCurCol; /* Current column of window corner */
- int cxChPage; /* Width and height of our window, in characters
- int cyChPage;
- int iMaxHorz; /* Scroll bar upper bounds */
- int iMaxVert;
- BOOL fNeedHorz; /* Do we need the scroll bars or not? */
- BOOL fNeedVert;
- HWND hWndHorzSB; /* Window handles of ScrollBar windows */
- HWND hWndVertSB;
- extern HWND hWndFrame; /* Client, frame windows */
- extern HWND hWndClient;
- PFNWP pfnOldClient; /* Old Client Window Procedure pointer */
- PFNWP pfnOldFrame; /* Old Frame Window Procedure pointer */
- SHORT cyChPS; /* Number of rows in AVIO PS */
- SHORT cxChPS; /* Number of cols in AVIO PS */
- SHORT cyChScreen; /* Number of rows in display space */
- SHORT cxChScreen; /* Number of cols in display space */
- PFNQL pfnQueryLine;
- /*
- Measurements used to help make the window look nice
- */
- LONG cxConstant, cyConstant; /* Miscellaneous f
- int cxMaxFrame, cyMaxFrame; /* Maximum frame wi
- LONG lChWidth, lChHeight;
- SHORT cxMaxClient, cyMaxClient; /* Client area bounds
- BOOL fCreatedPS; /* AVIO PS created */
- int cHUpdate = -1; /* Keep track of upd
- int cVUpdate = -1;
- /*
- Local prototypes
- */
- void FixScroll(BOOL, BOOL, HWND, ULONG, int *, int, int *);
- void UpdateScrollBars(RECTL);
- void Refresh(void);
- void Update(USHORT, USHORT, USHORT);
- /*
- The actual routines
- */
- void AvioInit(PLBINFO plbi) {
- /*
- Initialize Presentation Space, Device Context, Scroll Bars
- */
- VIOCURSORINFO vci;
- /*
- Initialize the line buffer info
- */
- cyChScreen = plbi->sRows;
- cxChScreen = plbi->sCols;
- cyChPS = plbi->sPSrows;
- cxChPS = plbi->sPScols;
- pfnQueryLine = plbi->pfnQL;
- /*
- One Time Initializations...
- */
- if (!fCreatedPS) {
- /*
- Create the AVIO Presentation Space, with one attribute byte
- */
- hDC = WinOpenWindowDC(hWndClient); /* Open the device context
- VioCreatePS(&hVPS, cyChPS, cxChPS + 1, 0, 1, 0);
- VioAssociate(hDC, hVPS); /* Link the PS with the DC */
- /*
- Turn off the cursor (set invisible attribute)
- */
- VioGetCurType(&vci, hVPS);
- vci.attr = -1;
- VioSetCurType(&vci, hVPS);
- /*
- Measure the frame components
- */
- cxConstant = 0;
- cyConstant = Value(SV_CYTITLEBAR) + Value(SV_CYMENU);
- /*
- Snag scroll bar info
- */
- hWndHorzSB = WinWindowFromID(hWndFrame, FID_HORZSCROLL);
- hWndVertSB = WinWindowFromID(hWndFrame, FID_VERTSCROLL);
- fNeedHorz = fNeedVert = TRUE;
- /*
- Setup the Client and Frame routines
- */
- pfnOldFrame = WinSubclassWindow(hWndFrame, AvioFrameWndProc);
- pfnOldClient = WinSubclassWindow(hWndClient, AvioClientWndProc
- fCreatedPS = TRUE;
- }
- /*
- Repaint the screen
- */
- iTopLine = iCurCol = 0;
- AvioStartup(plbi->fLargeFont);
- }
-
- void AvioStartup(BOOL fLargeFont) {
- /*
- Clear the screen, set the font, redraw the area
- */
- RECTL rclFrame;
-
- ClearScreen();
- AvioLargeFont(fLargeFont);
- WinQueryWindowRect(hWndFrame, &rclFrame);
- UpdateScrollBars(rclFrame);
- Update(0, cyChPS, 0);
- }
-
- void AvioScroll(USHORT SB_Command, USHORT Position, BOOL Horizontal) {
- /*
- Process the scroll bar messages
-
- These routines are symmetric; in fact, SB_LINELEFT = SB_LINEUP, etc...
- so one might note that this could be condensed. It's left expanded for
- speed and clarity. The scrollbar values are bounded to stay inside
- the Presentation Space.
- */
- if (Horizontal) { /* Horizontal Scroll Bar */
- switch (SB_Command) {
- case SB_LINELEFT:
- iCurCol = LowerBound(iCurCol, 1, 0); break;
- case SB_LINERIGHT:
- iCurCol = UpperBound(iCurCol, 1, iMaxHorz); break;
- case SB_PAGELEFT:
- iCurCol = LowerBound(iCurCol, cxChPage, 0); break;
- case SB_PAGERIGHT:
- iCurCol = UpperBound(iCurCol, cxChPage, iMaxHorz); break;
- case SB_SLIDERTRACK:
- iCurCol = (SHORT) Position;
- default: break;
- }
- if (SB_Command != SB_SLIDERTRACK)
- SetScroll(hWndHorzSB, iCurCol, iMaxHorz);
-
- } else { /* Vertical Scroll Bar */
- switch (SB_Command) {
- case SB_LINEUP:
- iTopLine = LowerBound(iTopLine, 1, 0); break;
- case SB_LINEDOWN:
- iTopLine = UpperBound(iTopLine, 1, iMaxVert); break;
- case SB_PAGEUP:
- iTopLine = LowerBound(iTopLine, cyChPage, 0); break;
- case SB_PAGEDOWN:
- iTopLine = UpperBound(iTopLine, cyChPage, iMaxVert);break;
- case SB_SLIDERTRACK:
- iTopLine = (SHORT) Position;
- default: break;
- }
- if (SB_Command != SB_SLIDERTRACK)
- SetScroll(hWndVertSB, iTopLine, iMaxVert);
- }
- Refresh();
- }
-
- MRESULT AvioSize(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {
- /*
- Do the default AVIO sizing, and kyfe a few values
- */
- RECTL rclFrame;
-
- if (!fCreatedPS) return 0L;
- /*
- Update the scroll bars, and the screen
- */
- WinQueryWindowRect(hWndFrame, &rclFrame);
- UpdateScrollBars(rclFrame);
- /*
- Now, do the normal AVIO processing
- */
- return WinDefAVioWindowProc(hWnd, msg, mp1, mp2);
- }
-
- void Update(USHORT usLineNum, USHORT usHowMany, USHORT usStartLine) {
- /*
- Updates N lines starting from START line on screen.
- Starts at saved line LINENUM.
- */
- USHORT i; /* Loop index variable */
- USHORT usWhichLine = usLineNum; /* Line number to be querie
- char *szLine;
-
- for (i = usStartLine; i < (usStartLine + usHowMany); i++) {
- szLine = (*pfnQueryLine)(usWhichLine++); /* Get the line */
- if (szLine) Blast(szLine, i, 0); /* Print it out */
- }
- }
-
- void Refresh(void) {
- /*
- Do the origin shifting and screen updating
- */
- SHORT Delta;
- int static iOldTopLine = 0;
-
- VioSetOrg(0, iCurCol, hVPS); /* Get the free AVIO horizontal shift */
- Delta = iTopLine - iOldTopLine; /* Compute vertical shift */
- if (Abs(Delta) < cyChPS) {
- if (Delta < 0) { /* Scroll Up -- make Delta positive*/
- ScrollDown(-Delta);
- Update(iTopLine, -Delta, 0);
- } else { /* Scroll Down by Delta */
- ScrollUp(Delta);
- Update(iTopLine + cyChPS - Delta, Delta, cyChPS - Delta);
- }
- } else AvioRedraw(); /* Redo the entire screen */
- iOldTopLine = iTopLine;
- }
-
- void AvioClose(void) {
- /*
- Termination routines
- */
- /*
- Destroy the Presentation Space
- */
- VioAssociate(NULL, hVPS);
- VioDestroyPS(hVPS);
- fCreatedPS = FALSE;
- }
-
- void AvioPaint(HWND hWnd) {
- /*
- Paint the AVIO presentation space by telling it to show itself.
- A possible optimization here is to repaint only the update region.
- */
- static HPS hPS;
- static RECTL RectL;
-
- hPS = WinBeginPaint(hWnd, (HPS) NULL, &RectL);
- VioShowPS(cyChPS, cxChPS, 0, hVPS);
- WinEndPaint(hPS);
- }
-
- MRESULT AvioMinMax(PSWP pSWP) {
- /*
- Handle WM_MINMAX messages, to make sure frame doesn't get too big
- */
- if (pSWP->fs & (SWP_MAXIMIZE | SWP_RESTORE)) {
- if (pSWP->fs & SWP_MAXIMIZE) {
- /*
- Save cx, cy values for later origin displacement
- */
- int Oldcx = pSWP->cx;
- int Oldcy = pSWP->cy;
- /*
- Displace, and change to maximum size
- */
- pSWP->x += (Oldcx -
- (pSWP->cx = cxMaxFrame + (int) (Value(SV_CXSIZEBORDER) << 1))
- pSWP->y += (Oldcy -
- (pSWP->cy = cyMaxFrame + (int) (Value(SV_CYSIZEBORDER) << 1))
- }
- /*
- Now, fix the scroll bars
- */
- AvioAdjustFramePos(pSWP);
- return (MRESULT) TRUE;
- }
- return FALSE;
- }
-
- void AvioClear(void) { ClearScreen(); }
-
- void AvioAdjustFramePos(PSWP pSWP) {
- /*
- Trap WM_ADJUSTWINDOWPOS messages to the frame with this routine.
- Keep the window sized right, and control scrollbar visibility.
- */
- RECTL rclFrame;
-
- if (!(pSWP->cx && pSWP->cy)) return; /* Null area... */
- if (pSWP->fs & SWP_MINIMIZE) return; /* Iconic... */
- /*
- Make sure the dimensions are in range
- */
- pSWP->cx = Min(pSWP->cx, (cxMaxFrame + (SHORT)(Value(SV_CXSIZEBORDER)<<1)
- pSWP->cy = Min(pSWP->cy, (cyMaxFrame + (SHORT)(Value(SV_CYSIZEBORDER)<<1)
- /*
- Update the scroll bars
- */
- rclFrame.xLeft = (LONG) pSWP->x;
- rclFrame.xRight = (LONG) (pSWP->x + pSWP->cx - 1);
- rclFrame.yBottom = (LONG) pSWP->y;
- rclFrame.yTop = (LONG) (pSWP->y + pSWP->cy - 1);
- UpdateScrollBars(rclFrame);
-
- return;
- }
-
- void AvioTrackFrame(HWND hWnd, MPARAM mpTrackFlags) {
- /*
- Takes action on WM_TRACKFRAME message
- */
- static TRACKINFO tiTrackInfo;
- /*
- Get the tracking information in the TrackInfo structure
- */
- WinSendMsg(hWnd, WM_QUERYTRACKINFO, mpTrackFlags, &tiTrackInfo);
- WinTrackRect(hWnd, NULL, &tiTrackInfo);
- }
-
- void AvioQueryTrackInfo(PTRACKINFO pTI) {
- /*
- Routine which processes WM_QUERYTRACKINFO messages to the frame.
- Call this routine after the default one to change various parameters.
-
- Note: In reality, since we have a menu bar, we should make the
- minimum width of the window something such that it does not "fold."
- */
- BOOL fMove;
- /*
- Get the grid set up for byte alignment (unless moving)
-
- cxGrid is set to half character width so that arrow keys
- will function when sizing (they try to size by half a
- character)
- */
- fMove = ((pTI->fs & TF_MOVE) == TF_MOVE);
- pTI->fs |= TF_GRID;
- pTI->cxGrid = (fMove) ? 1 : ((SHORT) lChWidth);
- pTI->cyGrid = (fMove) ? 1 : ((SHORT) lChHeight);
- pTI->cxKeyboard = (SHORT) lChWidth;
- pTI->cyKeyboard = (SHORT) lChHeight;
- /*
- Bound the frame.
- Maximum: Sizing Border, Scrollbars, Title, Menus, client regio
- */
- pTI->ptlMaxTrackSize.x = (LONG) (pTI->cxBorder << 1) + (LONG) cxMaxFrame;
- pTI->ptlMaxTrackSize.y = (LONG) (pTI->cyBorder << 1) + (LONG) cyMaxFrame;
- }
-
- void AvioRedraw(void) {
- /*
- Clear, then redraw the entire Presentation Space
- */
- ClearScreen();
- Update(iTopLine, cyChPS, 0);
- }
-
- MRESULT CALLBACK AvioClientWndProc
- (HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {
- /*
- Window Procedure which traps messages to the Client area
- */
- switch (msg) {
- case WM_PAINT: /* Paint the AVIO way! */
- AvioPaint(hWnd);
- break;
-
- case WM_SIZE: /* Size the AVIO way! */
- return AvioSize(hWnd, msg, mp1, mp2);
- break;
-
- case WM_HSCROLL:
- AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), TRUE);
- break;
-
- case WM_VSCROLL:
- AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), FALSE);
- break;
-
- case WM_ERASEBACKGROUND:
- break;
-
- case WM_TRACKFRAME:
- AvioTrackFrame(hWnd, mp1);
- break;
-
- case WM_MINMAXFRAME: /* Limit Maximized window size
- AvioMinMax((PSWP) mp1);
-
- /* fall through */
-
- default: return (*pfnOldClient)(hWnd, msg, mp1, mp2);
- }
- return 0;
- }
-
- MRESULT CALLBACK AvioFrameWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM m
- /*
- Force the frame to stay small enough (no larger than the PS)
- */
- {
- BOOL rc; /* Return code from WM_QUERYTRACKINFO */
-
- switch(msg) {
- case WM_ADJUSTWINDOWPOS: /* Calculate scroll bar adjustments *
- AvioAdjustFramePos(mp1);
- break;
-
- case WM_QUERYTRACKINFO: /* Get default, then process m
- rc = (BOOL) SHORT1FROMMR((*pfnOldFrame)(hWnd, msg, mp1, mp2));
- AvioQueryTrackInfo((PTRACKINFO) mp2);
- return (MRESULT) rc;
-
- default: break;
- }
- return (*pfnOldFrame)(hWnd, msg, mp1, mp2);
- }
-
- void UpdateScrollBars(RECTL rclClient) {
- /*
- This routine fixes up the scroll bars when the window is resized, or
- when the font size is changed.
-
- Parameters: The dimensions of the frame window
- Result: Updates the scrollbars, enabling/disabling as needed
- */
- BOOL fNeededHorz = fNeedHorz; /* Did we need the scrollbars then? */
- BOOL fNeededVert = fNeedVert;
- /*
- Compute the client rectangle, without the scrollbars
- */
- WinCalcFrameRect(hWndFrame, &rclClient, TRUE);
- /*
- Compute page width -- do we need the horizontal scroll bar?
- */
- cxChPage = (int) CalcChars(lcx(rclClient), lChWidth);
- fNeedHorz = ((iMaxHorz = Max(cxChScreen - cxChPage, 0)) > 0);
- /*
- Compute page height -- do we need the vertical scroll bar?
- */
- cyChPage = (int) CalcChars(lcy(rclClient), lChHeight);
- fNeedVert = ((iMaxVert = Max(cyChScreen - cyChPage, 0)) > 0);
- /*
- Maintain scrollbar integrity
- */
- iCurCol = Min(iCurCol, iMaxHorz);
- iTopLine = Min(iTopLine, iMaxVert);
- /*
- Now, update the scrollbars as necessary
- */
- FixScroll(fNeededHorz, fNeedHorz, hWndHorzSB,
- FCF_HORZSCROLL, &iCurCol, iMaxHorz, &cHUpdate);
-
- FixScroll(fNeededVert, fNeedVert, hWndVertSB,
- FCF_VERTSCROLL, &iTopLine, iMaxVert, &cVUpdate);
- /*
- Now, update the screen to be visually consistent
- */
- Refresh();
- }
-
- void FixScroll(fNeeded, fNeed, hWnd, flScroll, piPos, iMax, pc)
- /*
- This routine makes the necessary scrollbar adjustments, and
- also enables/disables them.
- */
- BOOL fNeeded; /* Whether we used to need the scrollbar */
- BOOL fNeed; /* Whether we need the scrollbar now */
- HWND hWnd; /* Handle to the scrollbar window */
- ULONG flScroll; /* FCF_xxxxSCROLL flag (for the scrollbar)
- int *piPos; /* Current location of scrollbar thumb */
- int iMax; /* New maximum for the scrollbar */
- int *pc; /* Counter for WinEnableWindowUpdate recur
- {
- if (fNeed) { /* Enable the scroll bar -- we didn't need it before */
- if (!fNeeded) {
- EnableSB(hWnd);
- UpdateOff((*pc), hWnd);
- UpdateFrame(flScroll);
- UpdateOn((*pc), hWnd);
- }
- SetScroll(hWnd, (*piPos) = Min((*piPos), iMax), iMax);
- } else { /* Disable the scroll bar, we no longer need it */
- if (fNeeded) {
- DisableSB(hWnd);
- UpdateOff((*pc), hWnd);
- UpdateFrame(flScroll);
- UpdateOn((*pc), hWnd);
- }
- }
- }
-
- void AvioLargeFont(BOOL fLargeFont) {
- static BOOL fFirst = TRUE; // Need to
- static LONG lSmallHt, lSmallWd, lLargeHt, lLargeWd; // Font sizes
- SWP swp;
-
- if (fFirst) {
- /*
- The first time through, get the small and large font sizes
- */
- DevQueryCaps(hDC, CAPS_CHAR_HEIGHT, 1L, &lLargeHt);
- DevQueryCaps(hDC, CAPS_CHAR_WIDTH, 1L, &lLargeWd);
- DevQueryCaps(hDC, CAPS_SMALL_CHAR_HEIGHT, 1L, &lSmallHt);
- DevQueryCaps(hDC, CAPS_SMALL_CHAR_WIDTH, 1L, &lSmallWd);
- fFirst = FALSE;
- }
- /*
- Set the character size with VioSetDeviceCellSize
- */
- SetCellSize( (SHORT) (lChHeight = ((fLargeFont) ? lLargeHt : lSmallHt)),
- (SHORT) (lChWidth = ((fLargeFont) ? lLargeWd : lSmallWd)) )
- /*
- Compute maximum size of client area
- */
- cxMaxClient = (cxChPS * (SHORT) lChWidth);
- cxMaxFrame = cxMaxClient + (SHORT) cxConstant;
- cyMaxClient = (cyChPS * (SHORT) lChHeight);
- cyMaxFrame = cyMaxClient + (SHORT) cyConstant;
- /*
- Send a WM_ADJUSTFRAMEPOS message
- */
- WinQueryWindowPos(hWndFrame, &swp);
- if (swp.fs & SWP_MAXIMIZE) {
- AvioMinMax(&swp);
- WinSetMultWindowPos(hWndFrame, &swp, 1);
- } else {
- swp.fs = SWP_ACTIVATE | SWP_MOVE | SWP_SHOW | SWP_SIZE;
- WinSetWindowPos(hWndFrame, NULL, swp.x, swp.y,
- Min(cxMaxFrame, swp.cx), Min(cyMaxFrame, swp.cy), swp.fs);
- }
- AvioAdjustFramePos(&swp); /* Fix up the frame, scroll bars
- AvioPaint(hWndClient); /* Repaint with new characters */
- }
-
-
- AVIO.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\AVIO.C
-
- /*
- avio.c -- AVIO handling routines
- For a cleaner implementation, look at the BROWSE application.
-
- Implements scrollbars, sets up an AVIO Presentation Space
- Intrinsically linked with a circular queue routine
-
- Created by Microsoft Corporation, 1989
- */
-
- #define INCL_AVIO
- #define INCL_DEV
- #define INCL_VIO
- #define INCL_WIN
- #include <os2.h>
- #include "global.h"
- "circleq.h" /* Get Circular Buffer routines */
- "avio.h" /* Prototype our routines */
- <stdio.h> /* Needed to open LOG file */
- /*
- Constants
- */
- AVIO_PS_ROWS 25 /* Dimensions of the AVIO PS */
- #define AVIO_PS_COLUMNS MAXLINELEN
- CATTRBYTES 1 /* 1 or 3 attribute bytes/cell */
- DEFPAGEWIDTH 5 /* Default pagesizes */
- #define DEFPAGEHEIGHT 5
-
- char Blank[2] = { 0x20, 0x07 };
-
- /*
- Macros to make the code more readable
- */
- /* Upper and Lower Bound Calculations */
- #define Abs(a) (((a) > 0) ? (a) : (-(a)))
- #define LowerBound(pos, disp, lbound) Max(pos - disp, lbound)
- #define UpperBound(pos, disp, ubound) Min(pos + disp, ubound)
-
- /* Scroll Bar Abbreviations */
-
- #define DisableSB(hSB) WinSetParent(hSB, HWND_OBJECT, FALSE)
- #define EnableSB(hSB) WinSetParent(hSB, hWndSBParent, FALSE)
- #define HBarHeight() (fNeedHorz ? lHSBHeight : 0L)
- #define VBarWidth() (fNeedVert ? lVSBWidth : 0L)
- #define SetScroll(h, pos, max) \
- WinSendMsg(h, SBM_SETSCROLLBAR, MPFROM2SHORT(pos, 0), MPFROM2SHORT(0, max
- #define UpdateFrame(sb) \
- WinSendMsg(hWndSBParent, WM_UPDATEFRAME, MPFROMLONG(sb), 0L)
- #define UpdateOff(w) WinEnableWindowUpdate(w, FALSE)
- #define UpdateOn(w) WinEnableWindowUpdate(w, TRUE)
-
- /* Scrolling Macros */
- #define ClearScreen() ScrollUp(-1)
- #define ScrollDown(n) VioScrollDn(0, 0, -1, -1, n, Blank, hVPS)
- #define ScrollUp(n) VioScrollUp(0, 0, -1, -1, n, Blank, hVPS)
- #define SetCursor(x, y) VioSetCurPos((USHORT) x, (USHORT) y, hV
-
- /* Miscellaneous */
- /*
- If partial ANSI emulation is desired, use:
- VioSetCurPos((USHORT) x, (USHORT) y, hVPS); \
- VioWrtTTY(l->szText, l->cch, hVPS)
- */
- #define Blast(l, x, y) VioWrtCharStr(l->szText, l->cch, x, y, hVPS)
- /*
- Calculate the number of characters in a page
- For nicer behavior, you can do rounding here
- */
- #define CalcChars(pPg, pCh, default) \
- ((pCh) ? (Max((int) ((pPg) / ((SHORT) pCh)), 0)) : (default))
- #define Value(value) WinQuerySysValue(HWND_DESKTOP, value)
- /*
- File-Local Variables
- */
- HDC hDC; /* Device Context */
- HVPS hVPS; /* Virtual PS */
- int iTopLine; /* PS Line of window corner */
- int iCurCol; /* Current column of window corner */
- int cchPgWidth; /* Width and height of our window */
- int cchPgHeight;
- int cchMaxHorz; /* Scroll bar upper bounds */
- int cchMaxVert;
- BOOL fNeedHorz; /* Do we need the scroll bars or not? */
- BOOL fNeedVert;
- HWND hWndHScroll; /* Window handles of ScrollBar windows */
- HWND hWndVScroll;
- HWND hWndSBParent; /* Could mooch off the value in main(), but
- /*
- Measurements used to help make the window look nice
- */
- LONG lChWidth, lChHeight; /* Character size *
- LONG lHSBHeight, lVSBWidth; /* Scrollbar measur
- LONG lMiscWidth, lMiscHeight; /* Border, titlebar, ...
- int iMaxWidth, iMaxHeight; /* Client area boun
- int iMaxFrameWidth, iMaxFrameHeight; /* Frame window bounds */
- BOOL fCreated; /* AVIO PS created */
- int rc; /* Return code */
- VIOCURSORINFO vci;
- /*
- Local prototypes
- */
- void GetMeasurements(void);
- void Update(USHORT, USHORT, USHORT, BOOL);
- void Refresh(BOOL);
- void WantCursor(BOOL);
- void SetScrollPos(void);
- void SetScrollPosHorz(void);
- void SetScrollPosVert(void);
- /*
- The actual routines
- */
- void GetMeasurements(void) {
- /*
- Get display parameters
- */
- /*
- Scroll bar widths and heights
- */
- lHSBHeight = Value(SV_CYHSCROLL);
- lVSBWidth = Value(SV_CXVSCROLL);
- /*
- Non-PS widths and heights
- */
- lMiscHeight = (Value(SV_CYSIZEBORDER) << 1) /* A border on
- + Value(SV_CYTITLEBAR) /* The title bar...
- + Value(SV_CYMENU) /* ...and the menu bar */
- + Value(SV_CYBYTEALIGN); /* ...and alignment *
-
- lMiscWidth = (Value(SV_CXSIZEBORDER) << 1);/* A border on each sid
- /*
- Height and width of characters
- */
- rc = DevQueryCaps(hDC, CAPS_CHAR_HEIGHT, 1L, &lChHeight);
- rc = DevQueryCaps(hDC, CAPS_CHAR_WIDTH, 1L, &lChWidth);
- /*
- Compute size of client and frame windows
- */
- iMaxWidth = (AVIO_PS_COLUMNS * (int) lChWidth);
- iMaxHeight = (AVIO_PS_ROWS * (int) lChHeigh
- iMaxFrameWidth = (iMaxWidth + (int) lMiscWidth);
- iMaxFrameHeight = (iMaxHeight + (int) lMiscHeight);
- /*
- Compute cursor attributes
- */
- vci.yStart = (USHORT) 0;
- vci.cEnd = (USHORT) lChHeight - 1;
- vci.cx = 0;
- }
-
- void AvioInit(HWND hWndFrame, HWND hWndClient) {
- /*
- Initialize Presentation Space, Device Context, Scroll Bars
- */
- /*
- Create the AVIO Presentation Space
- */
- hDC = WinOpenWindowDC(hWndClient);
- VioCreatePS(&hVPS, AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, CATTRBYTES, 0);
- VioAssociate(hDC, hVPS);
- fCreated = TRUE;
- /*
- Turn on the cursor and home it
- */
- WantCursor(TRUE);
- SetCursor(0, 0);
- /*
- Snag scroll bar info
- */
- hWndHScroll = WinWindowFromID(hWndFrame, FID_HORZSCROLL);
- hWndVScroll = WinWindowFromID(hWndFrame, FID_VERTSCROLL);
- hWndSBParent = WinQueryWindow(hWndHScroll, QW_PARENT, FALSE);
- fNeedHorz = fNeedVert = TRUE;
- /*
- Get character height in pixels, etc...
- */
- GetMeasurements();
- }
-
- void AvioStartup(HWND hWndClient) {
- SWP swp;
- /*
- Initialize the queue
- */
- QueInit();
- /*
- Initialize the screen
- */
- ClearScreen();
- WinQueryWindowPos(hWndClient, &swp);
- AvioSize(hWndClient, WM_NULL, NULL, MPFROM2SHORT(swp.cx, swp.cy));
- }
-
- void AvioScroll(USHORT SB_Command, USHORT usPosition, BOOL fHorizontal) {
- /*
- Process the scroll bar messages
-
- These routines are symmetric; in fact, SB_LINELEFT = SB_LINEUP, etc...
- so one might note that this could be condensed. It's left expanded for
- speed and clarity. I bound the values each way so that we stay inside
- the AVIO presentation space.
- */
- if (fHorizontal) { /* Horizontal Scroll Bar */
- switch (SB_Command) {
- case SB_LINELEFT:
- iCurCol = LowerBound(iCurCol, 1, 0); break;
- case SB_LINERIGHT:
- iCurCol = UpperBound(iCurCol, 1, cchMaxHorz); break;
- case SB_PAGELEFT:
- iCurCol = LowerBound(iCurCol, cchPgWidth, 0); break;
- case SB_PAGERIGHT:
- iCurCol = UpperBound(iCurCol, cchPgWidth, cchMaxHorz); break;
- case SB_SLIDERTRACK:
- iCurCol = (SHORT) usPosition;
- default: break;
- }
- if (SB_Command != SB_SLIDERTRACK)
- SetScroll(hWndHScroll, iCurCol, cchMaxHorz);
-
- } else { /* Vertical Scroll Bar */
- switch (SB_Command) {
- case SB_LINEUP:
- iTopLine = LowerBound(iTopLine, 1, 0); break;
- case SB_LINEDOWN:
- iTopLine = UpperBound(iTopLine, 1, cchMaxVert); break;
- case SB_PAGEUP:
- iTopLine = LowerBound(iTopLine, cchPgHeight, 0); break;
- case SB_PAGEDOWN:
- iTopLine = UpperBound(iTopLine, cchPgHeight, cchMaxVert); bre
- case SB_SLIDERTRACK:
- iTopLine = (SHORT) usPosition;
- default: break;
- }
- if (SB_Command != SB_SLIDERTRACK)
- SetScroll(hWndVScroll, iTopLine, cchMaxVert);
- }
- Refresh(FALSE);
- }
-
- MRESULT AvioSize(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2) {
- /*
- Do the default AVIO sizing, and kyfe a few values
- */
- if (!fCreated) return 0L;
- /*
- Compute height and width of page in characters
-
- The scrollbars have already been subtracted out,
- since we are called by the client area.
- */
- cchPgHeight = CalcChars(SHORT2FROMMP(mp2), lChHeight, DEFPAGEHEIGHT);
- cchPgWidth = CalcChars(SHORT1FROMMP(mp2), lChWidth, DEFPAGEWIDTH);
- /*
- Adjust scrollbar maximums
- */
- cchMaxVert = Max(AVIO_PS_ROWS - cchPgHeight, 0);
- cchMaxHorz = Max(AVIO_PS_COLUMNS - cchPgWidth, 0);
- /*
- Maintain scrollbar integrity
- */
- fNeedHorz = (cchMaxHorz > 0);
- fNeedVert = (cchMaxVert > 0);
- SetScroll(hWndHScroll, iCurCol = Min(iCurCol, cchMaxHorz), cchMaxHorz);
- SetScroll(hWndVScroll, iTopLine = Min(iTopLine,cchMaxVert), cchMaxVert);
- /*
- Do the Scroll Bar shifting
- */
- Refresh(FALSE);
- /*
- Now, do the normal AVIO processing
- */
- return WinDefAVioWindowProc(hWnd, msg, mp1, mp2);
- }
-
- void Update
- (USHORT usLineNum, USHORT usHowMany, USHORT usStartLine, BOOL fForced) {
- /*
- Updates usHowMany lines starting from usStartLine on screen.
- Starts at saved line usLineNum. If fForced is set, all lines
- in range are displayed; otherwise it's lazy.
- */
- USHORT i; /* Loop index */
- USHORT usWhichLine = usLineNum; /* Line to be queried */
- Line l; /* Line to be output */
-
- for (i = usStartLine; i < (usStartLine + usHowMany); i++) {
- l = QueQuery(usWhichLine++); /* Get the line */
- if (!l->fDrawn || fForced) {
- if (l->cch) Blast(l, i, 0); /* Print it out */
- if (!l->fComplete) SetCursor(i, l->cch);
- l->fDrawn = TRUE;
- }
- }
- }
-
- void Refresh(BOOL fRedraw) {
- /*
- fRedraw forces full redraw if set
- */
- SHORT sDelta;
- int static iOldTopLine = -AVIO_PS_ROWS;
-
- VioSetOrg(0, iCurCol, hVPS); /* Get the free AVIO horizontal shift */
- sDelta = iTopLine - iOldTopLine; /* Compute vertical shift */
- if ((Abs(sDelta) < AVIO_PS_ROWS) && !fRedraw) {
- if (sDelta < 0) { /* Scroll Up -- make sDelta positive*/
- ScrollDown(-sDelta);
- Update(iTopLine, -sDelta, 0, TRUE);
- } else { /* Scroll Down by sDelta */
- ScrollUp(sDelta);
- Update(iTopLine + cchPgHeight - sDelta, sDelta,
- cchPgHeight - sDelta, TRUE);
- }
- } else AvioRedraw(); /* Redo the entire screen */
- iOldTopLine = iTopLine;
- }
-
- void AvioClose (void) {
- /*
- Termination routines
- */
- /*
- Destroy the Presentation Space
- */
- VioAssociate(NULL, hVPS);
- VioDestroyPS(hVPS);
- fCreated = FALSE;
- }
-
- void AvioPaint(HWND hWnd) {
- static HPS hPS;
- static RECTL rcl;
-
- hPS = WinBeginPaint(hWnd, NULL, &rcl);
- VioShowPS(AVIO_PS_ROWS, AVIO_PS_COLUMNS, 0, hVPS);
- WinEndPaint(hPS);
- }
-
- MRESULT AvioMinMax(PSWP pSWP) {
- /*
- Control Maximizing
- */
- if (pSWP->fs & (SWP_MAXIMIZE | SWP_RESTORE)) {
- if (pSWP->fs & SWP_MAXIMIZE) {
- /*
- Save cx, cy values for later origin displacement
- */
- int iOldcx = pSWP->cx;
- int iOldcy = pSWP->cy;
- /*
- Displace, and change to maximum size
- */
- pSWP->x += (iOldcx - (pSWP->cx = iMaxFrameWidth));
- pSWP->y += (iOldcy - (pSWP->cy = iMaxFrameHeight));
- }
- /*
- Now, fix the scroll bars
- */
- AvioAdjustFrame(pSWP);
- return (MRESULT) TRUE;
- }
- return FALSE;
- }
-
- void AvioClear(void) { ClearScreen(); }
-
- void AvioAdjustFrame(PSWP pSWP) {
- /*
- Trap WM_ADJUSTWINDOWPOS messages to the frame with this routine.
- Keep the window sized right, and control scrollbar visibility.
- */
- BOOL fNeededHorz = fNeedHorz;
- BOOL fNeededVert = fNeedVert;
- /*
- Do scrollbar enable/disable calculations (but don't update the screen)
- */
- if (pSWP->fs & SWP_MINIMIZE) fNeedHorz = fNeedVert = FALSE;
- if ((pSWP->cx * pSWP->cy) == 0) return;
- /*
- Do we need them?
- */
- fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight));
- fNeedHorz = (pSWP->cx < (SHORT) (iMaxFrameWidth + VBarWidth()));
- fNeedVert = (pSWP->cy < (SHORT) (iMaxFrameHeight + HBarHeight()));
- /*
- Do width calculations to make sure we're staying small enough.
- The Tracking Rectangle shouldn't allow us to get too big.
- */
- /*
- Check if we're stretching too far
- */
- pSWP->cx = Min(pSWP->cx, iMaxFrameWidth + (int) VBarWidth());
- pSWP->cy = Min(pSWP->cy, iMaxFrameHeight + (int) HBarHeight());
- /*
- ...if so, fix, then add them!
- */
- AvioSize(NULL, WM_NULL, NULL, MPFROM2SHORT(
- pSWP->cx - (int) (lMiscWidth + VBarWidth()),
- pSWP->cy - (int) (lMiscHeight + HBarHeight()) ));
-
- if (fNeedHorz) {
- if (!fNeededHorz) {
- EnableSB(hWndHScroll);
- UpdateOff(hWndHScroll);
- UpdateFrame(FCF_HORZSCROLL);
- UpdateOn(hWndHScroll);
- }
- } else {
- if (fNeededHorz) {
- DisableSB(hWndHScroll);
- UpdateOff(hWndHScroll);
- UpdateFrame(FCF_HORZSCROLL);
- UpdateOn(hWndHScroll);
- }
- }
- if (fNeedVert) {
- if (!fNeededVert) {
- EnableSB(hWndVScroll);
- UpdateOff(hWndVScroll);
- UpdateFrame(FCF_VERTSCROLL);
- UpdateOn(hWndVScroll);
- }
- } else {
- if (fNeededVert) {
- DisableSB(hWndVScroll);
- UpdateOff(hWndVScroll);
- UpdateFrame(FCF_VERTSCROLL);
- UpdateOn(hWndVScroll);
- }
- }
- }
-
- void AvioTrackFrame(HWND hWnd, MPARAM mpTrackFlags) {
- /*
- Takes action on WM_TRACKFRAME message
- */
- static TRACKINFO tiTrackInfo;
- /*
- Get the tracking information in the TrackInfo structure
- */
- WinSendMsg(hWnd, WM_QUERYTRACKINFO, mpTrackFlags, &tiTrackInfo);
- WinTrackRect(hWnd, NULL, &tiTrackInfo);
- }
-
- void AvioQueryTrackInfo(PTRACKINFO pTI) {
- /*
- Forces the frame to be byte aligned and bounded
- */
- BOOL fMove;
- /*
- Get the grid set up for byte alignment
-
- Set cxGrid to half a character width, because sizing
- from the keyboard tries to move by half characters.
- Also, make sure we can move the window freely.
- */
- fMove = ((pTI->fs & TF_MOVE) == TF_MOVE);
- pTI->fs |= TF_GRID;
- pTI->cxGrid = (fMove) ? 1 : ((SHORT) lChWidth);
- pTI->cyGrid = (fMove) ? 1 : ((SHORT) lChHeight);
- pTI->cxKeyboard = (SHORT) lChWidth;
- pTI->cyKeyboard = (SHORT) lChHeight;
- /*
- Bound the frame now
- */
- pTI->ptlMinTrackSize.x = (pTI->cxBorder << 1) + lMiscWidth;
- pTI->ptlMinTrackSize.y = (pTI->cyBorder << 1) + lMiscHeight;
- pTI->ptlMaxTrackSize.x = iMaxFrameWidth + lVSBWidth + (pTI->cxBorder <<
- pTI->ptlMaxTrackSize.y = iMaxFrameHeight + lHSBHeight + (pTI->cyBorder <<
- }
-
- BOOL AvioUpdateLines(BOOL fPage, BOOL *fPaging) {
- /*
- Update the display
- */
- int cLines;
-
- cLines = QueUpdateHead(AVIO_PS_ROWS, fPage, *fPaging);
- if (cLines == AVIO_PS_ROWS) *fPaging = TRUE;
- if (cLines > 0) {
- ScrollUp(cLines);
- Update(iTopLine + AVIO_PS_ROWS - cLines, cLines,
- AVIO_PS_ROWS - cLines, TRUE);
- }
- Update(iTopLine, cchPgHeight, 0, FALSE);
- return TRUE;
- }
-
- void AvioRedraw(void) {
- /*
- Clear, then redraw the entire Presentation Space
- */
- ClearScreen();
- Update(iTopLine, cchPgHeight, 0, TRUE);
- }
-
- void WantCursor(BOOL fYes) {
- /*
- Do the underscore cursor
- */
- vci.attr = (USHORT) (fYes ? 0 : -1);
- vci.yStart = 0;
- vci.cEnd = (USHORT) lChHeight - 1;
- vci.cx = 0;
- VioSetCurType(&vci, hVPS);
- }
-
- void AvioPageUp(void) {
- /*
- Execute the Page Up instruction
- */
- int cLines;
-
- cLines = QuePageUp(AVIO_PS_ROWS);
- ScrollDown(cLines);
- Update(iTopLine, cLines, 0, TRUE);
- }
-
-
-
- BIGBEN.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\BIGBEN\BIGBEN.C
-
- /*
- * This example uses a few of the many VIO calls.
- *
- * This example puts the time on the screen in large numbers.
- *
- * Created by Microsoft Corp. 1986
- */
-
- #include <os2def.h>
- #define INCL_DOSPROCESS
- #define INCL_DOSDATETIME
- #include <bsedos.h>
- #define INCL_SUB
- #include <bsesub.h>
- #include <stdio.h>
-
- #define CHAR_WIDTH 8
- #define CHAR_HEIGHT 7
-
- CLOCK_ROW 10 /* row to start the clock */
- TOTAL_COLMS 80 /* screen size in colms */
- TOTAL_ROWS 24 /* screen size in rows */
-
-
- char BigChars[10][CHAR_HEIGHT][CHAR_WIDTH] = {
-
- {
- " 00 ",
- " 0 0 ",
- " 0 0",
- " 0 0",
- " 0 0",
- " 0 0 ",
- " 00 "
- },
- {
- " 1 ",
- " 1 ",
- " 1 ",
- " 1 ",
- " 1 ",
- " 1 ",
- " 1 "
- },
- {
- " 2222 ",
- " 2 2",
- " 2",
- " 2 ",
- " 2 ",
- " 2 ",
- " 222222"
- },
- {
- " 33333 ",
- " 3",
- " 3",
- " 333 ",
- " 3",
- " 3",
- " 33333 "
- },
- {
- " 44 ",
- " 4 4 ",
- " 4 4 ",
- " 4 4 ",
- " 444444",
- " 4 ",
- " 4 "
- },
- {
- " 555555",
- " 5 ",
- " 55555 ",
- " 5",
- " 5",
- " 5 5",
- " 5555 "
- },
- {
- " 6 ",
- " 6 ",
- " 6 ",
- " 6666 ",
- " 6 6",
- " 6 6",
- " 6666 "
- },
- {
- " 777777",
- " 7",
- " 7 ",
- " 7 ",
- " 7 ",
- " 7 ",
- " 7 "
- },
- {
- " 8888 ",
- " 8 8",
- " 8 8",
- " 8888 ",
- " 8 8",
- " 8 8",
- " 8888 "
- },
- {
- " 9999 ",
- " 9 9",
- " 9 9",
- " 9999 ",
- " 9 ",
- " 9 ",
- " 9 "
- }
- };
-
-
- main(argc, argv)
- int argc;
- char *argv[];
- {
- unsigned rc; /* return code */
- DATETIME Now; /* time struct for DosGetDateTime */
-
- /* clear the screen */
-
- VioWrtNCell( " \07", TOTAL_ROWS * TOTAL_COLMS, 0, 0, 0 );
-
- /* paint separators between hours and minutes, and minutes and second
-
- VioWrtNCell( "|\07", 1, (CLOCK_ROW + 2), 27, 0 );
- VioWrtNCell( "|\07", 1, (CLOCK_ROW + 5), 27, 0 );
- VioWrtNCell( "|\07", 1, (CLOCK_ROW + 2), 52, 0 );
- VioWrtNCell( "|\07", 1, (CLOCK_ROW + 5), 52, 0 );
-
- for (;;) {
-
- /* get the system time */
-
- if (rc = DosGetDateTime( &Now)) {
-
- printf("DosGetDateTime failed, error: %d\n", rc);
- DosExit(EXIT_PROCESS, 0);
- }
-
- /* write the digits out to the screen */
-
- LoadNumber(Now.hours / 10, 5, CLOCK_ROW);
- LoadNumber(Now.hours % 10, 15, CLOCK_ROW);
- LoadNumber(Now.minutes / 10, 30, CLOCK_ROW);
- LoadNumber(Now.minutes % 10, 40, CLOCK_ROW);
- LoadNumber(Now.seconds / 10, 55, CLOCK_ROW);
- LoadNumber(Now.seconds % 10, 65, CLOCK_ROW);
-
- DosSleep(900L);
- }
- }
-
-
- /* display the digit at the given coordinates */
-
- LoadNumber( dig, x, y )
- unsigned dig;
- unsigned x;
- unsigned y;
- {
- int i;
-
- /* write a list of char strings to make up a display number */
-
- for (i=0; (i < CHAR_HEIGHT); i++)
-
- /* write a character string starting from the coordinates */
-
- VioWrtCharStr( BigChars[dig][i], CHAR_WIDTH, y++, x, 0);
- }
-
-
- BIO.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\BIO\BIO.C
-
- /* Biorhythm - Utility to compute personal biorhythm charts.
- *
- * Created by Microsoft Corp., 1989
- *
- * Purpose:
- * Program entry point, initialization and GetMessage loop.
- *
- * Arguments:
- * None
- *
- * Globals (modified):
- * hAB - Handle to the Anchor Block
- * hMsgQ - Handle to the application's message queue
- * hwndAppFrame - Window handle of parent window's frame
- * hwndKidFrame - Window handle of parent window's frame
- * hwndApp - Window handle of parent window's client area
- * hwndKid - Window handle of child window's client area
- * szAppName[10] - RC file program name (Biorhythm).
- * szKidName[10] - RC file child window name (Legend).
- *
- * Globals (referenced):
- * tmFontInfo - Text Metric structure defined during WM_CREATE
- *
- * Description:
- * The theory of biorhythms states that life consists of three cycles,
- * physical, emotional and intellectual of 23, 28 and 33 days,
- * respectively. The cycles each begin on the date of birth.
- *
- * Limits:
- * The intended use of this program is for the 20th and 21st centuries.
- * The calculations of biorhythms will not be accurate outside of this
- * range due to formulae used to compute days between dates.
- *
- */
-
- #define INCL_WIN
- #include <os2.h>
-
- #include <stddef.h>
-
- #include "bio.h"
-
- /* Write-once global variables */
- HAB hAB;
- HMQ hMsgQ;
- HWND hwndApp, hwndKid;
- HWND hwndAppFrame, hwndKidFrame;
- char szAppName[10];
- char szKidName[10];
- ULONG AppCtlData = FCF_STANDARD | FCF_VERTSCROLL | FCF_NOBYTEALIGN & ~
- ULONG KidCtlData = FCF_TITLEBAR;
- PFNWP OldFrameWndProc;
-
- /* Read-only global variables */
- extern FONTMETRICS tmFontInfo;
- extern SHORT cxLegendField;
- extern SHORT cxDateField;
-
- SHORT cdecl main( )
- {
- QMSG qMsg;
- SHORT dx, dy, x, y;
- SHORT cxSizeBorder;
- SHORT cySizeBorder;
- SHORT cxBorder;
- SHORT cyBorder;
-
- /* Standard initialization. Get anchor block and message queue. */
- hAB = WinInitialize(0);
- hMsgQ = WinCreateMsgQueue( hAB, 0 );
-
- /* Get string constants for parent and child window registration
- and creation from resource string table. */
- WinLoadString( hAB, (HMODULE) NULL, IDS_APPNAME, sizeof(szAppName), szApp
- WinLoadString( hAB, (HMODULE) NULL, IDS_KIDNAME, sizeof(szKidName), szKid
-
- /* Register parent window. Terminate if error. */
- if ( !WinRegisterClass( hAB, szAppName, BioWndProc,
- CS_CLIPCHILDREN | CS_SIZEREDRAW, 0 ) )
- return( FALSE );
-
- /* Register child window. Terminate if error. */
- if ( !WinRegisterClass( hAB, szKidName, KidWndProc, 0, 0 ) )
- return( FALSE );
-
- /* Create a parent window of class szAppName */
- hwndAppFrame = WinCreateStdWindow(
- HWND_DESKTOP,
- 0L,
- &AppCtlData,
- szAppName,
- NULL,
- 0L,
- (HMODULE) NULL,
- ID_BIO,
- (HWND FAR *)&hwndApp
- );
-
- /* Create a child window of class KidClass */
- hwndKidFrame = WinCreateStdWindow(
- hwndApp,
- FS_BORDER,
- &KidCtlData,
- szKidName,
- szKidName,
- 0L,
- (HMODULE) NULL,
- 0,
- (HWND FAR *)&hwndKid
- );
-
- /* Subclass frame so that minimum window size can be controled */
- OldFrameWndProc = WinSubclassWindow( hwndAppFrame, FrameWndProc );
-
- /* Get the size of the screen and border. Used to place and size window
- cxSizeBorder = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSIZEBORDER );
- cySizeBorder = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSIZEBORDER );
- cxBorder = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXBORDER );
- cyBorder = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER );
- x = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN )
- y = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN )
-
- /* Calculate width and height of child window. Must be able to
- display three lines and wide enough for text and corresponding colored
- line. Must take into account titlebar and border vertical sizes. */
- dx = cxLegendField * 2;
- dy = (SHORT)(tmFontInfo.lMaxBaselineExt*3 +
- WinQuerySysValue( HWND_DESKTOP, SV_CYTITLEBAR ) +
- WinQuerySysValue( HWND_DESKTOP, SV_CYBORDER ) * 2);
-
- /* Place and size parent and child windows, then make them visible.
- WinCreateStdWindow does not include position and size arguments.
- Parent window is thin, but full screen high. Child window is placed
- 10 pixels over and up from the parent window's lower left corner. */
- WinSetWindowPos( hwndAppFrame, NULL,
- x-(3*cxDateField)+cxSizeBorder,
- -cySizeBorder,
- (3*cxDateField),
- y+2*cySizeBorder,
- SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW );
- WinSetWindowPos( hwndKidFrame, NULL, 10, 10, dx, dy,
- SWP_MOVE | SWP_SIZE | SWP_ACTIVATE | SWP_SHOW );
-
- /* Get messages from application queue and dispatch them for processing *
- while( WinGetMsg( hAB, &qMsg, (HWND)NULL, 0, 0 ) )
- {
- WinDispatchMsg( hAB, &qMsg );
- }
-
- /* Clean up. All child windows will be destoyed automatically */
- WinDestroyWindow( hwndAppFrame );
- WinDestroyMsgQueue( hMsgQ );
- WinTerminate( hAB );
- }
-
-
- BIOCMD.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\BIO\BIOCMD.C
-
- /* BioDlg() - Dialog Box routine.
- *
- * Created by Microsoft Corporation, 1989
- *
- * Purpose:
- * Allow setting of birthdate and viewing date for biorhythm display.
- *
- * Arguments:
- * hDlg - Handle of Dialog Box owning message
- * message - Message itself
- * mp1 - Extra message-dependent info
- * mp2 - Extra message-dependent info
- *
- * Globals (modified):
- * Born - Birthdate in julian days. Read from OS2.INI.
- * SelectDay - Current day being tracked, day is highlighted.
- * This is stored as # days from birthdate.
- * This is initialized to the current date in WM_CREATE
- * Day - Day number from date born which is top line being
- * displayed. Initially three days before SelectDay.
- * bBorn - Boolean indicating whether valid birtdate entered or
- * defined in OS2.INI. Nothing graphed until valid.
- *
- * Globals (referenced):
- * hAB - Handle to the Anchor Block
- * szAppName[] - RC file program name (Biorhythm).
- *
- * Description:
- * Biorythm cycles start on the date of birth and the state of
- * of these cycles may be viewed on the selected date. A check
- * box is provided to update (record) the birthdate in the WIN.INI
- * file so that it will be automatically available in subsequent
- * sessions.
- *
- * Limits:
- * Minor error checking is provided when OK is selected to make
- * sure that the dates specified fall in the 20th and 21st
- * centuries. No error checking is attempted to verify correct
- * month or day of month entries.
- *
- */
-
- #define INCL_WIN
- #include <os2.h>
-
- #include "bio.h"
- #include <math.h>
- #include <stdio.h>
-
- /* Read-only global variables */
- extern HAB hAB;
- extern char szAppName[];
-
- /* Global variables (modified) */
- extern long SelectDay, Day;
- extern double Born;
- extern BOOL bBorn;
-
- /* Function prototypes */
- void InitBioDlg(HWND);
- void BioDlgCmd(HWND, MPARAM);
-
- MRESULT CALLBACK BioDlg( hDlg, message, mp1, mp2 )
- HWND hDlg;
- USHORT message;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch( message ) {
- case WM_INITDLG:
- InitBioDlg(hDlg);
- break;
-
- case WM_COMMAND:
- BioDlgCmd(hDlg, mp1);
- break;
-
- default:
- return( WinDefDlgProc( hDlg, message, mp1, mp2 ) );
-
- }
- return 0L;
- }
-
-
- /* About() - General purpose About dialog box.
- *
- * Purpose:
- * Provide program propoganda.
- *
- * Arguments:
- * hDlg - Handle of Dialog Box owning message
- * message - Message itself
- * mp1 - Extra message-dependent info
- * mp2 - Extra message-dependent info
- */
-
- MRESULT CALLBACK About( hWndDlg, message, mp1, mp2 )
- HWND hWndDlg;
- USHORT message;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch( message )
- {
- case WM_COMMAND:
- switch( LOUSHORT( mp1 ) )
- {
- case DID_OK:
- WinDismissDlg( hWndDlg, TRUE );
- break;
-
- default:
- break;
- }
- break;
-
- default:
- return( WinDefDlgProc( hWndDlg, message, mp1, mp2 ) );
- }
- return( FALSE );
- }
-
-
- void InitBioDlg(HWND hDlg) {
- /*
- If valid OS2.INI info, fill in birthdate edit fields
- */
- USHORT year, month;
- double day;
-
- if (bBorn) {
- calendar( Born, (int *)&year, (int *)&month, &day );
- WinSetDlgItemShort( hDlg, ID_BDYEAR, year, FALSE );
- WinSetDlgItemShort( hDlg, ID_BDMONTH, month, FALSE );
- WinSetDlgItemShort( hDlg, ID_BDDAY, (int)day, FALSE );
- }
- /* Display current date or date highlighted */
- calendar( Born+SelectDay, (int *)&year, (int *)&month, &day );
- WinSetDlgItemShort( hDlg, ID_YEAR, year, FALSE );
- WinSetDlgItemShort( hDlg, ID_MONTH, month, FALSE );
- WinSetDlgItemShort( hDlg, ID_DAY, (int)day, FALSE );
- }
-
-
- void BioDlgCmd(HWND hDlg, MPARAM mp1) {
- /*
- Bio Dialog Box routine WM_COMMAND processor
- */
- USHORT year, month, iDay;
- double day;
- char szBuf[10];
-
- switch( LOUSHORT( mp1 ) ) {
- case DID_OK:
- /* Get the birthday edit field values */
- WinQueryDlgItemShort( hDlg, ID_BDYEAR, &year, FALSE );
- WinQueryDlgItemShort( hDlg, ID_BDMONTH, &month, FALSE );
- WinQueryDlgItemShort( hDlg, ID_BDDAY, &iDay, FALSE );
- day = (double)iDay;
- /* Check that date is within acceptable range */
- if (year<1900 || year>2100) {
- WinMessageBox( HWND_DESKTOP, hDlg,
- "Dates valid from 1900-2100",
- "Birthday!", 0,
- MB_OK | MB_ICONEXCLAMATION );
- break;
- }
- /* Get julian date of birth date */
- Born = julian( year, month, day );
-
- /* Write birth date to OS2.INI if check box checked */
- if (WinSendDlgItemMsg(hDlg, ID_OS2INI, BM_QUERYCHECK, 0L, 0L)) {
- sprintf(szBuf, "%d", year);
- WinWriteProfileString( hAB, szAppName, "Year", szBuf );
- sprintf(szBuf, "%d", month);
- WinWriteProfileString( hAB, szAppName, "Month", szBuf );
- sprintf(szBuf, "%d", (int)day);
- WinWriteProfileString( hAB, szAppName, "Day", szBuf );
- }
-
- /* Get selected day of interest edit field values */
- WinQueryDlgItemShort( hDlg, ID_YEAR, &year, FALSE );
- WinQueryDlgItemShort( hDlg, ID_MONTH, &month, FALSE );
- WinQueryDlgItemShort( hDlg, ID_DAY, &iDay, FALSE );
- day = (double)iDay;
- /* Check that date is within acceptable range */
- if (year<1900 || year>2100) {
- WinMessageBox( HWND_DESKTOP, hDlg,
- "Dates valid from 1900-2100",
- "Display Date!", 0,
- MB_OK | MB_ICONEXCLAMATION );
- break;
- }
-
- /* Compute number of days since birth */
- SelectDay = (long)(julian( year, month, day ) - Born);
- /* Top date of display is 3 days before selected day */
- Day = SelectDay - 3;
- /* Got a valid birthdate, enable all routines */
- bBorn = TRUE;
- WinDismissDlg( hDlg, TRUE );
- break;
-
- case DID_CANCEL:
- /* Exit and ignore entries */
- WinDismissDlg( hDlg, FALSE );
- break;
-
- default:
- break;
- }
- }
-
-
- BIOPAINT.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\BIO\BIOPAINT.C
-
- /*
- biopaint.c - WM_PAINT processing and calendar conversion routine
-
- Created by Microsoft Corporation, 1989
- */
- #define INCL_WIN
- #define INCL_GPI
- #include <os2.h>
-
- #include "bio.h"
- #include <math.h>
- #include <stdio.h>
-
- /* Read-only global variables */
- extern double Born;
- extern long Day, SelectDay;
- extern BOOL bBorn;
- extern FONTMETRICS tmFontInfo;
- extern int LinesPerPage;
- extern RECTL rclClient;
- extern SHORT cxDateField;
-
- /* Read-only static variables */
- static double Cycle[] = { 23.0, 28.0, 33.0 };
- static char cDayOfWeek[] = "MTWTFSS";
- extern LONG Color[];
-
-
-
- /* APPPaint() - Parent window WM_PAINT processing routine.
- *
- * Purpose:
- * Routine to graph biorhythm cycles and tabulate dates.
- *
- * Arguments:
- * hWnd - Handle of Window owning message
- * message - Message itself
- * mp1 - Extra message-dependent info
- * mp2 - Extra message-dependent info
- *
- * Globals (static):
- * Cycle[] - Array holding period for phy/emot/int: 23,28,33
- * cDayOfWeek[] - Array of chars holding first letter of days of week.
- * Color[] - Set of colored pens used to identify cycles.
- *
- * Globals (referenced):
- * Born - Birthdate in julian days. Read from WIN.INI.
- * SelectDay - Current day being tracked, day is highlighted.
- * This is stored as the number of days from birthdate.
- * Initialized to present day in WM_CREATE processing.
- * Day - Day number from date born which is top line being
- * displayed. Initially three days before SelectDay.
- * bBorn - Boolean indicating whether valid birtdate entered or
- * rclClient - Size of client area defined by WM_SIZE message
- * LinesPerPage - Number of system font lines on client area, defined
- * by WM_SIZE message handling
- * tmFontInfo - Text Metric structure defined during WM_CREATE
- *
- * Description:
- * Tabulates dates and graphs cycles. On color displays, weekends
- * are written in red. The update rectangle is used to minimize
- * repaint time of affected client area.
- */
- VOID APIENTRY APPPaint( hWnd )
- HWND hWnd;
- {
- HPS hPS;
- POINTL ptl;
- int y, i;
- int start, last;
- char szDay[16];
- int Amplitude, offset;
- int year, month;
- double day;
- RECTL rc, rcClip;
- int DayOfWeek;
- HRGN hrgnClip;
- POINTL ptlTextBox[5];
-
- hPS = WinBeginPaint( hWnd, NULL, &rcClip );
-
- /* Erase client area */
- WinQueryWindowRect( hWnd, &rc );
- WinFillRect( hPS, &rc, CLR_WHITE );
-
- /* Label parts of table and graph. */
- ptl.y = rclClient.yTop - tmFontInfo.lMaxBaselineExt + /* Top line */
- tmFontInfo.lMaxDescender;
- ptl.x = 0;
- GpiCharStringAt( hPS, &ptl, 7L, (PCH)" DATE" );
- ptl.x = cxDateField + tmFontInfo.lAveCharWidth;
- GpiCharStringAt( hPS, &ptl, 3L, (PCH)"LOW" );
- GpiQueryTextBox( hPS, 4L, "HIGH", TXTBOX_COUNT, ptlTextBox );
- ptl.x = rclClient.xRight - ptlTextBox[TXTBOX_CONCAT].x - tmFontInfo.lAveC
- GpiCharStringAt( hPS, &ptl, 4L, (PCH)"HIGH" );
-
- /* Underline labels from left to right across client area */
- ptl.y = rclClient.yTop - tmFontInfo.lMaxBaselineExt;
- ptl.x = 0;
- GpiMove( hPS, &ptl );
- ptl.x = rclClient.xRight;
- GpiLine( hPS, &ptl );
-
- /* Draw a vertical line separator between dates and cycles */
- ptl.y = rclClient.yTop;
- ptl.x = cxDateField;
- GpiMove( hPS, &ptl );
- ptl.y = rclClient.yBottom;
- GpiLine( hPS, &ptl );
-
- /* Draw a dotted vertical center line to reference cycles */
- GpiSetLineType( hPS, LINETYPE_DOT );
- ptl.x = (cxDateField + rclClient.xRight) / 2;
- GpiMove( hPS, &ptl );
- ptl.y = rclClient.yTop;
- GpiLine( hPS, &ptl );
- /* (Should not have to restore line type after EndPaint) */
- GpiSetLineType( hPS, LINETYPE_DEFAULT );
-
- /* Update only the range of lines which fall into update rectangle */
- start = (int)((rclClient.yTop - rcClip.yTop) / tmFontInfo.lMaxBaselineExt
- if (start<1)
- start = 1;
- last = (int)((rclClient.yTop - rcClip.yBottom) / tmFontInfo.lMaxBaselineE
- if (last>(LinesPerPage-1))
- last = LinesPerPage-1;
-
- /* Set clip rectangle to completely draw entire rectangle representing
- each date affected. Start drawing one day before and after
- (outside clip rectangle) so that cycle lines will connect correctly
- with unaffected lines. */
- rcClip.yTop = rclClient.yTop - start*tmFontInfo.lMaxBaselineExt;
- start--;
- last++;
- rcClip.yBottom = rclClient.yTop - last*tmFontInfo.lMaxBaselineExt + 1;
- hrgnClip = GpiCreateRegion( hPS, 1L, &rcClip );
- GpiSetClipRegion( hPS, hrgnClip, &hrgnClip );
-
- /* List days and date */
- for (y=start; y<=last; y++) {
- /* Get the calendar date from julian day */
- calendar( Born+Day+y-1, &year, &month, &day );
- /* Get offset into days of the week initials array */
- DayOfWeek = (int)((LONG)(Born+Day+y) % 7);
- /* Assemble each of the parts in a buffer */
- sprintf(szDay, " %02d-%02d-%02d",
- month, (int)day, year - (trunc4((double)year / 100)*100) );
- /* If color available, draw weekends in red */
- if (DayOfWeek > 4)
- GpiSetColor( hPS, CLR_RED );
- ptl.x = 0;
- ptl.y = rclClient.yTop - ((y+1)*tmFontInfo.lMaxBaselineExt -
- tmFontInfo.lMaxDescender);
- GpiCharStringAt( hPS, &ptl, 1L, (PCH)&cDayOfWeek[DayOfWeek] );
- GpiQueryWidthTable( hPS, (LONG)'W', 1L, &ptl.x );
- GpiCharStringAt( hPS, &ptl, 9L, (PCH)szDay );
- GpiSetColor( hPS, CLR_BLACK );
- }
-
- /* Amplitude of sin wave is half client area minus space for dates */
- Amplitude = (int)((rclClient.xRight - cxDateField - tmFontInfo.lAveCharWi
- /* Move to right, make room for column of dates */
- offset = (int)(Amplitude + cxDateField + tmFontInfo.lAveCharWidth - (tmFo
- for (i=0; i<3 && bBorn; i++ ) {
- GpiSetColor( hPS, Color[i] );
- for (y=start; y<=last; y++) {
- ptl.x = (int)(sin( (y+Day-1)/Cycle[i]*2*3.14159 ) * Amplitude + o
- ptl.y = rclClient.yTop - (y*tmFontInfo.lMaxBaselineExt +
- tmFontInfo.lMaxBaselineExt/2);
- if ((y+Day-1 > 0) && (y>start))
- GpiLine( hPS, &ptl );
- else
- GpiMove( hPS, &ptl );
- }
- }
-
- /* Draw highlight on selected day if visible. */
- if ((SelectDay >= Day) && (SelectDay - Day < LinesPerPage - 1)) {
- rc.xRight = rclClient.xRight;
- rc.xLeft = rclClient.xLeft;
- rc.yTop = rclClient.yTop - (int)(SelectDay - Day + 1) * tmFontInfo.lM
- rc.yBottom = rc.yTop - tmFontInfo.lMaxBaselineExt + 1;
- WinInvertRect( hPS, &rc );
- }
-
- WinEndPaint( hPS );
-
- return;
- }
-
-
- /* julian() - Compute julian date from Gregorian calendar date.
- *
- * Purpose:
- * Provide a standard time base.
- *
- * Arguments:
- * year - Calendar year
- * month - Calendar month
- * day - Calendar day and fraction
- *
- * Return Value:
- * double - Julian date converted
- *
- * Description:
- * Convert Gregorian dates to Julian Days. Refer to Alamanac for
- * Computers (1978), p. B2, Naval Observatory Pub.
- *
- * Limits:
- * Valid between ~1900 and 2099.
- *
- */
-
- double PASCAL julian (year, month, day)
- int year, month;
- double day;
- {
- double dj;
- double fracDay, intDay;
-
- fracDay = modf(day, &intDay);
- dj = (long)367*year - 7*(year + (month+9) / 12) / 4 + 275*month / 9 +
- intDay + 1721013.5 + fracDay;
- return dj;
- }
-
-
- /* calendar() - Compute Gregorian calendar date from julian date.
- *
- * Purpose:
- * Provide a standard time base.
- *
- * Arguments:
- * juldate - Julian date to convert
- * year - Calendar year result
- * month - Calendar month result
- * day - Calendar day and fraction result
- *
- * Return Value:
- * void
- *
- * Globals (modified):
- * none
- *
- * Globals (referenced):
- * none
- *
- * Description:
- * Convert Julian Days to Gregorian date. Refer to Astronomical
- * Formulae for Calculators (1979), p. 23, by Jean Meeus.
- *
- * Limits:
- * Valid for positive Julian Day values.
- *
- */
-
- void PASCAL calendar (juldate, year, month, day)
- double juldate;
- int *year;
- int *month;
- double *day;
- {
- long b, c, d, e, z, alf;
-
- juldate = juldate + 0.5;
- z = trunc4(juldate);
- alf = trunc4((z - 1867216.25)/36524.25);
- b = z + 1 + alf - alf / 4 + 1524;
- c = trunc4((b - 122.1)/365.25);
- d = 365*c + c / 4;
- e = trunc4((b - d)/30.6001);
- *day = b - d - trunc4(30.6001*e) + juldate - z;
- if (e > 13)
- *month = (int)e - 13;
- else
- *month = (int)e - 1;
- if (*month > 2)
- *year = (int)c - 4716;
- else
- *year = (int)c - 4715;
- }
-
- long PASCAL trunc4( dflValue )
- double dflValue;
- {
- double intValue;
- modf(dflValue, &intValue);
- return (long)intValue;
- }
-
-
- BMAP.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\MSNGR\BMAP.C
-
- /****************************** MODULE Header ******************************\
- * Module Name: bmap.c - Messenger application - bitmap module
- *
- * Created: 8/1/89 sanfords
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
-
- #include "msngr.h"
- #include "string.h"
- #ifdef SLOOP
- #define BITMAPINFOHEADER2 BITMAPINFOHEADER
- #define PBITMAPINFOHEADER2 PBITMAPINFOHEADER
- #define BITMAPINFO2 BITMAPINFO
- #define PBITMAPINFO2 PBITMAPINFO
- #endif
-
- typedef struct _CDATA {
- RECTL rcl;
- HBITMAP hbm;
- BOOL fSelect;
- BOOL fSelecting;
- NPUSERLIST npUL;
- } CDATA;
- typedef CDATA *NPCDATA;
-
-
- typedef struct _PKT {
- HBITMAP hbm;
- SHORT cx;
- SHORT cy;
- char szName[MAX_NAMESTR + 1];
- } PKT;
- typedef PKT *NPPKT;
-
- extern HWND hwndMsngr;
- extern SHORT cyText;
- extern HAB hab;
- extern HSZ hszAppName;
- extern HSZ hszEmailName;
- extern char szEmailName[];
- extern HWND hwndLB;
- extern ITEMLIST msgTopicItemList[];
-
-
-
- /*
- * local procs
- */
- MRESULT bmpInit(HWND hwnd, NPPKT ppktInit);
- MRESULT sndBmapInit(HWND hwnd, NPUSERLIST pUserItem);
- BOOL sndBmap(NPCDATA pcd);
- HBITMAP SnapRegion(HPS hps, PRECTL prcl);
- void DrawRgn(HPS hps, PRECTL prcl);
- void SortRect(PRECTL prcl, PRECTL prclSorted);
- HDC CreateDC(PSZ lpszDriver, HDC hdcCompat);
-
- #define max(a,b) (((a) > (b)) ? (a) : (b))
-
- /*
- * file globals
- */
- ATOM fmtBmapPkt;
- HPOINTER hptrSelBmap = 0;
- HPOINTER hptrBmap = 0;
-
- void InitBmapModule()
- {
- fmtBmapPkt = WinAddAtom(WinQuerySystemAtomTable(), SZBMAPDATA);
- hptrSelBmap = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_SELBMAP);
- hptrBmap = WinLoadPointer(HWND_DESKTOP, NULL, IDD_GETBITMAP);
- }
-
- void CloseBmapModule()
- {
- WinDeleteAtom(WinQuerySystemAtomTable(), fmtBmapPkt);
- WinDestroyPointer(hptrSelBmap);
- WinDestroyPointer(hptrBmap);
- }
-
- HDMGDATA bmpXfer(pXferInfo)
- PXFERINFO pXferInfo;
- {
- PBYTE pbuf;
- PKT pkt;
- PBITMAPINFO pbmi;
- HDC hdc;
- HPS hpsMem;
- SIZEL size;
-
- if (pXferInfo->usFmt != fmtBmapPkt)
- return(DDE_NOTPROCESSED);
-
- if (pXferInfo->usType == XTYP_POKE) {
- /*
- * we have bitmap bits...stick them into pkt.hbm.
- */
- pbuf = DdeAccessData(pXferInfo->hDmgData);
-
- DdeCopyBlock(pbuf, (PBYTE)&pkt.szName[0], MAX_NAMESTR + 1L);
- pbmi = (PBITMAPINFO)(pbuf + MAX_NAMESTR + 1);
-
- pkt.cx = pbmi->cx;
- pkt.cy = pbmi->cy;
- size.cx = (LONG)pkt.cx;
- size.cy = (LONG)pkt.cy;
- hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);
- hpsMem = GpiCreatePS(hab, hdc, &size,
- PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );
- pkt.hbm = GpiCreateBitmap(hpsMem, (PBITMAPINFOHEADER2)pbmi, CBM_INIT,
- (PBYTE)&pbmi->argbColor[1 << pbmi->cBitCount],
- (PBITMAPINFO2)pbmi);
- GpiAssociate(hpsMem, NULL);
- GpiDestroyPS(hpsMem);
- DevCloseDC(hdc);
- DdeFreeData(pXferInfo->hDmgData);
-
- WinLoadDlg(HWND_DESKTOP, hwndMsngr, BmpDlgProc, 0L, IDD_GETBITMAP,
- (PVOID)&pkt);
- return(1);
- }
- return(0);
- }
-
-
- /*
- * This is the proc used for receiving a bitmap
- */
- MRESULT EXPENTRY BmpDlgProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- HBITMAP hbm;
- HPS hps;
- WRECT wrc;
-
- switch(msg) {
- case WM_INITDLG:
- return(bmpInit(hwnd, (NPPKT)(SHORT)mp2));
- break;
-
- case WM_DESTROY:
- if (hbm = ((NPPKT)WinQueryWindowUShort(hwnd, QWS_USER))->hbm)
- GpiDeleteBitmap(hbm);
- WinFreeMem(hheap, (NPBYTE)WinQueryWindowUShort(hwnd, QWS_USER),
- sizeof(PKT));
- break;
-
- case WM_WINDOWPOSCHANGED:
- /*
- * hide the OK button when minimized since it messes up the icon.
- */
- if ((LONG)mp2 & AWP_MINIMIZED)
- WinShowWindow(WinWindowFromID(hwnd, MBID_OK), FALSE);
- else if ((LONG)mp2 & AWP_RESTORED)
- WinShowWindow(WinWindowFromID(hwnd, MBID_OK), TRUE);
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- break;
-
- case WM_COMMAND:
- WinDestroyWindow(hwnd);
- break;
-
- case WM_PAINT:
- WinDefDlgProc(hwnd, msg, mp1, mp2);
- /*
- * draw the bitmap just above the OK button.
- */
- hps = WinGetPS(hwnd);
- WinQueryWindowRect(WinWindowFromID(hwnd, MBID_OK), (PRECTL)&wrc);
- WinMapWindowPoints(WinWindowFromID(hwnd, MBID_OK), hwnd, (PPOINTL)&wr
- wrc.yBottom = wrc.yTop + cyText / 2;
- hbm = ((NPPKT)WinQueryWindowUShort(hwnd, QWS_USER))->hbm;
- WinDrawBitmap(hps, hbm, (PRECTL)NULL, (PPOINTL)&wrc, 0L, 0L, DBM_NORM
- WinReleasePS(hps);
- break;
-
- default:
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- }
- return(0);
- }
-
-
- MRESULT bmpInit(hwnd, ppktInit)
- HWND hwnd;
- NPPKT ppktInit;
- {
- char szTitle[MAX_TITLESTR];
- WRECT wrc;
- NPPKT ppkt;
- SHORT cxMin;
-
- if (!(ppkt = (NPPKT)WinAllocMem(hheap, sizeof(PKT))))
- return(1);
- *ppkt = *ppktInit;
- WinSetWindowUShort(hwnd, QWL_USER, (USHORT)ppkt);
- /*
- * This is required because currently, automatic ICON resource loading
- * is not supported for dialogs.
- */
- WinSendMsg(hwnd, WM_SETICON, (MPARAM)hptrBmap, 0L);
- /*
- * Set up title.
- */
- WinQueryWindowText(hwnd, MAX_TITLESTR, (PSZ)szTitle);
- lstrcat(szTitle, szTitle, ppkt->szName);
- WinSetWindowText(hwnd, (PSZ)szTitle);
- /*
- * resize the dialog so the bitmap just fits.
- */
- WinQueryWindowRect(hwnd, (PRECTL)&wrc);
- cxMin = wrc.xRight;
- WinQueryWindowRect(WinWindowFromID(hwnd, MBID_OK), (PRECTL)&wrc);
- WinMapWindowPoints(WinWindowFromID(hwnd, MBID_OK), hwnd, (PPOINTL)&wrc, 2
- WinSetWindowPos(hwnd, NULL, 0, 0, max(wrc.xLeft * 2 + ppkt->cx, cxMin),
- wrc.yTop + ppkt->cy + cyText +
- (SHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR), SWP_SIZE);
- return(0);
- }
-
-
-
- MRESULT EXPENTRY SendBitmapDlgProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- NPCDATA pcd;
- POINTL pt;
- HPS hps;
-
- pcd = (NPCDATA)WinQueryWindowUShort(hwnd, QWS_USER);
-
- switch (msg) {
- case WM_INITDLG:
- return(sndBmapInit(hwnd, (NPUSERLIST)(SHORT)mp2));
- break;
-
- case WM_DESTROY:
- WinFreeMem(hheap, (NPBYTE)pcd, sizeof(CDATA));
- break;
-
- case WM_COMMAND:
- switch (LOUSHORT(mp1)) {
- case IDC_SENDBITMAP:
- if (sndBmap(pcd))
- WinDismissDlg(hwnd, 0);
- break;
-
- case MBID_CANCEL:
- WinDismissDlg(hwnd, 0);
- break;
-
- case IDC_SELECT:
- pcd->fSelect = TRUE;
- WinSetCapture(HWND_DESKTOP, hwnd);
- break;
- }
- break;
-
- case WM_BUTTON1DOWN:
- if (pcd->fSelect) {
- if (pcd->hbm) {
- GpiDeleteBitmap(pcd->hbm);
- pcd->hbm = NULL;
- }
- WinSetRect(hab, &pcd->rcl, SHORT1FROMMP(mp1), SHORT2FROMMP(mp1),
- SHORT1FROMMP(mp1), SHORT2FROMMP(mp1));
- WinMapWindowPoints(hwnd, (HWND)HWND_DESKTOP, (PPOINTL)&pcd->rcl,
- hps = WinGetScreenPS(HWND_DESKTOP);
- DrawRgn(hps, &pcd->rcl);
- WinReleasePS(hps);
- pcd->fSelecting = TRUE;
- }
- break;
-
- case WM_MOUSEMOVE:
- if (pcd->fSelect) {
- WinSetPointer(HWND_DESKTOP, hptrSelBmap);
- } else {
- WinSetPointer(HWND_DESKTOP,
- WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE));
- }
- if (pcd->fSelecting) {
- hps = WinGetScreenPS(HWND_DESKTOP);
- DrawRgn(hps, &pcd->rcl); /* erase old rect */
- pt.x = SHORT1FROMMP(mp1);
- pt.y = SHORT2FROMMP(mp1);
- WinMapWindowPoints(hwnd, HWND_DESKTOP, &pt, 1);
- pcd->rcl.xRight = pt.x;
- pcd->rcl.yTop = pt.y;
- DrawRgn(hps, &pcd->rcl); /* draw new one */
- WinReleasePS(hps);
- }
- break;
-
- case WM_BUTTON1UP:
- if (pcd->fSelecting) {
- WinSetCapture(HWND_DESKTOP, (HWND)NULL);
- hps = WinGetScreenPS(HWND_DESKTOP);
- DrawRgn(hps, &pcd->rcl);
- pcd->hbm = SnapRegion(hps, &pcd->rcl);
- WinReleasePS(hps);
- pcd->fSelecting = FALSE;
- pcd->fSelect = FALSE;
- WinEnableWindow(WinWindowFromID(hwnd, IDC_SENDBITMAP),
- !WinIsRectEmpty(hab, &pcd->rcl));
- }
- break;
-
-
- default:
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0);
- }
-
-
- /*
- * returns fFailed
- */
- MPARAM sndBmapInit(hwnd, pUserItem)
- HWND hwnd;
- NPUSERLIST pUserItem;
- {
- NPCDATA pcd;
- char szTitle[MAX_TITLESTR];
- char szName[MAX_NAMESTR];
-
- if (!(pcd = (NPCDATA)WinAllocMem(hheap, sizeof(CDATA))))
- return(1);
- WinSetRectEmpty(hab, &pcd->rcl);
- pcd->hbm = NULL;
- pcd->fSelect = FALSE;
- pcd->fSelecting = FALSE;
- pcd->npUL = pUserItem;
- if (pcd->npUL->hConvMsg == NULL) {
- NotifyUser(SZCANTCONNECT);
- return(1);
- }
- WinQueryWindowText(hwnd, MAX_TITLESTR, szTitle);
- DdeGetHszString(pcd->npUL->hsz, szName, (LONG)MAX_NAMESTR);
- lstrcat(szTitle, szTitle, szName);
- WinSetWindowText(hwnd, (PSZ)szTitle);
- WinSetWindowUShort(hwnd, QWS_USER, (USHORT)pcd);
- return(0);
- }
-
-
- BOOL sndBmap(pcd)
- NPCDATA pcd;
- {
- BITMAPINFOHEADER bih;
- SHORT cbBuffer, cbBitmapInfo;
- PBYTE pbBuffer;
- PBITMAPINFO pbmi;
- PSZ pszName;
- SEL sel;
- HPS hps;
- HDC hdc;
- SIZEL size;
-
- /*
- * Compute the size of the image-data buffer and the bitmap information
- * structure.
- */
- GpiQueryBitmapParameters(pcd->hbm, &bih);
- cbBuffer = (((bih.cBitCount * bih.cx) + 31) / 32) * 4;
- if (cbBuffer > 0xFFFF / bih.cy / bih.cPlanes) {
- NotifyUser(SZTOOBIG);
- return(FALSE);
- }
- cbBuffer *= bih.cy * bih.cPlanes;
- cbBitmapInfo = sizeof(BITMAPINFO) +
- (sizeof(RGB) * (1 << bih.cBitCount));
-
- /*
- * Allocate memory for the image data-buffer and the bitmap information
- * structure.
- */
- DosAllocSeg(cbBuffer + cbBitmapInfo + MAX_NAMESTR + 1, &sel, 0);
- pszName = (PSZ)MAKEP(sel, 0);
- lstrcpy(pszName, szEmailName);
- pbmi = (PBITMAPINFO)(pszName + MAX_NAMESTR + 1);
- pbBuffer = (PBYTE)&pbmi->argbColor[1 << bih.cBitCount];
- *(PBITMAPINFOHEADER)pbmi = bih;
-
- size.cx = (LONG)bih.cx;
- size.cy = (LONG)bih.cy;
- hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);
- hps = GpiCreatePS(hab, hdc, &size,
- PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );
- GpiSetBitmap(hps, pcd->hbm);
- GpiQueryBitmapBits(hps, 0L, (LONG)bih.cy, (PBYTE)pbBuffer,
- (PBITMAPINFO2)pbmi);
- GpiAssociate(hps, NULL);
- GpiDestroyPS(hps);
- DevCloseDC(hdc);
-
- if (!DdeClientXfer(pszName,
- (LONG)(cbBuffer + cbBitmapInfo + MAX_NAMESTR + 1),
- pcd->npUL->hConvMsg,
- msgTopicItemList[IIL_BMPXFER].hszItem,
- fmtBmapPkt, XTYP_POKE, ulTimeout, 0L)) {
- MyPostError(DdeGetLastError());
- }
-
- DosFreeSeg(sel);
- GpiDeleteBitmap(pcd->hbm);
- pcd->hbm = NULL;
- WinSetRectEmpty(hab, &pcd->rcl);
- return(TRUE);
- }
-
-
- HBITMAP SnapRegion(hps, prcl)
- HPS hps;
- PRECTL prcl;
- {
- HDC hdc;
- HBITMAP hbm, hbmOld;
- BITMAPINFOHEADER bih;
- POINTL rgpt[3];
- HPS hpsMem;
- SIZEL size;
-
- SortRect(prcl, prcl);
- WinInflateRect(hab, prcl, -1, -1);
-
- size.cx = (USHORT)(prcl->xRight - prcl->xLeft);
- size.cy = (USHORT)(prcl->yTop - prcl->yBottom);
-
- /* Create a memory DC */
- hdc = CreateDC((PSZ)"MEMORY", (HDC)NULL);
-
- /* create a memory PS */
- hpsMem = GpiCreatePS(hab, hdc, &size,
- PU_ARBITRARY | GPIT_NORMAL | GPIA_ASSOC );
-
- /* Create a bitmap */
- bih.cbFix = sizeof(BITMAPINFOHEADER);
- bih.cx = (SHORT)size.cx;
- bih.cy = (SHORT)size.cy;
- bih.cPlanes = 1;
- bih.cBitCount = 8;
- hbm = GpiCreateBitmap(hpsMem, (PBITMAPINFOHEADER2)&bih, 0L, 0, 0);
- if (hbm == GPI_ERROR)
- return(0);
-
- /* put the bitmap into the memory PS */
- hbmOld = GpiSetBitmap(hpsMem, hbm);
-
- /* copy the window to the memory PS */
- rgpt[0].x = 0;
- rgpt[0].y = 0;
- rgpt[1].x = size.cx;
- rgpt[1].y = size.cy;
- rgpt[2].x = prcl->xLeft;
- rgpt[2].y = prcl->yBottom;
- GpiBitBlt(hpsMem, hps, 3L, (PPOINTL)&rgpt[0], ROP_SRCCOPY, 0L);
-
- /* free the bitmap */
- GpiSetBitmap(hpsMem, hbmOld);
-
- /* destroy the memory DC */
- GpiAssociate(hpsMem, NULL);
- GpiDestroyPS(hpsMem);
- DevCloseDC(hdc);
- return(hbm);
- } /* end snapregion */
-
-
- HDC CreateDC(lpszDriver, hdcCompat)
- PSZ lpszDriver;
- HDC hdcCompat;
- {
- struct {
- ULONG FAR *lpLogAddr;
- PSZ lpszDriver;
- } opendc;
-
- opendc.lpLogAddr = NULL;
- opendc.lpszDriver = lpszDriver;
-
- return((HDC)DevOpenDC(hab, OD_MEMORY, (PSZ)"*", 2L,
- (PDEVOPENDATA)&opendc, hdcCompat));
- }
-
-
- void DrawRgn(hps, prcl)
- HPS hps;
- PRECTL prcl;
- {
- RECTL rclSorted;
-
- SortRect(prcl, &rclSorted);
- WinDrawBorder(hps, &rclSorted, 1, 1, SYSCLR_WINDOW, SYSCLR_WINDOW,
- DB_DESTINVERT | DB_STANDARD);
- }
-
- void SortRect(prcl, prclSorted)
- PRECTL prcl;
- PRECTL prclSorted;
- {
- LONG l;
-
- WinCopyRect(hab, prclSorted, prcl);
- if (prclSorted->yTop < prclSorted->yBottom) {
- l = prclSorted->yBottom;
- prclSorted->yBottom = prclSorted->yTop;
- prclSorted->yTop = l;
- }
-
- if (prclSorted->xRight < prclSorted-> xLeft) {
- l = prclSorted->xRight;
- prclSorted->xRight = prclSorted->xLeft;
- prclSorted->xLeft = l;
- }
- }
-
-
-
-
-
-
- BROWSE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\BROWSE\AVBROWSE\BROWSE.C
-
- /*
- browse.c -- AVIO File Browsing Utility
-
- Created by Microsoft Corporation, 1989
- */
- #define INCL_WINTRACKRECT
- #define INCL_WINWINDOWMGR
- #define INCL_WINPOINTERS
- #define INCL_WINFRAMEMGR
- #include <os2.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include "avio.h"
- #include "browse.h"
- #include <opendlg.h>
- /*
- Constants
- */
- #define MAXLINELEN 120
- #define AVIO_PS_ROWS 25
- #define AVIO_PS_COLS 80
- /*
- Global Variables
- */
- FILE *pfInput;
- PFNWP pfnOldClient;
- char *aszLines[NUM_DATA_LINES];
- SHORT sTopLine = 0;
- DLF dlfInput;
- HFILE hfInput;
- USHORT usAction;
- LBINFO lbiData;
- HPOINTER hptrWait;
- HPOINTER hptrArrow;
- HWND hWndClient;
- HWND hWndFrame;
- BOOL fLargeFont = FALSE;
- SHORT sMaxLine;
- /*
- Open the input file
- */
- int cdecl main(int argc, char *argv[]) {
- static CHAR szClientClass[] = "Browse";
- static CHAR szCaption[] = "";
- HAB hAB;
- HMQ hmq;
- QMSG qmsg;
- ULONG flFrameFlags = FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCRO
- ULONG flFrameStyle = WS_VISIBLE | FS_SCREENALIGN;
- char *szInFile;
-
- hAB = WinInitialize(0);
- hmq = WinCreateMsgQueue(hAB, 0);
-
- WinRegisterClass(hAB, szClientClass, BrowseWndProc, CS_SYNCPAINT, 0);
-
- hWndFrame = WinCreateStdWindow(HWND_DESKTOP, flFrameStyle,
- &flFrameFlags, szClientClass, szCaption,
- 0L, (HMODULE) NULL, ID_RESOURCE, &hWndCl
- /*
- Get the hourglass and arrow pointers
- */
- hptrWait = WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, FALSE);
- hptrArrow = WinQuerySysPointer(HWND_DESKTOP, SPTR_ARROW, FALSE);
-
- if (argc == 1) pfInput = stdin;
- else {
- if (!(pfInput = fopen(argv[1], "r"))) {
- fprintf(stderr, "***Error: Could not open %s", szInFile);
- return(-1);
- }
- }
- ReadFile();
- /*
- Setup AVIO PS and force a paint
- Note: This subclasses the client and frame windows
- */
- lbiData.sPSrows = AVIO_PS_ROWS;
- lbiData.sPScols = AVIO_PS_COLS;
- lbiData.sRows = sTopLine;
- lbiData.sCols = sMaxLine;
- lbiData.pfnQL = (PFNQL) RetrieveLine;
- lbiData.fLargeFont = FALSE;
- AvioInit(&lbiData);
- /*
- Process messages
- */
- while (WinGetMsg(hAB, &qmsg, NULL, 0, 0)) WinDispatchMsg(hAB, &qmsg);
-
- /* Blast the AVIO PS */
- AvioClose();
-
- WinDestroyWindow(hWndFrame);
- WinDestroyMsgQueue(hmq);
- WinTerminate(hAB);
- return 0;
- }
-
- void ReadFile(void) {
- /*
- Reads in a file using <stdio.h> fgets() calls.
- It might be wise to put better word wrap facilities here
- */
- char szLine[MAXLINELEN];
-
- /* Put up the hourglass */
- WinSetPointer(HWND_DESKTOP, hptrWait);
-
- /* Reinitialize buffer, MaxLineLength */
- for (; sTopLine > 0; ) free(aszLines[--sTopLine]);
- sMaxLine = 0;
-
- /* Read in the file */
- while (fgets(szLine, MAXLINELEN, pfInput)) {
-
- /* Convert LF (\n) into NULL (\0) */
- if (szLine[strlen(szLine) - 1] == '\n') {
- szLine[strlen(szLine) - 1] = 0;
- } else szLine[MAXLINELEN - 1] = 0;
-
- if (StoreLine(szLine)) {
- fprintf(stderr,"***Error: Line buffer full\n");
- return;
- }
- }
- fclose(pfInput);
-
- /* Reset the mouse pointer */
- WinSetPointer(HWND_DESKTOP, hptrArrow);
-
- return;
- }
-
- SHORT StoreLine(char *szLine) {
- /*
- Put a line into the line buffer; line numbers are free
- For > 64K data, add code here and in RetrieveLine
- */
- int i, cLinePos;
- BOOL fDone;
- /*
- Check if top line exceeded, or malloc() fails
- */
- if (sTopLine == NUM_DATA_LINES) return -1;
- /*
- Compute line length with tabs expanded
- */
- cLinePos = 0;
- for (i = 0; i < MAXLINELEN; i++) {
- switch(szLine[i]) {
- case '\0':
- cLinePos++; i = MAXLINELEN;
- break;
- case '\t':
- do {
- cLinePos++;
- } while (cLinePos % 8);
- break;
-
- default:
- cLinePos++;
- }
-
- }
- if (cLinePos > sMaxLine) sMaxLine = cLinePos;
- if (!(aszLines[sTopLine] = malloc(cLinePos))) return -1;
- /*
- Copy szLine into the line buffer. Expand tabs here.
- */
- i = cLinePos = 0; fDone = FALSE;
- while ((i <= MAXLINELEN) && (!fDone)) {
- switch(szLine[i]) {
- case '\t':
- do {
- aszLines[sTopLine][cLinePos++] = ' ';
- } while (cLinePos % 8);
- break;
-
- default:
- aszLines[sTopLine][cLinePos++] = szLine[i];
- fDone = !szLine[i];
- break;
- }
- i++;
- }
- sTopLine++;
- return 0;
- }
-
- char * _loadds RetrieveLine(USHORT usLineNum) {
- /*
- Return line numbered usLineNum
- */
- if ((SHORT) usLineNum >= sTopLine) { /* Out of range */
- return NULL;
- }
- return aszLines[usLineNum];
- }
-
- MRESULT CALLBACK BrowseWndProc(hWnd, msg, mp1, mp2)
- HWND hWnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- /*
- Handle the About... and Open... messages
- */
- switch(msg) {
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
- case IDM_ABOUT:
- WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,
- (HMODULE) NULL, IDD_ABOUT, NULL);
- return 0;
-
- case IDM_OPEN:
- /*
- Open the file, using the file dialog
- then reopen it with stdio calls
- */
- SetupDLF(&dlfInput, DLG_OPENDLG, &hfInput,
- "\\*.*", NULL, "Browse Open File",
- "Select a file to be browsed.");
- DlgFile(hWnd, &dlfInput);
- pfInput = fopen(dlfInput.szOpenFile, "r");
- ReadFile();
- /*
- Close the opened handle
- */
- DosClose(hfInput);
-
- /* Fix up the screen display */
- lbiData.sRows = sTopLine;
- lbiData.sCols = sMaxLine;
- lbiData.fLargeFont = fLargeFont;
- AvioInit(&lbiData);
-
- return 0;
-
- case IDM_FONT:
- AvioLargeFont(fLargeFont = !fLargeFont);
- return 0;
-
- default: return 0;
- }
- break;
- default: return WinDefWindowProc(hWnd, msg, mp1, mp2);
- }
- return 0L;
- }
-
- MRESULT CALLBACK AboutDlgProc(hDlg, msg, mp1, mp2)
- /*
- About... dialog procedure
- */
- HWND hDlg;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hDlg, TRUE); break;
- default: break;
- }
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
-
- BROWSE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\BROWSE\VBROWSE\BROWSE.C
-
- /*
- VIO File Browsing Application
- Created by Microsoft Corporation, 1989
- */
- #define INCL_KBD
- #define INCL_VIO
- #include <stdio.h>
- #include <stdlib.h>
- #include <os2.h>
- #include <string.h>
- #include "browse.h"
- /*
- Global Variables
- */
- FILE *pfInput;
- char *aszLines[NUM_DATA_LINES];
- SHORT sTopLine= -1;
- SHORT sRows;
- SHORT HorScrollPos=0;
- BYTE abBlank[2] = { 0x20, 0x07 };
-
- /*
- Macros for Vio calls
- The last parameter is zero because we're using a VIO PS
- */
- #define ClearScreen() VioScrollDn(0, 0, -1, -1, -1, abBlank, 0)
- #define Move(r,c) VioSetCurPos(r, c, 0)
- #define ScrollDown(n) VioScrollDn(0, 0, -1, -1, n, abBlank, 0)
- #define ScrollUp(n) VioScrollUp(0, 0, -1, -1, n, abBlank, 0)
- #define Write(s) VioWrtTTY(s, strlen(s), 0)
- /*
- Macros for bounds checking
- */
- #define Abs(x) (((x) > 0) ? (x) : (-(x)))
- #define Max(x, y) (((x) > (y)) ? (x) : (y))
- #define Min(x, y) (((x) < (y)) ? (x) : (y))
- #define LowerBound(pos, disp, lbound) Max(pos - disp, lbound)
- #define UpperBound(pos, disp, ubound) Min(pos + disp, ubound)
-
- /*
- Functions
- */
- int cdecl main(int argc, char *argv[]) {
- /*
- Open the input file and initialize globals
- */
- char *szFilename;
- VIOMODEINFO viomiMode;
-
- /*
- Open the Input File
- */
- if (argc == 1)
- pfInput = stdin;
- else {
- szFilename = argv[1];
- if (!(pfInput = fopen(szFilename,"r"))) {
- fprintf(stderr, "***Error: Could not open %s", szFilename);
- return(-1);
- }
- }
- /*
- Read it into the line buffer
- */
- if (ReadFile()) return(-1);
- /*
- Get the video parameters
- */
- viomiMode.cb = sizeof(viomiMode);
- VioGetMode(&viomiMode, 0);
- sRows = (SHORT) viomiMode.row;
-
- DisplayScreen(0, TRUE);
- ManipulateFile();
-
- return 0;
- }
-
- SHORT ReadFile(VOID) {
- /*
- Read lines from the file into the line buffer
- If there's an error, abort the program (return -1)
- */
- char szLine[MAXLINELENGTH];
-
- while (fgets(szLine, MAXLINELENGTH, pfInput)) {
-
- /* Convert LF (\n) character to NULL (\0) */
- if (szLine[strlen(szLine)-1] == '\n')
- szLine[strlen(szLine)-1] = 0;
- else {
- fprintf(stderr,"***Error: Incomplete line read\n");
- return(-1);
- }
-
- /* Put the line into the line buffer */
- if (StoreLine(szLine)) {
- fprintf(stderr,"***Error: Line buffer full\n");
- return(-1);
- }
- }
-
- /* Close the Input file */
- fclose(pfInput);
- return 0;
- }
-
- VOID ManipulateFile(VOID) {
- /*
- Main loop for display processing
- */
- CHAR ch;
- SHORT sLine = 0;
-
- /* The main command loop */
- while ((ch = GetKbdInput()) != ESC) {
- /*
- Take user input and compute new top line of screen
- by taking appropriate jump in jumptable.
-
- Note: no horizontal scrolling.
- */
- switch (ch) {
- case LINE_UP: sLine = LowerBound(sLine, 1, 0);
- case LINE_DOWN: sLine = UpperBound(sLine, 1, BOTTOM);
- case PAGE_UP: sLine = LowerBound(sLine, sRows, 0);
- case PAGE_DOWN: sLine = UpperBound(sLine, sRows, BOTTOM); bre
- case HOME_KEY: sLine = 0;
- case END_KEY: sLine = BOTTOM;
- default: break
- }
- DisplayScreen((USHORT) sLine, !ch);
- }
-
- /* Set Cursor to the bottom of the screen */
- Move((USHORT) sRows - 1, 0);
- }
-
- SHORT StoreLine(char *szLine) {
- /*
- Put a line into the line buffer; line numbers are free
- For > 64K data, add code here and in RetrieveLine
- */
- /*
- Check if top line exceeded, or if malloc() fails
- */
- if ((sTopLine == NUM_DATA_LINES) ||
- ((aszLines[++sTopLine] = malloc(strlen(szLine) + 1)) == NULL))
-
- return -1;
- /*
- Copy szLine into the line buffer
- */
- strcpy(aszLines[sTopLine], szLine);
- return 0;
- }
-
- SHORT RetrieveLine(char **pszLine , USHORT usLineNum) {
- /*
- Return line numbered usLineNum
- */
- if ((SHORT) usLineNum > sTopLine) return -1; /* Out of range */
- *pszLine = aszLines[usLineNum];
- return 0;
- }
-
- VOID DisplayScreen(USHORT usDisplayTop, BOOL fForceDraw) {
- /*
- Display lines on the screen, starting at usDisplayTop
- by scrolling, then painting new information
- */
- SHORT sDelta;
- static USHORT usOldDispTop;
-
- sDelta = usDisplayTop - usOldDispTop;
- /*
- If only a few lines need repainting...
- */
- if ((Abs(sDelta) < sRows) && !fForceDraw ) {
- /*
- Moving to a "higher line", so:
- Scroll down by the amount (make the difference positive)
- Paint in the lines at the top
- */
- if (sDelta < 0) {
- ScrollDown(-sDelta);
- Refresh(usDisplayTop, -sDelta, 0);
- } else {
- /*
- Moving to a "lower line", so:
- Scroll the information up, and paint at the bottom
- */
- ScrollUp(sDelta);
- Refresh(usDisplayTop + sRows - sDelta, sDelta, sRows - sDelta);
- }
- } else { /* Paint the entire screen */
- ClearScreen();
- Refresh(usDisplayTop, sRows, 0);
- }
- usOldDispTop = usDisplayTop;
- }
-
- VOID Refresh (USHORT iLine, USHORT usLines, USHORT usStart) {
- /*
- Updates usLines lines, starting at line iLine in the line
- buffer, and line usStart on the screen
- */
- USHORT usLine;
- char *szLine;
-
- for (usLine = 0; usLine < usLines; usLine++) {
- /*
- Read the line, set the cursor, print the line
- */
- if (RetrieveLine(&szLine, (iLine + usLine))) break;
- Move((usStart + usLine), 0);
- Write(szLine);
- }
- }
-
- CHAR GetKbdInput(VOID) {
- /*
- Get chars, then check scan codes and return our own values
- */
- KBDKEYINFO kbciKeyInfo;
-
- /*
- Wait for characters
- */
- KbdCharIn(&kbciKeyInfo, IO_WAIT, 0);
-
- switch (kbciKeyInfo.chScan) {
- case ESC: /* escape */
- case LINE_UP:
- case LINE_DOWN:
- case PAGE_UP:
- case PAGE_DOWN:
- case HOME_KEY:
- case END_KEY:
- return kbciKeyInfo.chScan; break;
- default:
- return((CHAR) NULL); break;
- }
- }
-
-
- CALC.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CALC\CALC.C
-
- /****************************** Module Header *******************************
- /*
- /* Module Name: calc.c - Calc application
- /*
- /* OS/2 Presentation Manager version of Calc, ported from Windows version
- /*
- /* Created by Microsoft Corporation, 1987
- /*
- /****************************************************************************
-
- #define INCL_WININPUT
- #define INCL_WINPOINTERS
- #define INCL_WINMENUS
- #define INCL_WINSYS
- #define INCL_WINCLIPBOARD
- #define INCL_GPIPRIMITIVES
- #define INCL_GPIBITMAPS
- #define INCL_GPILCIDS
- #define INCL_DEV
- #define INCL_ERRORS
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSNLS
- #include <os2.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include "calc.h"
-
- /****************************************************************************
- /*
- /* GLOBAL VARIABLES
- /*
- /****************************************************************************
-
- CHAR chLastKey, chCurrKey;
- CHAR szreg1[20], szreg2[20], szmem[20], szregx[20];
- CHAR szTitle[30], szErrorString[20], szPlusMinus[2];
- SHORT sCharWidth, sCharHeight;
- extern BOOL fError;
- BOOL fValueInMemory = FALSE;
- BOOL fMDown = FALSE; /* TRUE iff 'm' key depressed */
- UCHAR uchMScan = 0; /* scan code for 'm' key */
-
- #define TOLOWER(x) ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x))
- #define WIDTHCONST 28
- #define CXCHARS 37
- #define CYCHARS 13
-
- HAB hab;
- HDC hdcLocal; /* Local used for button bitmap */
- HPS hpsLocal;
- HDC hdcSqr; /* Sqr used for square-root bitmap */
- HPS hpsSqr;
- HBITMAP hbmLocal, hbmSqr;
- HMQ hmqCalc;
- HWND hwndCalc, hwndMenu;
- HWND hwndCalcFrame;
- HPS hpsCalc;
- HDC hdcCalc;
- HPOINTER hptrFinger;
-
- DEVOPENSTRUC dop = /* used by DevOpenDC */
- {
- NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL
- };
-
- static char achKeys[25] = /* keyboard keys */
- {
- '\271', '0', '.', '\261', '+', '=',
- '\272', '1', '2', '3', '-', 'c',
- '\273', '4', '5', '6', '*', '%',
- '\274', '7', '8', '9', '/', 'q',
- NULL
- };
-
- static CHAR achDKeys[25] = /* 4th key is plusminus */
- {
- ' ', '0', '.', '+', '+', '=',
- ' ', '1', '2', '3', '-', 'C',
- ' ', '4', '5', '6', '*', '%',
- ' ', '7', '8', '9', '/', ' ',
- NULL
- };
-
- /****************************************************************************
- /*
- /* PROCEDURE DECLARATIONS
- /*
- /****************************************************************************
-
- VOID FarStrcpy( PSZ, PSZ);
- MPARAM EXPENTRY AboutDlgProc( HWND, USHORT, MPARAM, MPARAM);
- BOOL CalcInit(VOID);
- VOID CalcPaint( HWND, HPS);
- VOID CalcTextOut( HPS, INT, INT, PCH, INT);
- MRESULT EXPENTRY CalcWndProc( HWND, USHORT, MPARAM, MPARAM);
- VOID cdecl main(VOID);
- VOID DataXCopy( VOID);
- VOID DataXPaste( VOID);
- VOID DrawNumbers( HPS);
- VOID Evaluate(BYTE);
- BOOL FlashSqr( HPS, PWPOINT);
- VOID FlipKey( HPS, INT, INT);
- VOID FrameKey( HPS, INT, INT);
- VOID InitCalc( VOID);
- BOOL InterpretChar( CHAR);
- VOID ProcessKey( PWPOINT);
- BOOL PSInit( VOID);
- CHAR Translate( PWPOINT);
- VOID UpdateDisplay( VOID);
-
-
- /****************************************************************************
- /****************************************************************************
- VOID CalcTextOut( hps, iX, iY, pch, iCount)
-
- HPS hps;
- INT iX, iY;
- PCH pch;
- INT iCount;
- {
- POINTL ptl;
-
- ptl.x = iX;
- ptl.y = iY;
-
- GpiSetColor( hps, CLR_BLACK);
- GpiCharStringAt( hps, (PPOINTL)&ptl, (LONG)iCount, (PSZ)pch);
- }
-
-
- /****************************************************************************
- /* Write the appropriate number or error string to the display area
- /* and mark memory-in-use if appropriate.
- /****************************************************************************
- VOID
- UpdateDisplay()
- {
- RECTL rcl;
-
- rcl.xLeft = (6 * sCharWidth);
- rcl.yBottom = 1050 * sCharHeight / 100;
- rcl.xRight = rcl.xLeft + (12 * sCharWidth);
- rcl.yTop = rcl.yBottom + (3 * sCharHeight) / 2;
-
- WinFillRect( hpsCalc, &rcl, CLR_WHITE); /* paint display area whi
- if( fError)
- WinDrawText( hpsCalc
- , -1
- , szErrorString
- , &rcl
- , CLR_BLACK
- , CLR_WHITE
- , DT_RIGHT | DT_VCENTER );
- else
- WinDrawText( hpsCalc
- , -1
- , szreg1
- , &rcl
- , CLR_BLACK
- , CLR_WHITE
- , DT_RIGHT | DT_VCENTER );
-
- if (fValueInMemory) /* little black square shows mem use
- {
- rcl.xLeft = (6 * sCharWidth);
- rcl.yBottom = 1050 * sCharHeight / 100;
- rcl.xRight = rcl.xLeft + (sCharWidth / 2);
- rcl.yTop = rcl.yBottom + (sCharHeight / 2);
- WinFillRect( hpsCalc, &rcl, CLR_BLACK);
- }
- }
-
-
- /****************************************************************************
- /* Display helpful info
- /****************************************************************************
- MPARAM EXPENTRY
- AboutDlgProc( hwnd, msg, mp1, mp2)
-
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- if (msg == WM_COMMAND)
- {
- WinDismissDlg(hwnd, TRUE);
- return(MPFROMSHORT(TRUE));
- }
- else return(WinDefDlgProc( hwnd, msg, mp1, mp2));
- }
-
-
- /****************************************************************************
- /* General initialization
- /****************************************************************************
- BOOL
- CalcInit()
- {
- hab = WinInitialize( NULL);
-
- hmqCalc = WinCreateMsgQueue( hab, 0);
- if( !hmqCalc)
- return(FALSE);
-
- WinLoadString( NULL, NULL, 1, 30, (PSZ)szTitle);
- WinLoadString( NULL, NULL, 2, 20, (PSZ)szErrorString);
- WinLoadString( NULL, NULL, 3, 2, (PSZ)szPlusMinus);
-
- if (!WinRegisterClass( hab, szTitle, CalcWndProc, CS_SIZEREDRAW, 0))
- return(FALSE);
-
- hptrFinger = WinLoadPointer( HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);
-
- InitCalc(); /* arithmetic initialization */
-
- return(TRUE);
- }
-
- /****************************************************************************
- /* main procedure
- /****************************************************************************
- VOID cdecl
- main()
- {
- QMSG qmsg;
- ULONG ulFCF;
-
- if (!CalcInit()) { /* general initialization *
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- goto exit;
- }
-
- if (!PSInit()) { /* presentation spaces & bitm
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- goto exit;
- }
-
- ulFCF = FCF_STANDARD & ~(LONG)(FCF_SIZEBORDER | FCF_MAXBUTTON);
- hwndCalcFrame = WinCreateStdWindow( HWND_DESKTOP
- , WS_VISIBLE | FS_BORDER
- , &ulFCF
- , szTitle
- , NULL
- , 0L
- , NULL
- , IDR_CALC
- , &hwndCalc);
-
- WinSetWindowPos( hwndCalcFrame
- , (HWND)NULL
- , 2
- , 2
- , CXCHARS * sCharWidth
- , CYCHARS * sCharHeight
- + (SHORT)WinQuerySysValue( HWND_DESKTOP
- , SV_CYTITLEBAR )
- + (SHORT)WinQuerySysValue( HWND_DESKTOP
- , SV_CYMENU )
- , SWP_MOVE | SWP_SIZE );
-
- while (WinGetMsg( hab, &qmsg, NULL, 0, 0))
- WinDispatchMsg( hab, &qmsg);
-
- exit: /* clean up */
- if (hdcSqr) /* square-root bitmap */
- {
- GpiDestroyPS( hpsSqr);
- if (hbmSqr)
- GpiDeleteBitmap( hbmSqr);
- }
-
- if (hdcLocal) /* keypad button */
- {
- GpiDestroyPS( hpsLocal);
- if (hbmLocal)
- GpiDeleteBitmap( hbmLocal);
- }
-
- WinDestroyWindow(hwndCalcFrame);
-
- WinDestroyMsgQueue(hmqCalc);
- WinTerminate(hab);
-
- DosExit(EXIT_PROCESS, 0); /* exit without error */
- }
-
-
- /****************************************************************************
- /* Calc Window Procedure
- /****************************************************************************
- MRESULT EXPENTRY
- CalcWndProc(hwnd, msg, mp1, mp2)
-
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- HPS hps;
- RECTL rclPaint;
- WPOINT wpt;
- BOOL fClip;
- USHORT usFmtInfo;
- RECTL rcl;
- SIZEL sizl;
-
- switch (msg)
- {
- case WM_CREATE:
- hdcCalc = WinOpenWindowDC( hwnd);
- WinQueryWindowRect( hwnd, &rcl);
- sizl.cx = rcl.xRight - rcl.xLeft;
- sizl.cy = rcl.yTop - rcl.yBottom;
- hpsCalc = GpiCreatePS( hab
- , hdcCalc
- , &sizl
- , GPIA_ASSOC | PU_PELS );
- break;
-
- case WM_DESTROY:
- WinDestroyPointer(hptrFinger);
- GpiDestroyPS( hpsSqr);
- GpiDeleteBitmap( hbmSqr);
- GpiDestroyPS( hpsLocal);
- GpiDeleteBitmap( hbmLocal);
- break;
-
- case WM_INITMENU:
- fClip = FALSE;
- if (WinOpenClipbrd( hab))
- {
- fClip = WinQueryClipbrdFmtInfo( hab, CF_TEXT, &usFmtInfo);
- WinCloseClipbrd( hab);
- }
- WinSendMsg((HWND)mp2, MM_SETITEMATTR,
- (MPARAM) MAKELONG(CMD_PASTE, TRUE),
- (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED))
- break;
-
- case WM_PAINT:
- hps = WinBeginPaint(hwnd, NULL, &rclPaint);
- CalcPaint( hwnd, hps); /* re-draw calculat
- WinEndPaint(hps);
- break;
-
- case WM_COMMAND:
- if (fError)
- break;
- switch(LOUSHORT(mp1))
- {
- case CMD_COPY:
- DataXCopy(); /* copy to clipboard */
- break;
- case CMD_PASTE:
- DataXPaste(); /* paste from clipboard */
- break;
- case CMD_EXIT:
- WinPostMsg( hwndCalcFrame, WM_QUIT, 0L, 0L);
- break;
- case CMD_ABOUT:
- WinDlgBox( HWND_DESKTOP
- , hwndCalcFrame
- , (PFNWP)AboutDlgProc
- , NULL
- , 1
- , (PSZ)NULL );
- break;
- }
- break;
-
- case WM_CLOSE:
- WinPostMsg(hwndCalcFrame, WM_QUIT, 0L, 0L);
- break;
-
- case WM_MOUSEMOVE:
- WinSetPointer( HWND_DESKTOP, hptrFinger);
- break;
-
- case WM_BUTTON1DOWN:
- wpt.x = LOUSHORT(mp1);
- wpt.y = HIUSHORT(mp1);
- ProcessKey( &wpt);
- goto dwp;
- break;
-
- case WM_CHAR:
- if (SHORT1FROMMP(mp1) & KC_KEYUP)
- {
- if (CHAR4FROMMP(mp1) == uchMScan)
- fMDown = FALSE; /* 'm' key went up */
- }
- else
- {
- if (SHORT1FROMMP(mp1) & KC_CHAR)
- {
- if (InterpretChar((UCHAR)SHORT1FROMMP(mp2)))
- {
- UpdateDisplay();
- }
- else
- {
- if (((UCHAR)SHORT1FROMMP(mp2)== 'm') || ((U
- {
- uchMScan = CHAR4FROMMP(mp1);
- fMDown = TRUE;
- }
- }
- }
- }
- break;
-
- case WM_ACTIVATE:
- if (HIUSHORT(mp1))
- WinSetFocus( HWND_DESKTOP, hwndCalc);
- break;
-
- case WM_SETFOCUS:
- if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);
- fMDown = FALSE; /* since we are losing foc
- break;
-
- dwp:
- default:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0L);
- }
-
-
- /****************************************************************************
- /* translate & interpret keys (ie. locate in logical keyboard)
- /****************************************************************************
- BOOL
- InterpretChar( ch)
-
- CHAR ch;
- {
- BOOL fDone;
- NPCH pchStep;
- INT i;
-
- fDone = FALSE;
- pchStep = achKeys;
- switch (ch)
- {
- case 'n':
- ch = szPlusMinus[0];
- break;
- case 27: /* xlate Escape into 'c' */
- ch = 'c';
- break;
- case '\r': /* xlate Enter into '=' */
- ch = '=';
- break;
- }
-
- if (fMDown) /* Do memory keys */
- {
- switch (ch)
- {
- case 'c':
- case 'C':
- ch = '\274';
- break;
- case 'r':
- case 'R':
- ch = '\273';
- break;
- case '+':
- ch = '\272';
- break;
- case '-':
- ch = '\271';
- break;
- }
- }
-
- while (!fDone && *pchStep)
- {
- if ((CHAR) *pchStep++ == ch)
- fDone = TRUE; /* char found in logical keyboard */
- }
- if (fDone)
- {
- chLastKey = chCurrKey;
- i = pchStep - achKeys - 1;
- FlipKey( hpsCalc, i/6, i%6);
- Evaluate( achKeys[i]);
- }
- return (fDone);
- }
-
-
- /****************************************************************************
- /* briefly reverse the shading on one of the keys
- /****************************************************************************
- VOID
- FlipKey( hps, iRow, iCol)
-
- HPS hps;
- INT iRow, iCol;
- {
- RECTL rcl;
-
- rcl.xLeft = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
- rcl.yBottom = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
- rcl.xRight = rcl.xLeft + (11 * sCharWidth / 3);
- rcl.yTop = rcl.yBottom + (7 * sCharHeight / 4);
- WinInvertRect( hps, &rcl);
- DosSleep( 50L);
- WinInvertRect( hps, &rcl);
- }
-
-
- /****************************************************************************
- /* compute whether a point is over a button and flash the button if so
- /****************************************************************************
- BOOL
- FlashSqr( hps, pwpt)
-
- HPS hps;
- PWPOINT pwpt;
- {
- INT iRow, iCol;
- BOOL fDone;
-
- /* find x range */
- fDone = FALSE;
- iCol = 0;
- iRow = 3;
- while (!fDone && iCol<6)
- {
- if (pwpt->x < (iCol * 6 * sCharWidth)
- + (14 * sCharWidth / 10)
- + (11*sCharWidth/3) )
- {
- if (pwpt->x > (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10))
- fDone = TRUE;
- else
- return FALSE;
- }
- else
- iCol++;
- }
- if (!fDone)
- return FALSE;
- fDone = FALSE;
- while (!fDone && iRow >= 0)
- {
- if (pwpt->y > ((165 * sCharHeight / 100) + (2 * iRow * sCharHeight)))
- {
- if (pwpt->y < (165 * sCharHeight / 100)
- + (2 * iRow * sCharHeight)
- + (7 * sCharHeight / 4) )
- fDone = TRUE;
- else
- return FALSE;
- }
- else
- iRow--;
- }
- if (!fDone)
- return FALSE;
- pwpt->x = iCol;
- pwpt->y = iRow;
- FlipKey( hps, iRow, iCol);
- return TRUE;
- }
-
-
- /****************************************************************************
- /* which key is point on?
- /****************************************************************************
- CHAR
- Translate( pwpt)
-
- PWPOINT pwpt;
- {
- return( achKeys[ pwpt->y * 6 + pwpt->x]);
- }
-
-
- /****************************************************************************
- /* invoke flashing, point-to-key translation, and result-display update
- /****************************************************************************
- VOID
- ProcessKey( pwpt)
-
- PWPOINT pwpt;
- {
- BOOL fFlashed;
-
- chLastKey = chCurrKey;
- fFlashed = FlashSqr( hpsCalc, pwpt);
-
- if (fFlashed)
- Evaluate( (BYTE)Translate( pwpt));
- UpdateDisplay();
- }
-
-
- /****************************************************************************
- /* draw a blank key
- /****************************************************************************
- VOID
- FrameKey(hps, iRow, iCol)
-
- HPS hps;
- INT iRow, iCol;
- {
- POINTL aptl[3];
-
- aptl[0].x = (iCol * 6 * sCharWidth) + (14 * sCharWidth / 10);
- aptl[0].y = (165 * sCharHeight / 100) + (2 * iRow * sCharHeight);
- aptl[1].x = (11 * sCharWidth / 3) + (aptl[0].x);
- aptl[1].y = (7 * sCharHeight / 4) + (aptl[0].y);
- aptl[2].x = 0;
- aptl[2].y = 0;
- GpiBitBlt( hps, hpsLocal, 3L, aptl, ROP_SRCCOPY, BBO_IGNORE);
- }
-
-
- /****************************************************************************
- /* draw the keys and fill in numbers
- /****************************************************************************
- VOID
- DrawNumbers(hps)
-
- HPS hps;
- {
- INT iRow, iCol;
-
- /* Draw the keys and fill in the numbers we can */
- for (iRow = 0; iRow < 4; iRow++)
- {
- for (iCol = 0; iCol < 6; iCol++)
- {
- FrameKey( hps, iRow, iCol);
- CalcTextOut( hps
- , (iCol * 6 * sCharWidth)
- + (WIDTHCONST * sCharWidth / 10)
- , (iRow + 1) * 2 * sCharHeight
- , (PSZ)(achDKeys + (iRow * 6) + iCol)
- , 1 );
- }
- }
- }
-
-
- /****************************************************************************
- /* redraw the whole calculator
- /****************************************************************************
- VOID
- CalcPaint( hwnd, hps)
-
- HWND hwnd;
- HPS hps;
- {
- RECTL rclDst;
- CHARBUNDLE cbnd;
- INT iX, iY;
-
- WinQueryWindowRect( hwnd, &rclDst);
- WinFillRect( hps, &rclDst, CLR_GREEN);
-
- DrawNumbers(hps);
- CalcTextOut(hps, iX = (11 * sCharWidth / 5) + 1, iY = 2 * sCharHeight,
- (PSZ)"M-", 2);
- CalcTextOut(hps, iX, iY + 2 * sCharHeight, (PSZ)"M+", 2);
- CalcTextOut(hps, iX, iY + 4 * sCharHeight, (PSZ)"MR", 2);
- CalcTextOut(hps, iX, iY + 6 * sCharHeight, (PSZ)"MC", 2);
-
- /* Draw the minus of the plus/minus button */
- cbnd.usBackMixMode = FM_LEAVEALONE;
- GpiSetAttrs( hps, PRIM_CHAR, CBB_BACK_MIX_MODE, 0L, &cbnd);
- iX = (3 * 6 * sCharWidth) + (WIDTHCONST * sCharWidth / 10);
- CalcTextOut( hps, iX, iY + sCharHeight / 4, (PSZ)"_", 1);
-
- /* Draw the square root bitmap */
- rclDst.xLeft = 160 * sCharWidth / 5;
- rclDst.yBottom = 31 * sCharHeight / 4;
- rclDst.xRight = rclDst.xLeft + 2 * sCharWidth;
- rclDst.yTop = rclDst.yBottom + (3 * sCharHeight / 2);
- WinDrawBitmap( hps
- , hbmSqr
- , NULL
- , (PPOINTL)&rclDst
- , CLR_WHITE
- , CLR_BLACK
- , DBM_STRETCH );
-
- UpdateDisplay();
- }
-
-
- /****************************************************************************
- /* initialize the bitmaps for a blank key and for the square-root sign
- /****************************************************************************
- BOOL
- PSInit()
- {
- HPS hps;
- FONTMETRICS fm;
- POINTL ptl;
- SIZEL sizl;
- BITMAPINFOHEADER bmp;
- POINTL aptl[4];
- LONG alCaps[2];
-
- /************************************************************************
- /* compute the units of horizontal and vertical distance based on
- /************************************************************************
- hps = WinGetPS( HWND_DESKTOP);
- GpiQueryFontMetrics( hps, (LONG)sizeof(FONTMETRICS), &fm);
- sCharHeight = (SHORT)(fm.lEmHeight); /* avg height of uppercase character
- sCharWidth = (SHORT)(fm.lEmInc); /* usually 'M' increment
- WinReleasePS( hps);
-
- /************************************************************************
- /* prepare the square root bitmap
- /************************************************************************
- hdcSqr = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
- if( !hdcSqr)
- return(FALSE);
-
- sizl.cx = sizl.cy = 0L;
- hpsSqr = GpiCreatePS( hab
- , hdcSqr
- , &sizl
- , PU_PELS | GPIT_MICRO | GPIA_ASSOC );
- hbmSqr = GpiLoadBitmap( hpsSqr, NULL, IDB_SQR, 0L, 0L);
-
- /************************************************************************
- /* prepare the bitmap of a blank key
- /************************************************************************
- hdcLocal = DevOpenDC( hab, OD_MEMORY, "*", 3L, (PDEVOPENDATA)&dop, NULL);
- if( !hdcLocal)
- return(FALSE);
-
- sizl.cx = sizl.cy = 0L;
- hpsLocal = GpiCreatePS( hab
- , hdcLocal
- , &sizl
- , PU_PELS | GPIT_MICRO | GPIA_ASSOC );
- bmp.cbFix = 12;
- bmp.cx = 11 * sCharWidth / 3;
- bmp.cy = sCharHeight * 2;
- DevQueryCaps( hdcLocal, CAPS_COLOR_PLANES, 2L, alCaps);
- bmp.cPlanes = (USHORT)alCaps[0];
- bmp.cBitCount = (USHORT)alCaps[1];
- hbmLocal = GpiCreateBitmap( hpsLocal, &bmp, 0L, NULL, NULL);
- if( !hbmLocal )
- return(FALSE);
- GpiSetBitmap( hpsLocal, hbmLocal);
-
- aptl[0].x = aptl[0].y = 0;
- aptl[1].x = 11 * sCharWidth / 3;
- aptl[1].y = 7 * sCharHeight / 4;
- aptl[2].x = aptl[2].y = 0;
- aptl[3].x = aptl[1].x;
- aptl[3].y = aptl[1].y;
- GpiSetColor( hpsLocal, CLR_GREEN); /* match the background to
- GpiBitBlt( hpsLocal, NULL, 2L, aptl, ROP_PATCOPY, BBO_IGNORE);
-
- /* Draw the rounded rect */
- ptl.x = 0;
- ptl.y = 0;
- GpiSetCurrentPosition( hpsLocal, &ptl);
- ptl.x = (11 * sCharWidth / 3) - 1;
- ptl.y = (7 * sCharHeight / 4) - 1;
- GpiSetColor( hpsLocal, CLR_WHITE); /* white interior
- GpiBox( hpsLocal
- , DRO_FILL
- , &ptl
- , (LONG)sCharWidth
- , (LONG)(sCharHeight / 2) );
- ptl.x = 0;
- ptl.y = 0;
- GpiSetCurrentPosition( hpsLocal, &ptl);
- ptl.x = (11 * sCharWidth / 3) - 1;
- ptl.y = (7 * sCharHeight / 4) - 1;
- GpiSetColor( hpsLocal, CLR_BLACK); /* black border
- GpiBox( hpsLocal
- , DRO_OUTLINE
- , &ptl
- , (LONG)sCharWidth
- , (LONG)(sCharHeight / 2) );
- return( TRUE);
- }
-
-
- CALCMATH.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CALC\CALCMATH.C
-
- /****************************** Module Header *******************************
- /*
- /* Module Name: calcmath.c - Calc application
- /*
- /* OS/2 Presentation Manager version of Calc, ported from Windows version
- /*
- /* Created by Microsoft Corporation, 1987
- /*
- /****************************************************************************
-
- #define INCL_WINCLIPBOARD
- #include <os2.h>
- #include <string.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <math.h>
-
- extern BOOL fValueInMemory;
- extern CHAR chLastKey;
- extern CHAR szreg1[20], szreg2[20], szmem[20];
- extern HWND hwndCalc;
- extern CHAR szregx[];
- extern HAB hab;
- BOOL fReadNumber;
- CHAR PendingOperation;
- BOOL fFirstOperand, fError;
- CHAR szresult[20];
- SEL sel;
-
- #define tolower(x) (((x) >= 'A') && ((x)<='Z')) ? (x) - 'A' + 'a' : (x)
- #define MAXINT (double)999999999
- #define MININT (double)-999999999
- #define ABS(x) (((x) >= (double)0) ? (x) : (-(x)))
-
-
- /****************************************************************************
- extern VOID UpdateDisplay( VOID);
- extern BOOL InterpretChar( CHAR);
-
- VOID AppendNumber( BYTE);
- VOID BinaryOperator( CHAR);
- VOID Clear( VOID);
- VOID DataXCopy( VOID);
- VOID DataXPaste( VOID);
- VOID Equilibrate( VOID);
- VOID Evaluate( BYTE);
- VOID FarStrcpy( PSZ, PSZ);
- NPCH ftoa( double);
- VOID InitCalc( VOID);
- VOID MClear( VOID);
- VOID MMinus( VOID);
- VOID MPlus( VOID);
- VOID Negate( VOID);
- VOID Number( CHAR);
- VOID Percent( VOID);
- VOID reverse( NPCH);
- VOID Simplify( VOID);
- VOID SquareRoot( VOID);
-
-
- /****************************************************************************
- VOID FarStrcpy( pszDest, pszSrc)
- PSZ pszDest, pszSrc;
- {
- while( *pszDest++ = *pszSrc++);
- }
-
- /****************************************************************************
- VOID
- reverse( s)
-
- NPCH s;
- {
- CHAR ch;
- register INT iHead, iTail;
-
- for (iHead = 0, iTail = strlen(s) - 1; iHead<iTail; iHead++, iTail-- ) {
- ch = s[iHead];
- s[iHead] = s[iTail];
- s[iTail] = ch;
- }
- }
-
- /****************************************************************************
- NPCH
- ftoa( dblNum)
-
- double dblNum;
- {
- sprintf( szresult, "%.8f", dblNum );
- return (szresult);
- }
-
-
- /****************************************************************************
- VOID
- Negate()
- {
- CHAR sztemp[ 20 ];
-
- if (szreg1[0] == '-')
- strcpy(szreg1, (&szreg1[1])); /* get rid of minus
- else if (szreg1[0] != '0' || (strlen(szreg1) > 2)) { /* can't negate zero
- sztemp[0] = '-';
- strcpy(&sztemp[1], szreg1);
- strcpy(szreg1, sztemp);
- }
- }
-
- /****************************************************************************
- VOID
- Number( ch)
-
- CHAR ch;
- {
- register INT iLen, iSize;
-
- iSize = 9;
- if (szreg1[0] == '-') iSize++;
- if (strchr(szreg1, '.')) iSize++;
- iLen = strlen(szreg1 );
- if (iLen == iSize) return;
- if (iLen == 1 && szreg1[0] == '0') iLen--;
- szreg1[ iLen ] = ch;
- szreg1[min(iLen + 1, 11)] = 0;
- }
-
- /****************************************************************************
- VOID
- AppendNumber ( b)
-
- BYTE b;
- {
- if (b == '.') { /* if no decimal, add one at en
- if (!strchr(szreg1, '.'))
- strcat(szreg1, ".");
- }
- else if ( b == 0xb1 )
- Negate();
- else
- Number(b);
- }
-
- /****************************************************************************
- VOID
- Equilibrate()
- {
- double dblResult;
- double dblX1, dblX2;
-
- if (chLastKey == '=') return;
- dblResult = (double)atof(szreg1);
- dblX1 = (double)atof(szreg1);
- dblX2 = (double)atof(szreg2);
-
- switch (PendingOperation) {
- case '+':
- if (dblX2>(double)0) { /* check for overflow */
- if (dblX1>(double)0) {
- if (dblX1 > (MAXINT - dblX2))
- fError = TRUE;
- }
- }
- else if (dblX2 < (double)0) {
- if (dblX1 < (double)0) {
- if ( dblX1 < (MININT - dblX2))
- fError = TRUE;
- }
- }
- if (!fError)
- dblResult = dblX2 + dblX1;
- break;
- case '-':
- if (dblX2 < (double)0) {
- if (dblX1 > (double)0) {
- if (dblX1 > (dblX2 - MININT))
- fError = TRUE;
- }
- }
- else if (dblX2 > (double)0) {
- if (dblX1 < (double)0) {
- if (dblX1 < (dblX2 - MAXINT))
- fError = TRUE;
- }
- }
- if (!fError)
- dblResult = dblX2 - dblX1;
- break;
- case '/':
- if (dblX1 == (double)0.0)
- fError = TRUE;
- else if (dblX2 > (double)0) {
- if (dblX1 > (double)0) {
- if (dblX1 < (dblX2 / MAXINT))
- fError = TRUE;
- }
- else { /* dblX1 < 0 here */
- if (dblX1 > (dblX2 / MININT))
- fError = TRUE;
- }
- }
- else { /* dblX2 < 0 here */
- if (dblX1 < (double)0) {
- if (dblX1 > (dblX2 / MAXINT))
- fError = TRUE;
- }
- else { /* dblX1 > 0 here */
- if (dblX1 < (dblX2 / MININT))
- fError = TRUE;
- }
- }
- if (!fError)
- dblResult = dblX2 / dblX1;
- break;
- case '*':
- if (dblX1 == (double)0) return;
- if (ABS(dblX2) > (double)1) {
- if (ABS(dblX1) > (double)1) {
- if (ABS(dblX1) > (MAXINT / ABS(dblX2)))
- fError = TRUE;
- }
- }
- if (!fError) dblResult = dblX2 * dblX1;
- break;
- }
- if (!fError) {
- strcpy(szreg1, ftoa((double)dblResult));
- strcpy( szreg2, szreg1 );
- }
- Simplify();
- }
-
- /****************************************************************************
- VOID
- SquareRoot()
- {
- double dblResult;
-
- dblResult = (double)atof(szreg1);
- if (dblResult < 0.0) {
- fError = TRUE;
- return;
- }
- if ((dblResult == 0.0) || ((chLastKey == 'q') && (dblResult == 1.0)))
- return;
- if ((dblResult < (double) 1.00000002) && (dblResult > (double) 1.0))
- dblResult = (double)1.0;
- else
- dblResult = sqrt(dblResult);
- strcpy( szreg1, ftoa((double)dblResult));
- if (atof( szreg1 ) == 0.0)
- strcpy(szreg1, "0.");
- Simplify();
- }
-
- /****************************************************************************
- VOID
- BinaryOperator( ch)
-
- CHAR ch;
- {
- if (fFirstOperand) {
- fFirstOperand = FALSE;
- strcpy(szreg2, szreg1);
- }
- else {
- Equilibrate();
- }
- PendingOperation = ch;
- }
-
- /****************************************************************************
- VOID
- Clear()
- {
- fReadNumber = FALSE;
- fFirstOperand = TRUE;
- strcpy(szreg1, "0.");
- if (fError || chLastKey == 'c'){
- strcpy(szreg2, "0.");
- PendingOperation = NULL;
- }
- fError = FALSE;
- }
-
- /****************************************************************************
- /* trash out trailing zeros, if a '.' is in the number
- /* and leading zeros in all cases.
- /****************************************************************************
- VOID
- Simplify()
- {
- register INT iLen, iCount;
- CHAR achLocal[20];
-
- iCount = 0;
- strcpy(achLocal, szreg1);
- if (atof(achLocal) != 0.0) {
- while (achLocal[iCount++] == '0');
- strcpy(szreg1, &achLocal[iCount-1] );
- }
- if (strchr(szreg1, '.')) {
- iLen = strlen(szreg1);
- while (szreg1[--iLen] == '0');
- szreg1[min( iLen + 1, 11)] = 0; /* null terminate */
- }
- }
-
-
- /****************************************************************************
- VOID
- DataXPaste()
- {
- PSZ psz;
- ULONG ulText;
- register CHAR ch;
-
- if (WinOpenClipbrd( hab))
- {
- ulText = WinQueryClipbrdData( hab, CF_TEXT);
- if (ulText)
- {
- psz = MAKEP( (SEL)ulText, 0);
- while (*psz)
- {
- ch = (CHAR) (tolower(*psz));
- if (ch == 'm')
- {
- psz++;
- switch (tolower(*psz))
- {
- case '-':
- ch = '\271';
- break;
- case '+':
- ch = '\272';
- break;
- case 'r':
- ch = '\273';
- break;
- case 'c':
- ch = '\274';
- break;
- default:
- ch = ' ';
- break;
- }
- }
- psz++;
- InterpretChar(ch);
- UpdateDisplay();
- }
- }
- }
- WinCloseClipbrd( hab);
- InterpretChar('=');
- UpdateDisplay();
- }
-
-
- /****************************************************************************
- VOID
- DataXCopy()
- {
- PSZ pszText;
-
- if (WinOpenClipbrd( hab))
- {
- WinEmptyClipbrd( hab);
- DosAllocSeg( 20, (SEL FAR *)&sel, SEG_GIVEABLE);
- if (sel == NULL) return;
- pszText = MAKEP(sel, 0);
- FarStrcpy( pszText, (PSZ)szreg1);
- WinSetClipbrdData( hab, (ULONG)sel, CF_TEXT, CFI_SELECTOR);
- WinCloseClipbrd( hab);
- }
- }
-
-
- /****************************************************************************
- VOID
- MPlus()
- {
- double dblX1, dblX2, dblResult;
-
- dblX2 = atof(szmem);
- dblX1 = atof(szreg1);
-
- if (dblX2>(double)0) { /* check for overflow */
- if (dblX1>(double)0) {
- if (dblX1 > (MAXINT - dblX2))
- fError = TRUE;
- }
- }
- else if (dblX2 < (double)0) {
- if (dblX1 < (double)0) {
- if ( dblX1 < (MININT - dblX2))
- fError = TRUE;
- }
- }
- if (!fError) {
- dblResult = dblX2 + dblX1;
- strcpy( szmem, ftoa((double)dblResult));
- }
- if (dblResult == (double)0.0)
- fValueInMemory = FALSE;
- else fValueInMemory = TRUE;
- }
-
- /****************************************************************************
- VOID
- MClear()
- {
- strcpy(szmem, "0.");
- fValueInMemory = FALSE;
- }
-
-
- /****************************************************************************
- VOID
- MMinus()
- {
- double dblX1, dblX2, dblResult;
-
- dblX2 = atof(szmem);
- dblX1 = atof(szreg1);
- if (dblX2 < (double)0) {
- if (dblX1 > (double)0) {
- if (dblX1 > (dblX2 - MININT))
- fError = TRUE;
- }
- }
- else if (dblX2 > (double)0) {
- if (dblX1 < (double)0) {
- if (dblX1 < (dblX2 - MAXINT))
- fError = TRUE;
- }
- }
- if (!fError) {
- dblResult = dblX2 - dblX1;
- strcpy( szmem, ftoa((double)dblResult));
- }
- if (dblResult == (double)0.0)
- fValueInMemory = FALSE;
- else fValueInMemory = TRUE;
- }
-
- /****************************************************************************
- VOID
- Evaluate( bCommand)
-
- BYTE bCommand;
- {
- switch( bCommand ) {
- case '0': case '1': case '2': case '3': case '4': case '5':
- case '6': case '7': case '8': case '9': case '.': case 0xb1:
- case 'n': /* n = 'negate' from keyboard */
- if ( fReadNumber )
- AppendNumber( bCommand );
- else {
- /* if starting a new number */
- if (bCommand != 0xb1)
- strcpy(szreg1, "0");
- AppendNumber( bCommand );
- }
- if (bCommand != 0xb1)
- fReadNumber = TRUE;
- break;
- case '+': case '-': case '/': case '*': case 'p':
- BinaryOperator(bCommand);
- fReadNumber = FALSE;
- break;
- case '=':
- fReadNumber = FALSE;
- Equilibrate();
- PendingOperation = NULL;
- break;
- case 'q':
- SquareRoot();
- fReadNumber = FALSE;
- break;
- case 0xBB: /* MR */
- strcpy(szreg1, szmem);
- fReadNumber = FALSE;
- Simplify();
- break;
- case 0xBA: /* M+ */
- MPlus();
- fReadNumber = FALSE;
- Simplify();
- break;
- case 0xB9: /* M- */
- MMinus();
- fReadNumber = FALSE;
- Simplify();
- break;
- case 0xBC:
- MClear(); /* MC */
- break;
- case '%':
- Percent();
- fReadNumber = FALSE;
- break;
- case 'c':
- Clear();
- break;
- }
- }
-
- /****************************************************************************
- VOID
- Percent()
- {
- double dblX1, dblX2, dblResult;
-
- dblX1 = atof(szreg1) / 100.0;
- dblX2 = atof(szreg2);
- if (ABS(dblX2) > (double)1) {
- if (ABS(dblX1) > (double)1) {
- if (dblX1 > (MAXINT / dblX2))
- fError = TRUE;
- }
- }
- if (!fError) {
- dblResult = dblX2 * dblX1;
- strcpy( szreg1, ftoa((double)dblResult));
- }
- Simplify();
- }
-
- /****************************************************************************
- VOID
- InitCalc()
- {
- fReadNumber = FALSE;
- fError = FALSE;
- fFirstOperand = TRUE;
- PendingOperation = 0;
- strcpy(szreg1, "0.");
- strcpy(szmem, "0.");
- }
-
-
- CASCADE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CASCADE\CASCADE.C
-
- #define INCL_PM
- #include <OS2.H>
- #include "Cascade.H"
-
- char szAppName[] = "Cascade";
- char szAppTitle[] = "Cascading Menu Example";
-
- HAB hAB;
- HMQ hmqMsgQueue;
- HWND hWndMain,
- hWndFrame;
-
- int cdecl main()
- {
- QMSG qmsg;
- ULONG ctlData = FCF_STANDARD & ~FCF_ACCELTABLE;
-
- hAB = WinInitialize (0);
-
- hmqMsgQueue = WinCreateMsgQueue (hAB, 0);
-
- if (!WinRegisterClass (hAB,
- szAppName,
- WndProc,
- CS_SYNCPAINT | CS_SIZEREDRAW,
- 0)) {
- return(0);
- }
-
- hWndFrame = WinCreateStdWindow ( HWND_DESKTOP,
- WS_VISIBLE,
- &ctlData,
- szAppName,
- NULL,
- 0L,
- 0,
- ID_RESOURCE,
- &hWndMain);
- WinSetWindowText (hWndFrame, szAppTitle);
- WinShowWindow (hWndFrame, TRUE);
-
- while ( WinGetMsg (hAB, &qmsg, NULL, 0, 0)) {
- WinDispatchMsg (hAB, &qmsg);
- }
-
- WinDestroyWindow (hWndFrame);
- WinDestroyMsgQueue (hmqMsgQueue);
- WinTerminate (hAB);
- }
-
- /*-------------------------------------------------------------------*/
- /* */
- /*-------------------------------------------------------------------*/
-
- BOOL CheckAll (HWND hMenu, int item, BOOL check);
- BOOL CheckAll (HWND hMenu, int item, BOOL check)
- {
- int mPos,max,test;
- MENUITEM mi;
- char szText[20];
- MPARAM mp1, mp2;
-
- max =(int) SHORT1FROMMR( WinSendMsg (hMenu, MM_QUERYITEMCOUNT, 0L, 0L) );
-
- for (mPos=0; mPos!=(int) max; mPos++) {
- test =(int) SHORT1FROMMR( WinSendMsg (hMenu, MM_ITEMIDFROMPOSITION, M
- WinSendMsg (hMenu, MM_QUERYITEMTEXT, MPFROM2SHORT(test,sizeof(szText)
- if (test == item) {
- mp1 = MPFROM2SHORT (test, TRUE);
- if (check)
- mp2 = MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED);
- else
- mp2 = MPFROM2SHORT(MIA_CHECKED, 0);
- WinPostMsg (hMenu, MM_SETITEMATTR, mp1, mp2);
- return TRUE;
- } else {
- WinSendMsg (hMenu, MM_QUERYITEM, MPFROM2SHORT(test,FALSE), (MPARA
- if (mi.hwndSubMenu) {
- if (CheckAll(mi.hwndSubMenu, item, check)) {
- mp1 = MPFROM2SHORT (test, TRUE);
- if (check)
- mp2 = MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED);
- else
- mp2 = MPFROM2SHORT(MIA_CHECKED, 0);
- WinPostMsg (hMenu, MM_SETITEMATTR, mp1, mp2);
- return TRUE;
- }
-
- }
- }
- }
- return FALSE;
- }
-
- /*-------------------------------------------------------------------*/
- /* */
- /*-------------------------------------------------------------------*/
-
-
- MRESULT EXPENTRY WndProc (hWnd, msg, mp1, mp2)
- HWND hWnd;
- USHORT msg;
- MPARAM mp1, mp2;
- {
- HPS hPS;
- HWND hMenu;
- static int prevFont = 0;
- int thisItem;
-
- switch (msg) {
-
- case WM_COMMAND:
- thisItem = SHORT1FROMMP(mp1);
- switch (thisItem) {
- case IDM_ABOUT:
- WinMessageBox (HWND_DESKTOP, hWnd,
- "Sample PM Application",
- szAppTitle, 1, MB_OK | MB_APPLMODAL | MB_MOVEABLE);
- break;
- default:
- if ((thisItem >= IDM_FIRSTFONT) && (thisItem<= IDM_LASTFO
- hMenu = WinWindowFromID (
- WinQueryWindow (hWnd, QW_PARENT, FALSE),
- FID_MENU);
- CheckAll (hMenu, prevFont, FALSE);
- CheckAll (hMenu, thisItem, TRUE);
- prevFont = thisItem;
- } else {
- DosBeep(600,60);
- }
- }
- break;
-
- case WM_CLOSE:
- WinPostMsg (hWnd, WM_QUIT, 0L, 0L);
- break;
-
- case WM_ERASEBACKGROUND:
- return ((MRESULT) TRUE);
- break;
-
- case WM_PAINT:
- hPS = WinBeginPaint (hWnd, NULL, (PWRECT)NULL);
- WinEndPaint (hPS);
- break;
-
- default:
- return (WinDefWindowProc (hWnd, msg, mp1, mp2));
- break;
- }
- return 0L;
- }
-
-
- CHASER.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CHASER\CHASER.C
-
- /* SWARM
- * Created by Microsoft Corp. 1986
- *
- * the idea behind this game is as follows:
- *
- * You have a collection of objects in the center of the playing field
- * that you are trying to protect (just one object in current version). You
- * control your own movements with the mouse. A number of "chasers" start
- * around the edges of the field and begin moving towards the objects
- * you want to protect. If you move the mouse on top of a chaser and click
- * the left button, the chaser will be killed and disappear from the screen
- * But as you close in on the chaser, it will detect your presence and try
- * to dodge you. Meanwhile the other chasers will continue to go after
- * your objects. If one of the chasers reaches an object, it will begin
- * dragging it away to the edge of the screen (currently the game just
- * ends when the single object is reached). When all objects are dragged
- * away, the game ends. If a chaser is killed while dragging an object, the
- * object is left where it is and must be protected in place - player canno
- * move objects. If you kill all the chasers, a new group of faster ones
- * will be spawned (currently the speed is constant). Your score is how
- * many chasers you can kill (no score currently kept), so there is no
- * advantage in sitting on the object for long periods.
- *
- * Swarm demonstrates several capabilities of OS/2 and the philosphy behind
- * them. This program is made of three components: Initialization, the
- * mouse driven thread and the attacker thread. The attacker thread is
- * launched as many times as there are attackers in a game. Launching
- * the attacker several times takes full advantage of the OS to schedule
- * resources. The programmer can think of the problem as only one attacker.
- * The system handles multiple instances of the thread.
- *
- * As the main loop launches threads it puts an ID code into the thread's
- * stack. The code is used to index into the universe data.
- *
- * A ram semaphore is used to control access to global data.
- *
- * This demonstration shows the use of the following OS/2 system calls:
- *
- * Tasking: VIO API: Mouse API:
- *
- * DosSemRequest() VioScrollUp() MouOpen()
- * DosSemClear() VioWrtCellStr() MouSetPtrPos()
- * DosCreateThread() VioSetCurType() MouReadEventQue()
- * DosExit() VioSetMode()
- * DosSleep()
- */
- #include <os2def.h>
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
- #include <bsedos.h>
- #define INCL_SUB
- #include <bsesub.h>
- #include <malloc.h>
- #undef NULL
- #include <stdio.h>
-
- #define STACKSIZE 200
-
- #define DANGERZONE 3
-
- #define LONGNAP 500L
- #define SHORTNAP 150L
-
- WAIT (-1L) /* Wait for ram Semaphore */
-
- CHASER 8 /* Number of chasers */
-
- SCREEN_HEIGHT 24 /* Default screen size */
- #define SCREEN_WIDTH 79
-
- GOAL univ[CHASER] /* Macros for constant stuff */
- #define ME univ[ID]
- #define MOUSE univ[CHASER+1]
-
- ALIVE 1 /* Flags for attackers/goal */
- #define DEAD 0
-
- char Chaser[2] = { 0xE8, 0x20 }; /* character and attribute */
- char Prize[2] = { 0x03, 0x2C }; /* for our various objects */
- char Blank[2] = { 0x20, 0x22 };
- char Blood[2] = { 0x20, 0x44 };
-
- struct { /* Universe structure and array */
- int row; /* univ[0] = chaser */
- int col; /* univ[n-1] = chaser */
- int state; /* univ[n] = GOAL */
- } univ[CHASER+1]; /* univ[n+1]= MOUSE */
-
- short ScreenHeight, /* Screen attributes */
- ScreenWidth;
-
- HMOU Mouse; /* place for mouse handle *
- ULONG Shortnap; /* Sleep times for chasers */
- ULONG Longnap;
- ULONG Semaphore = 0; /* Ram semaphore */
-
- struct _VIOCURSORINFO NewCur; /* struct for setting cursor typ
- struct _VIOCURSORINFO OldCur;
-
- struct _VIOMODEINFO modedata; /* Data saves for VIO mode */
- struct _VIOMODEINFO OldVioMode;
-
- /*
- * Define all procedures before main.
- */
- void Defender();
- void CleanUp();
- int InitGame();
- void chaserthread();
- int ParseCmdLine(int,char **);
-
- /*
- * main(ac,av)
- *
- * Top level procedure and MOUSE thread for the GAME demo.
- */
- int main(ac, av)
- int ac;
- char *av[];
- {
- /*
- * Parse the command line and perform some initialization.
- */
- if (ParseCmdLine(ac,av)) {
- printf("usage: %s [24|43] [F|M|S]\n",av[0]);
- DosExit(EXIT_THREAD,1);
- }
- if (InitGame()) /* Init game, exit if some problem */
- DosExit(EXIT_PROCESS,1);
-
- Defender(); /* Run mouse loop (defend against the swarm)
-
- CleanUp();
- }
-
- /*
- * Defender()
- *
- * This is the main loop of the mouse control thread.
- *
- * The semaphore is used to prevent the other threads from time slicing
- * while this routine is examining and/or modifying the universe. The
- * Semaphore is grabbed after the read of the Mouse queue so we don't tie
- * up the attackers while waiting for a mouse event.
- */
- void Defender()
- {
- USHORT ReadType = 1, /* Wait for mouse events */
- alive,
- i;
- struct _MOUEVENTINFO MouInfo; /* mouse event packet structure */
-
- alive = CHASER;
-
- do {
- MouReadEventQue( &MouInfo, &ReadType, Mouse); /* read where mouse is
-
- DosSemRequest( &Semaphore, WAIT);
-
- if( MouInfo.fs & 1) { /* If the mouse has moved
- MOUSE.row = MouInfo.row;
- MOUSE.col = MouInfo.col;
- }
- if( MouInfo.fs & 4 ) { /* if left button presse
- for (i = 0; i < CHASER; i++ ) {
- if( ( MOUSE.row == univ[i].row ) &&
- ( MOUSE.col == univ[i].col ) && /* see if we hit one */
- ( univ[i].state == ALIVE) ) {
- univ[i].state = DEAD;
-
- DosBeep(300,75); /* make a dying sou
- DosBeep(600,75);
- DosBeep(300,85);
-
- alive--; /* Decrease number alive */
- break; /* Can only kill one at a time
- }
- }
- }
- if( MouInfo.fs & 16 ) /* If right button pressed... */
- break; /* End game, clean up */
-
- DosSemClear(&Semaphore);
- }
- while (GOAL.state == ALIVE && alive); /* loop till all are dead */
- }
-
- /*
- * This thread manages the individual attackers. It is spun off as
- * many times as needed for a game.
- *
- * The interaction of the mouse cursor and the chaser character is sort
- * of funny, hence the funny code, below. The mouse cursor seems to
- * remember what was under it when it was written. Hence we cannot erase
- * the chaser if the mouse is "sitting" on it. If we do, then when the
- * mouse moves it will re-write the original object. This shows up as
- * phantom chasers.
- */
- void far chasethread(ID) /* code that controls each "chaser" */
- int ID;
- {
- short row, col; /* Our current position */
- short deltaX, deltaY; /* how far from the mouse are we? */
- short danger; /* flag to indicate not far enough! */
- short m; /* general purpose indexes */
-
-
- /* Print out the initial chaser character */
-
- VioWrtCellStr( Chaser, 2, ME.row, ME.col, 0 );
-
- /*
- * Keep running as long as the goal and myself haven't been killed.
- */
- for (;;) {
-
- row = ME.row; /* Grab the current position */
- col = ME.col;
- /*
- * If mouse is sitting upon the chaser, do nothing. Allow
- * the player some time to kill the chaser
- */
- if ((MOUSE.row == row) && (MOUSE.col == col)) {
- DosSleep( 1L );
- continue;
- }
- DosSemRequest(&Semaphore, WAIT);
- /*
- * If either the GOAL or Myself is dead, exit loop and clean up.
- * This wasn't tested in the for loop since we don't want to exit
- * if the MOUSE is sitting on the chaser.
- */
- if (ME.state != ALIVE || GOAL.state != ALIVE)
- break;
-
- deltaX = MOUSE.col - col; /* calculate how far we are */
- deltaY = MOUSE.row - row;
-
- if (((deltaX < -DANGERZONE) || (DANGERZONE < deltaX)) ||
- ((deltaY < -DANGERZONE) || (DANGERZONE < deltaY))) {
-
- danger = 0;
-
- if(GOAL.row < row) /* Creep towards the GOAL *
- row--;
- else if (GOAL.row > row)
- row++;
- if(GOAL.col < col)
- col--;
- else if(GOAL.col > col)
- col++;
- }
- else {
- danger = 1; /* Run away from the mouse */
-
- if ((MOUSE.row > row) && (row > 0))
- row--;
- else if ((MOUSE.row < row) && (row < ScreenHeight))
- row++;
- if ((MOUSE.col > col) && (col < ScreenWidth))
- col--;
- else if ((MOUSE.col < col) && (col > 0))
- col++;
- }
- /*
- * A quick and Dirty hack to prevent chasers from merging
- */
- for (m = 0; m < CHASER; m++ ) {
- if (univ[m].state == ALIVE &&
- univ[m].row == row &&
- univ[m].col == col &&
- m != ID) {
- row += 1;
- col += 3;
- }
- }
- /*
- * Zap the old chaser and print the new. Release the semaphore
- * after this, there can be no undesirable interactions now.
- */
- VioWrtCellStr( Blank, 2, ME.row, ME.col, 0 );
- VioWrtCellStr( Chaser, 2, row, col, 0 );
-
- DosSemClear(&Semaphore);
- /*
- * Update the current location
- */
- ME.row = row;
- ME.col = col;
- /*
- * See if we have reached the GOAL, if so eat it and exit
- */
- if ((row == GOAL.row) && (col == GOAL.col)) {
- VioWrtCellStr( Blank, 2, row, col, 0 );
- DosBeep(600,175);
- DosBeep(1200,175); /* if we reach the prize, let out a
- DosBeep(600,185); /* paint the screen red and end the
- DosBeep(1200,175);
- VioScrollUp( 0, 0, -1, -1, -1, Blood, 0 );
- GOAL.state = DEAD;
- }
- /*
- * Sleep an amount of time that varies depending
- * upon the danger level
- */
- if( danger )
- DosSleep(Shortnap);
- else
- DosSleep(Longnap);
-
- }
- /*
- * chaser is now dead or the game is over.
- * Erase its body and terminate the thread. Release the semaphore.
- */
- DosSemClear(&Semaphore);
-
- if (GOAL.state == ALIVE) {
- VioWrtCellStr(Blank, 2, ME.row, ME.col, 0 );
- }
- DosExit( EXIT_THREAD ,0);
- }
-
- /*
- * InitGame()
- *
- * Initialize the GOAL, MOUSE and the CHASERS, launch each chase thread.
- *
- * Returns an error if any internal processing errors
- */
- int InitGame()
- {
- struct _PTRLOC InitMouPos;
- void far chasethread(); /* code to control chasers */
- PBYTE Tstack; /* stack for new threads */
- unsigned chaseID;
- int i, rc;
- /*
- * Clear the screen.
- */
- VioScrollUp( 0, 0, -1, -1, -1, Blank, 0 );
- /*
- * Draw the prize
- */
- GOAL.row = ScreenHeight/2;
- GOAL.col = ScreenWidth /2;
- GOAL.state = ALIVE;
- VioWrtCellStr(Prize, 2, GOAL.row, GOAL.col, 0 );
- /*
- * Open the mouse pointer device and set it's location.
- */
- MouOpen( 0L, &Mouse );
- InitMouPos.row = GOAL.row;
- InitMouPos.col = GOAL.col;
- MouSetPtrPos( &InitMouPos, Mouse);
- MouDrawPtr(Mouse);
- /*
- * A simple minded initialization for the start of each chaser.
- * Some sort of random placement (based upon system time?) would
- * be nice.
- */
- univ[0].row = 0; univ[0].col = 0;
- univ[1].row = 0; univ[1].col = 25;
- univ[2].row = 0; univ[2].col = 55;
- univ[3].row = 0; univ[3].col = 79;
- univ[4].row = ScreenHeight; univ[4].col = 0;
- univ[5].row = ScreenHeight; univ[5].col = 25;
- univ[6].row = ScreenHeight; univ[6].col = 55;
- univ[7].row = ScreenHeight; univ[7].col = 79;
- /*
- * Grab the semaphore to prevent chaser from running until we are done.
- */
- DosSemRequest(&Semaphore, WAIT);
-
- for( i = 0; i < CHASER; i++ ) { /* for each of our threads
- univ[i].state = ALIVE; /* Set each one alive *
- Tstack = (PBYTE)malloc(sizeof(int) * STACKSIZE);
- if (Tstack == NULL ) { /* Create a stack */
- printf( "thread %d stack malloc failed\n", i );
- return(1);
- }
- Tstack += sizeof(int)*STACKSIZE; /* set stack pointer to correct end
- *--Tstack = HIBYTE(i);
- *--Tstack = LOBYTE(i); /* Push the ID on as a paramet
-
- rc = DosCreateThread(chasethread, &chaseID, Tstack);
- if(rc) {
- printf( "create of thread %d failed, error: %d\n", i, rc );
- return (1);
- }
- }
- DosSemClear(&Semaphore);
-
- return (0);
- }
-
- /*
- * CleanUp()
- *
- * Routine to reset the Video modes back to where they were.
- * (As best as possible).
- */
- void CleanUp()
- {
- char blank[2];
-
- DosSleep(1L); /* Yield the machine so attacker can clean up *
- VioSetMode( &OldVioMode, 0);
- /*
- blank[0] = ' ';
- blank[1] = OldVioMode.color;
- VioScrollUp( 0, 0, -1, -1, -1, blank, 0 );
- */
- VioSetCurType( &OldCur, 0);
- DosExit(EXIT_PROCESS,0); /* Exit and terminate all threads.
- }
-
- /*
- * ParseCmdLine(ac, av)
- *
- * Parses the command line arguments and sets up the game accordingly
- *
- */
- int ParseCmdLine(ac,av)
- int ac;
- char **av;
- {
- struct _VIOMODEINFO modedata;
- int VioMode;
-
- Longnap = LONGNAP;
- Shortnap = SHORTNAP;
- ScreenWidth = SCREEN_WIDTH;
- ScreenHeight = SCREEN_HEIGHT;
- VioMode = 25;
-
- while(--ac) {
- av++;
- switch(**av) {
- case 'f':
- case 'F':
- Longnap = LONGNAP / 2;
- Shortnap= SHORTNAP/ 2;
- break;
- case 'm':
- case 'M':
- Longnap = LONGNAP;
- Shortnap= SHORTNAP;
- break;
- case 's':
- case 'S':
- Longnap = LONGNAP * 2;
- Shortnap= SHORTNAP* 2;
- break;
- case '4': /* Assume 43 line mode was wanted */
- ScreenHeight = 42;
- ScreenWidth = 79;
- VioMode = 43;
- break;
- case '2':
- ScreenHeight = 24;
- ScreenWidth = 79;
- VioMode = 25;
- break;
- default:
- return(1);
- }
- }
-
- VioGetCurType(&OldCur, 0); /* Save old cursor */
-
- modedata.cb = sizeof(modedata); /* change mode as needed */
- VioGetMode( &modedata, 0);
- OldVioMode = modedata;
- modedata.row = VioMode;
- VioSetMode( &modedata, 0);
-
- NewCur.yStart = 0;
- NewCur.cEnd = 0;
- NewCur.cx = 1;
- NewCur.attr = -1;
-
- VioSetCurType( &NewCur, 0 ); /* make cursor go away */
-
- return (0);
- }
-
-
- CIRCLEQ.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\CIRCLEQ.C
-
- /*
- Circular Queue buffer implementation (which gets read by AVIO module)
- Created by Microsoft Corporation, 1989
- */
- #define INCL_DOSSEMAPHORES
- <os2.h> /* Need USHORT for global.h */
- <string.h> /* One strcpy call */
- #include "global.h"
- #include "circleq.h"
-
- TIMEOUT 1000L /* A second */
-
- LineInfo aliRing[QUEUESIZE]; /* The Circular Queue...*/
- int iHead, iTail;
- BOOL fFirst; /* Are we just starting? */
- LONG lSemMyQueue; /* Queue lock */
-
- void LineCopy(Line, Line);
- void QueFill(void);
-
- #define QueLock() DosSemRequest(&lSemMyQueue, -1L)
- #define QueUnlock() DosSemClear(&lSemMyQueue)
-
- #define Fix(n) (((n) >= 0) ? (n) : ((n) + QUEUESIZE))
- #define Circle(x) ((x) % QUEUESIZE)
- #define Incr(x) (x = Circle(x + 1))
- #define Decr(x) (x = (x > 0) ? (x - 1) : (QUEUESIZE - 1))
-
- void QueFill(void) {
- int i, j;
-
- for (i = 0; i < 25; i++) {
- aliRing[i].cch = MAXLINELEN;
- for (j = 0; j < MAXLINELEN; j++)
- aliRing[i].szText[j] = (char) (((i * j) % 10) + '0');
- }
- iHead = 0; iTail = 24;
- }
-
- void QueInit(void) {
- int i;
-
- fFirst = TRUE;
- QueLock();
- iHead = 0; iTail = 0;
- for (i = 0; i < QUEUESIZE; i++) aliRing[i].cch = 0;
- QueUnlock();
- }
-
- void QueAdvance(int n) {
- QueLock();
- iHead = Circle(iHead + n);
- QueUnlock();
- }
-
- Line QueQuery(int LineNum) { return &aliRing[Circle(iHead + LineNum)]; }
-
- BOOL QueInsertLine(Line pli) {
- /*
- Return FALSE if we try to overwrite the head
- */
- QueLock();
- /*
- Initialize the queue
- */
- if (fFirst) fFirst = FALSE;
- /*
- Increment TAIL, act if queue full
- Overwrite if last entry was incomplete
- */
- else if (aliRing[iTail].fComplete && (Incr(iTail) == iHead)) {
- /*
- We are overflowing...
- */
- Decr(iTail);
- QueUnlock();
- return FALSE;
- }
- /*
- Insert the element
- */
- LineCopy(pli, &aliRing[iTail]);
- QueUnlock();
- return TRUE;
- }
-
- BOOL QueCompleteLine(void) { return aliRing[iTail].fComplete; }
-
- void LineCopy(Line pliSrc, Line pliDst) {
- int i;
-
- pliDst->fDrawn = pliSrc->fDrawn;
- pliDst->fComplete = pliSrc->fComplete;
- pliDst->cch = pliSrc->cch;
- for (i = 0; i < (int) pliSrc->cch; i++) pliDst->szText[i] = pliSrc->szTex
- }
-
- int QueUpdateHead(int nRows, BOOL bPage, BOOL bPaging) {
- int i, nLines;
-
- nLines = Fix(Circle(iTail - iHead));
- nLines = (nLines >= nRows) ? (nLines - nRows + 1) : 0;
- if ((nLines = Min(nLines, nRows)) > 0) {
- if (bPage) {
- if (nLines < nRows) {
- QueLock();
- for (i = nLines; i < nRows; i++)
- aliRing[Circle(iHead + nRows + i)].cch = 0;
- QueUnlock();
- }
- nLines = nRows;
- }
- else if (bPaging) nLines = 0;
- QueLock();
- iHead = Circle(iHead + nLines);
- QueUnlock();
- }
- return nLines;
- }
-
- Line QueLastLine(void) {
- QueLock();
- aliRing[iTail].szText[aliRing[iTail].cch] = '\0';
- QueUnlock();
- return &aliRing[iTail];
- }
-
- int QuePageUp(int nRows) {
- int i, nLines;
-
- QueLock();
- nLines = Min((QUEUESIZE - 1) - Fix(Circle(iTail - iHead)), nRows);
- if (nLines) {
- iHead = Fix(Circle(iHead - nLines));
- for (i = 0; i < nLines; i++)
- aliRing[Circle(iHead + nRows + i)].fDrawn = FALSE;
- }
- QueUnlock();
- return nLines;
- }
-
-
- CLIPFILE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CLIPVIEW\CLIPFILE.C
-
- /*
- * CLIPFILE.C -- File handling for ClipView
- * Created by Microsoft Corporation, 1989
- *
- * This file contains one routine: SaveClipboard(), which uses
- * the OPENDLG library to put up a File...Save... dialog box.
- *
- * After getting a file name, it tries to save the current rendered format.
- */
- #define INCL_BITMAPFILEFORMAT
- #define INCL_DOSFILEMGR
- #define INCL_DOSMEMMGR
- #define INCL_GPIBITMAPS
- #define INCL_GPIMETAFILES
- #define INCL_WINCLIPBOARD
- #define INCL_WINERRORS
- #include <os2.h>
- #include <opendlg.h>
- #include <string.h>
- #include "clipview.h"
- /*
- * Globals
- */
- extern HAB vhab; /* Anchor block
- extern HWND vhwndClient; /* Main client area */
- /*
- Macros
- */
- #define CHK(f) fSuccess = fSuccess && (f)
- #define LOADSTRING(id, sz) WinLoadString(vhab, (HMODULE) NULL, id, MAXLEN, sz
- /*
- Private function prototypes
- */
- BOOL SaveText(HFILE hf, PSZ pszText);
-
- BOOL SaveClipboard(HWND hwnd, USHORT usFormat) {
- /*
- Save the clipboard contents in several formats.
- The "Save BITMAP" code is similar to that in the LINEFRAC sample.
- */
- BOOL fSuccess = TRUE; /* Did we succeed in saving? */
- ULONG hItem; /* Handle from QueryClipb
- /*
- Variables needed for File...Save... dialog.
- */
- DLF dlf; /* Dialog file */
- HFILE hf; /* Handle to output file */
- UCHAR szExt[8]; /* Default extension */
- UCHAR szInst[MAXLEN]; /* Instructions */
- UCHAR szMessage[MAXLEN]; /* Various messages */
- UCHAR szTitle[MAXTITLELEN];/* Application title */
- /*
- Variables needed for saving Metafiles
- */
- HMF hmfCopy; /* Clipboard metafile copy */
- /*
- Variables needed for saving BITMAPs
- */
- BITMAPINFOHEADER bmp; /* Header to be queried */
- HDC hdcMemory; /* Memory DC for the BITMAP */
- HPS hpsMemory; /* ...and it's associated PS */
- PBITMAPFILEHEADER pbfh; /* bmp + color table */
- POINTL ptlOrigin; /* Bitmap origin */
- SEL selBuffer; /* Selector to actual BITMAP */
- SEL selHeader; /* Selector for the BMP header */
- SIZEL sizl; /* Used in PS creation */
- ULONG cbBuffer; /* No. of bytes in buffer */
- USHORT cbExtra; /* No. of bytes in "final" segment
- USHORT cbHeader; /* No. of bytes in header */
- USHORT cbWrite1; /* No. of bytes to be written... *
- USHORT cbWrite2; /* ...in the two-part sel writes *
- USHORT cbWritten; /* No. of bytes actually written
- USHORT cSegs; /* No. of segments to write *
- USHORT i; /* Which segment is being written
- USHORT usHugeShift;
- /*
- Open the clipboard
- */
- if (!WinOpenClipbrd(vhab))
- return FALSE;
- /*
- Get the clipboard data
- */
- if (hItem = WinQueryClipbrdData(vhab, usFormat)) {
- /*
- Put up the Save... file dialog with the appropriate extensions
- */
- switch (usFormat) {
- case CF_TEXT:
- case CF_DSPTEXT: strcpy(szExt, "\\*.TXT"); break;
-
- case CF_BITMAP:
- case CF_DSPBITMAP: strcpy(szExt, "\\*.BMP"); break;
-
- case CF_METAFILE:
- case CF_DSPMETAFILE: strcpy(szExt, "\\*.MET"); break;
-
- default: strcpy(szExt, "\\*.*"); break;
- }
- /*
- Put the string "Saving Format: <format>" in the Save dialog box
- */
- GetFormatName(usFormat, szMessage);
- LOADSTRING(IDS_SAVETITLE, szTitle);
- strcat(szTitle, szMessage);
-
- LOADSTRING(IDS_APPNAME, szMessage);
- LOADSTRING(IDS_INST, szInst);
-
- SetupDLF(&dlf, DLG_SAVEDLG, &hf,
- (PSZ) szExt, (PSZ) szMessage, (PSZ) szTitle, (PSZ) szInst);
-
- dlf.szFileName[0] = dlf.szOpenFile[0] = '\0';
- /*
- Put up a Save file dialog, and respond appropriately to
- the return status.
- */
- switch (DlgFile(hwnd, &dlf)) {
- case TDF_ERRMEM:
- case TDF_INVALID:
- case TDF_NOSAVE:
- fSuccess = FALSE;
-
- /* fall through... */
- default:
- break;
- }
-
- if (fSuccess) {
- switch (usFormat) {
-
- case CF_TEXT:
- case CF_DSPTEXT:
- CHK(SaveText(hf, MAKEP((SEL) hItem, 0)));
- DosClose(hf);
- break;
-
- case CF_BITMAP:
- case CF_DSPBITMAP:
- /*
- Initialize the Memory DC and its PS
- */
- sizl.cx = sizl.cy = 0L;
- hdcMemory = DevOpenDC(vhab, OD_MEMORY, "*", 0L, NULL, NULL);
- hpsMemory = GpiCreatePS(vhab, hdcMemory, &sizl,
- GPIA_ASSOC | GPIT_MICRO | PU_PELS);
- /*
- Draw the BITMAP into the Memory DC
- */
- CHK(GpiSetBitmap(hpsMemory, (HBITMAP) hItem) != HBM_ERROR);
- ptlOrigin.x = ptlOrigin.y = 0L;
- CHK(WinDrawBitmap(hpsMemory, (HBITMAP) hItem, NULL,
- &ptlOrigin, CLR_BLACK, CLR_BACKGROUND, DBM_NORMAL)
- /*
- Get information about the BITMAP
- */
- CHK(GpiQueryBitmapParameters((HBITMAP) hItem, &bmp) == GPI_OK
- /*
- Compute the size of the buffer, and allocate
- Make sure that > 64K BITMAPs are handled
- (this code is from LFFILE.C)
- */
- cbBuffer = ( ((((ULONG)bmp.cBitCount*(ULONG) bmp.cx)+31L)/32L
- * 4L * (ULONG) bmp.cy * (ULONG) bmp.cPlanes )
- cSegs = (USHORT) (cbBuffer >> 16);
- cbExtra = (USHORT) (cbBuffer & 0xFFFFL);
- CHK(!DosAllocHuge(cSegs, cbExtra, &selBuffer, 0, 0));
- CHK(!DosGetHugeShift(&usHugeShift));
- /*
- Compute the size of the BITMAPFILEHEADER + color table...
- ...then allocate it.
- */
- cbHeader = (USHORT) (sizeof(BITMAPFILEHEADER)
- + (sizeof(RGB) << bmp.cBitCount));
- CHK(!DosAllocSeg(cbHeader, &selHeader, SEG_NONSHARED));
- pbfh = MAKEP(selHeader, 0);
- /*
- Copy the BITMAP information from the BITMAPINFOHEADER
- */
- pbfh->bmp.cbFix = 12;
- pbfh->bmp.cx = bmp.cx;
- pbfh->bmp.cy = bmp.cy;
- pbfh->bmp.cPlanes = bmp.cPlanes;
- pbfh->bmp.cBitCount = bmp.cBitCount;
- /*
- Get the actual BITMAP bits
- */
- CHK(GpiQueryBitmapBits(hpsMemory, 0L, (LONG) bmp.cy,
- MAKEP(selBuffer, 0), (PBITMAPINFO) &(pbfh->bmp))
- != GPI_ALTERROR);
- /*
- Set up the file header
- */
- pbfh->usType = BFT_BMAP;
- pbfh->cbSize = cbHeader + cbBuffer;
- pbfh->xHotspot = bmp.cx / 2; /* Anywhere wi
- pbfh->yHotspot = bmp.cy / 2;
- pbfh->offBits = cbHeader;
- /*
- Blast the BITMAP to a file...
- */
- /*
- ...first, the header...
- */
- CHK(!DosWrite(hf, pbfh, cbHeader, &cbWritten));
- /*
- ...then, the possibly large BITMAP itself
- */
- for (i = 0; i <= cSegs; ++i) {
- if (i < cSegs) {
- /*
- If we a 64K segment, write it in two
- parts. This must be done because
- DosWrite() can only write 64K - 1
- characters at once.
- */
- cbWrite1 = cbWrite2 = 0x8000;
- } else {
- /*
- The last segment is always small enough
- to write entirely.
- */
- cbWrite1 = cbExtra; cbWrite2 = 0;
- }
-
- if (cbWrite1) {
- CHK(!DosWrite(hf,
- MAKEP((selBuffer + (i << usHugeShift)), 0),
- cbWrite1, &cbWritten));
- if (cbWrite2) {
- CHK(!DosWrite(hf,
- MAKEP((selBuffer + (i<<usHugeShift)),cbWrite1
- cbWrite2, &cbWritten));
- }
- }
- }
- /*
- Clean up
-
- Error codes are not checked here because the file has
- already been saved.
- */
- DosClose(hf);
- GpiSetBitmap(hpsMemory, NULL);
- GpiDestroyPS(hpsMemory);
- DevCloseDC(hdcMemory);
- break;
-
- case CF_METAFILE:
- case CF_DSPMETAFILE:
- /*
- Save metafile
-
- We close and delete the file, because GpiSaveMetaFile()
- only allows the user to create a new file.
-
- We copy the metafile because GpiSaveMetafile()
- removes the data from the application's memory.
- */
- DosClose(hf);
- CHK(!DosDelete(dlf.szFileName, 0L));
- CHK((hmfCopy = GpiCopyMetaFile((HMF) hItem)) != GPI_ERROR);
- CHK(GpiSaveMetaFile(hmfCopy, dlf.szFileName) != GPI_ERROR);
- break;
-
- default:
- /*
- It may be reasonable to add support for other formats
- here, by saving a bitmap of the current window contents.
-
- But for now, close the file and return an error message.
- */
- DosClose(hf);
- fSuccess = FALSE;
- break;
- }
- }
- } else
- fSuccess = FALSE; /* Couldn't query the clipboard format! */
- /*
- Clean up
- */
- WinCloseClipbrd(vhab);
- return fSuccess;
- }
-
- BOOL SaveText(HFILE hf, PSZ pszText) {
- /*
- Save text format
-
- Count the number of characters, then write them.
- */
- PSZ pszCounter; /* Temporary to count chars in sel */
- ULONG ulcch = 0; /* The number of characters */
- USHORT cbWritten; /* No. of bytes actually written */
-
- pszCounter = pszText;
- while (*pszCounter++) ulcch++;
-
- return(!DosWrite(hf, pszText, (USHORT) ulcch, &cbWritten));
- }
-
-
- CLIPVIEW.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CLIPVIEW\CLIPVIEW.C
-
- /*
- * CLIPVIEW.C -- Clipboard Viewing application
- * Created by Microsoft Corporation, 1989
- *
- * This program registers itself as the clipboard viewer, if no clipboard
- * viewer exists. Then, it intercepts WM_DRAWCLIPBOARD messages.
- *
- * This file contains the routines which handle the client/frame windows,
- * the dialog routines, and the clipboard rendering code.
- */
- #define INCL_GPIBITMAPS
- #define INCL_GPIMETAFILES
- #define INCL_WINATOM
- #define INCL_WINCLIPBOARD
- #define INCL_WINFRAMEMGR
- #define INCL_WINLISTBOXES
- #define INCL_WINMENUS
- #define INCL_WINMLE
- #define INCL_WINSCROLLBARS
- #define INCL_WINSYS
- #define INCL_WINWINDOWMGR
- #include <os2.h>
- #include <string.h>
- #include "clipview.h"
- /*
- * Globals
- */
- BITMAPINFOHEADER vbmp; // Dimensions of current BITMAP
- BOOL vfUpdate = FALSE; // Are we updating the clipboard?
- BOOL vfViewBitmap = FALSE; // Are we currently viewing a
- HAB vhab; // Anchor block
- HDC vhdcMemory; // A memory DC for BitBlt-ing i
- HDC vhdcWindow = NULL; // Client window DC
- HMQ vhmqClip; // Message queue
- HPS vhpsMemory; // A PS associated with vhdcMem
- HWND vhwndClient; // Main client area
- HWND vhwndClipFrame = NULL; // Main frame window
- HWND vhwndHSB = NULL; // Horizontal scroll bar
- HWND vhwndMLE = NULL; // Handle to the MLE
- HWND vhwndTitlebar = NULL; // Title-bar handle
- HWND vhwndVSB = NULL; // Vertical scroll bar
- SHORT vcMaxHSB; // Maximum scroll range for HSB
- SHORT vcMaxVSB; // ...and for the VSB
- SHORT vcUpdate = -1; // Counter for scroll bar u
- USHORT vausFormats[MAXFORMATS]; // All available formats
- USHORT vcFmts; // How many formats?
- USHORT vusFormat; // What is the current format
- USHORT vfsFmtInfo; // Clipboard Format Informat
- /*
- Macros
- */
- #define LOADSTRING(id, sz) WinLoadString(vhab, (HMODULE) NULL, id, MAXLEN, sz
- #define MESSAGE(sz) WinMessageBox(HWND_DESKTOP, vhwndClient, sz, NULL, 0, \
- MB_OK | MB_ICONASTERISK | MB_SYSTEMMODAL);
- /*
- * Main routine...initializes window and message queue
- */
- int cdecl main( ) {
- QMSG qmsg; /* Message queue */
- ULONG ctldata; /* FCF_ flags */
- BOOL fViewer; /* Does a viewer already exist? */
- UCHAR szAlready[MAXLEN]; /* Already extant... message */
- UCHAR szClassName[MAXLEN]; /* New class name */
- /*
- Start up our PM application
- */
- vhab = WinInitialize(0);
- vhmqClip = WinCreateMsgQueue(vhab, 0);
- /*
- We create the client window first to try to avoid
- synchronization problems.
- */
- LOADSTRING(IDS_CLIPCLASS, szClassName);
- if (!WinRegisterClass( vhab, (PCH)szClassName, (PFNWP)ClipWndProc,
- CS_SIZEREDRAW, 0))
- return( 0 );
- /*
- Create the window (hidden)
- */
- ctldata = (FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCROLL)
- & ~(FCF_ACCELTABLE);
-
- vhwndClipFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE, &ctldata,
- szClassName, "",
- WS_VISIBLE, (HMODULE) NULL, ID_RESOU
- (PHWND) &vhwndClient );
- /*
- If there is no other clipboard viewer...
- */
- if (fViewer = !WinQueryClipbrdViewer(vhab, FALSE)) {
- /*
- ...we'll be the viewer. Show the clipboard window.
- */
- WinSetClipbrdViewer(vhab, vhwndClient);
- /*
- Poll messages from event queue
- */
- while( WinGetMsg( vhab, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
- WinDispatchMsg( vhab, (PQMSG)&qmsg );
- /*
- Stop being the clipboard viewer.
- */
- if (vhwndMLE)
- WinDestroyWindow(vhwndMLE);
- WinSetClipbrdViewer(vhab, NULL);
- } else {
- /*
- ...otherwise, notify the user, then terminate.
- */
- LOADSTRING(IDS_ALREADY, szAlready);
- MESSAGE(szAlready);
- }
- /*
- Clean up
- */
- WinDestroyWindow( vhwndClipFrame );
- WinDestroyMsgQueue( vhmqClip );
- WinTerminate( vhab );
-
- return !fViewer;
- }
-
- MRESULT CALLBACK ClipWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2) {
- /*
-
- * This routine processes WM_COMMAND, WM_CREATE, WM_DRAWCLIPBOARD, WM_PAINT.
- * Everything else is passed to the Default Window Procedure.
- */
- HPS hpsWindow;
- RECTL rcl;
- SWP swp;
- SIZEL sizl;
- UCHAR szMessage[MAXLEN];
-
- switch (msg) {
-
- case WM_CREATE:
- /*
- Create a memory DC/PS to BitBlt BITMAPs around.
- */
- sizl.cx = sizl.cy = 0L;
- vhdcMemory = DevOpenDC(vhab, OD_MEMORY, "*", 0L, NULL, NULL);
- vhpsMemory = GpiCreatePS(vhab, vhdcMemory, &sizl,
- GPIA_ASSOC | GPIF_DEFAULT | GPIT_MICRO | PU_PELS);
- break;
-
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
- /*
- About... dialog box
- */
- case IDM_ABOUT:
- WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc,
- (HMODULE) NULL, IDD_ABOUT, NULL);
- return 0;
- /*
- Render... dialog box
- */
- case IDM_RENDER:
- WinDlgBox(HWND_DESKTOP, hwnd, RenderDlgProc,
- (HMODULE) NULL, IDD_RENDER, NULL);
- return 0;
- /*
- Save... dialog box
- */
- case IDM_SAVE:
- if (!SaveClipboard(hwnd, vusFormat)) {
- LOADSTRING(IDS_NOTSAVED, szMessage);
- MESSAGE(szMessage);
- }
- return 0;
-
- default: break;
- }
- break;
-
- case WM_ERASEBACKGROUND:
- return (MRESULT) TRUE;
- break;
-
- case WM_PAINT:
- /* Open the presentation space */
- hpsWindow = WinBeginPaint(hwnd, NULL, &rcl);
-
- /* Fill in the background */
- WinFillRect(hpsWindow, &rcl, CLR_BACKGROUND);
-
- /* Paint in the clipboard */
- UpdateScreen(hwnd, vusFormat);
-
- /* Finish painting */
- WinEndPaint(hpsWindow);
- break;
-
- case WM_DRAWCLIPBOARD:
- /* Update the clipboard contents */
- GetAllFormats();
- vfUpdate = TRUE;
- WinPostMsg(hwnd, WM_PAINT, 0L, 0L);
- break;
-
- case WM_HSCROLL:
- if (vfViewBitmap) {
- /*
- Handle the appropriate scrolling messages
- */
- DoScrolling(hwnd, TRUE, HIUSHORT(mp2));
- } else
- /*
- If an ownerdraw format, let the owner handle it.
- */
- SendOwnerMsg(WM_HSCROLLCLIPBOARD, (MPARAM) hwnd, mp2);
- break;
-
- case WM_VSCROLL:
- if (vfViewBitmap) {
- /*
- Handle the appropriate scrolling messages
- */
- DoScrolling(hwnd, FALSE, HIUSHORT(mp2));
- } else
- /*
- If an ownerdraw format, let the owner handle it.
- */
- SendOwnerMsg(WM_VSCROLLCLIPBOARD, (MPARAM) hwnd, mp2);
- break;
-
- case WM_SIZE:
- /*
- If the MLE is processing a text selector,
- tell it to resize itself. If we have
- owner-draw data, tell the clipboard owner.
- If we have a BITMAP, readjust the scroll
- bar ranges.
- */
- if (vhwndMLE) {
- WinQueryWindowPos(vhwndMLE, &swp);
- swp.cx = SHORT1FROMMP(mp2);
- swp.cy = SHORT2FROMMP(mp2);
- WinSetMultWindowPos(vhab, &swp, 1);
- } else if (vfViewBitmap) {
- WinQueryWindowPos(hwnd, &swp);
- if ((vcMaxHSB = vbmp.cx - swp.cx) < 0)
- vcMaxHSB = 0;
- if ((vcMaxVSB = vbmp.cy - swp.cy) < 0)
- vcMaxVSB = 0;
- WinSendMsg(vhwndHSB, SBM_SETSCROLLBAR,
- 0L, MPFROM2SHORT(0, vcMaxHSB));
- WinSendMsg(vhwndVSB, SBM_SETSCROLLBAR,
- MPFROMSHORT(vcMaxVSB),
- MPFROM2SHORT(0, vcMaxVSB));
- } else {
- rcl.xLeft = rcl.yBottom = 0L;
- rcl.xLeft = (LONG) SHORT1FROMMP(mp2) - 1;
- rcl.yTop = (LONG) SHORT2FROMMP(mp2) - 1;
- SendOwnerMsg(WM_SIZECLIPBOARD, (MPARAM) hwnd, &rcl);
- }
- break;
-
- default:
- return WinDefWindowProc(hwnd, msg, mp1, mp2);
- break;
- }
- return 0L;
- }
-
- MRESULT CALLBACK RenderDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM m
- {
- /*
- Render... dialog procedure
- */
- HWND hwndListbox; /* Listbox of possible formats */
- UCHAR szFmtName[MAXLEN]; /* Format name */
- UCHAR szMessage[MAXLEN];
- USHORT i;
- USHORT usFormat; /* Format to render */
- MRESULT mrItem; /* Which listbox item selected? */
-
- switch(msg) {
-
- case WM_INITDLG:
- /*
- Put all the possible formats into the listbox, and
- select the first item by default.
- */
- hwndListbox = WinWindowFromID(hwndDlg, IDL_RENDER);
- WinSendMsg(hwndListbox, LM_DELETEALL, 0L, 0L);
- for (i = 0; i < vcFmts; i++) {
- GetFormatName(vausFormats[i], szFmtName);
- WinSendMsg(hwndListbox, LM_INSERTITEM,
- MPFROMSHORT(LIT_END), MPFROMP((PVOID) szFmtName));
- }
- WinSendMsg(hwndListbox, LM_SELECTITEM, 0L, MPFROMSHORT(TRUE));
- break;
-
- case WM_CONTROL:
- /*
- If the user makes a selection, quit!
- */
- if ((SHORT1FROMMP(mp1) == IDL_RENDER)
- && (SHORT2FROMMP(mp1) == LN_ENTER))
- WinPostMsg(hwndDlg, WM_COMMAND, MPFROMSHORT(DID_OK), 0L);
- break;
-
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK:
- /*
- Since the user chose a selection, try to render it.
- */
- hwndListbox = WinWindowFromID(hwndDlg, IDL_RENDER);
- mrItem = WinSendMsg(hwndListbox, LM_QUERYSELECTION, 0L, 0
- if (mrItem != (MRESULT) LIT_NONE) {
- usFormat = vausFormats[SHORT1FROMMR(mrItem)];
- if (usFormat != vusFormat) {
- /*
- If the clipboard format is not rendered,
- tell the user.
- */
- vfUpdate = TRUE;
- if (!UpdateScreen(vhwndClient, usFormat)) {
- LOADSTRING(IDS_NODISPLAY, szMessage);
- MESSAGE(szMessage);
- }
- }
- }
-
- /* fall through */
-
- case DID_CANCEL:
- WinDismissDlg(hwndDlg, TRUE);
-
- default: break;
- }
- default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
- MRESULT CALLBACK AboutDlgProc(HWND hwndDlg, USHORT msg, MPARAM mp1, MPARAM mp
- {
- /*
- About... dialog procedure
- */
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hwndDlg, TRUE);
- default: break;
- }
- default: return WinDefDlgProc(hwndDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
- VOID ReadSelector(HWND hwndMLE, PSZ pszText) {
- /*
- Compute the length of the text selector, in bytes.
- Allocate space, and copy the text selector into an MLE.
- */
- IPT ipt;
- ULONG ulcch = 0;
- PSZ pszCounter;
-
- pszCounter = pszText;
- while (*pszCounter++) ulcch++;
- WinSendMsg(hwndMLE, MLM_FORMAT, MPFROMSHORT(MLFIE_CFTEXT), 0L);
- WinSendMsg(hwndMLE, MLM_SETIMPORTEXPORT, pszText, (MPARAM) ulcch);
- WinSendMsg(hwndMLE, MLM_IMPORT, &ipt, (MPARAM) ulcch);
- }
-
- VOID FixFrame(VOID) {
- /*
- This routine tells the frame to update the scroll bars.
-
- First, make it so that the scroll bars cannot update themselves.
- Let the frame update the controls. Then, re-enable the scroll bars.
- */
- if (!(vcUpdate--)) {
- WinEnableWindowUpdate(vhwndHSB, FALSE);
- WinEnableWindowUpdate(vhwndVSB, FALSE);
- }
-
- WinSendMsg(vhwndClipFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_HORZSCROLL), 0L
- WinSendMsg(vhwndClipFrame, WM_UPDATEFRAME, MPFROMLONG(FCF_VERTSCROLL), 0L
-
- if (!(++vcUpdate)) {
- WinEnableWindowUpdate(vhwndHSB, TRUE);
- WinEnableWindowUpdate(vhwndVSB, TRUE);
- }
- }
-
- VOID NeedScrollBars(BOOL fNeed) {
- /*
- This routine hides changes the scroll bar state to correspond with
- fNeed, showing or hiding them as necessary.
- */
- static BOOL fNeeded = TRUE; /* The last scroll bar state *
-
- /*
- Get the scroll bar handles, if we haven't already.
- */
- if (!vhwndHSB) {
- vhwndHSB = WinWindowFromID(vhwndClipFrame, FID_HORZSCROLL);
- vhwndVSB = WinWindowFromID(vhwndClipFrame, FID_VERTSCROLL);
- }
- /*
- Case 1: We need scroll bars, so enable them.
- */
- if (fNeed) {
- if (!fNeeded) {
- WinSetParent(vhwndHSB, vhwndClipFrame, TRUE);
- WinSetParent(vhwndVSB, vhwndClipFrame, TRUE);
- FixFrame();
- }
- /*
- Case 2: We don't need scroll bars, so hide them.
- */
- } else {
- if (fNeeded) {
- WinSetParent(vhwndHSB, HWND_OBJECT, TRUE);
- WinSetParent(vhwndVSB, HWND_OBJECT, TRUE);
- FixFrame();
- }
- }
- /*
- Save state for next invocation
- */
- fNeeded = fNeed;
- }
-
- /*
- RenderFormat()
-
- Input: Clipboard format to render, and handle to client ar
- Side effects: Renders the image in the client area
- */
- BOOL RenderFormat(HWND hwnd, USHORT usFormat) {
- BOOL fRendered = TRUE;
- HMF hmfCopy;
- HPS hpsWindow;
- LONG alOptions[8];
- RECTL rclWindow;
- SIZEL sizl;
- SWP swpWindow;
- ULONG hItem;
- POINTL aptl[3];
- /*
- Open the clipboard
- */
- if (!WinOpenClipbrd(vhab))
- return FALSE;
- /*
- Open up the window DC and PS
- */
- if (!vhdcWindow)
- vhdcWindow = WinOpenWindowDC(hwnd);
-
- sizl.cx = sizl.cy = 0L;
- hpsWindow = GpiCreatePS(vhab, vhdcWindow, &sizl, GPIA_ASSOC | PU_ARBITRAR
- /*
- Enable the scroll bars, if necessary. This affects the size
- of the client area.
- */
- if (vfUpdate)
- NeedScrollBars( (vfViewBitmap =
- (usFormat == CF_BITMAP) || (usFormat == CF_DSPBITMAP)) );
-
- WinQueryWindowRect(hwnd, &rclWindow);
- /*
- Get the clipboard data
- */
- WinQueryClipbrdFmtInfo(vhab, usFormat, &vfsFmtInfo);
- if (!(hItem = WinQueryClipbrdData(vhab, usFormat))) {
- fRendered = FALSE;
- } else {
- /*
- Display the new format, as appropriate.
- */
- switch (usFormat) {
- case CF_TEXT:
- case CF_DSPTEXT:
- if (vfUpdate) {
- /*
- Create a new MLE and read the text into it.
- */
- vhwndMLE = WinCreateWindow(hwnd, WC_MLE, "",
- WS_VISIBLE | MLS_READONLY | MLS_HSCROLL | MLS_VSCROLL,
- 0, 0,
- (SHORT) rclWindow.xRight, (SHORT) rclWindow.yTop,
- hwnd, HWND_TOP, 0, NULL, NULL);
-
- ReadSelector(vhwndMLE, MAKEP((SEL) hItem, 0));
- }
- break;
-
- case CF_BITMAP:
- case CF_DSPBITMAP:
- if (vfUpdate) {
- /*
- Get the BITMAP dimensions, for scroll bar processing
- */
- if (GpiQueryBitmapParameters((HBITMAP) hItem, &vbmp)
- != GPI_OK) {
- return FALSE;
- }
- /*
- Set the scroll bar ranges from 0 to vbmp.max - client.max
- */
- WinQueryWindowPos(hwnd, &swpWindow);
-
- if ((vcMaxHSB = vbmp.cx - swpWindow.cx) < 0)
- vcMaxHSB = 0;
- if ((vcMaxVSB = vbmp.cy - swpWindow.cy) < 0)
- vcMaxVSB = 0;
- WinSendMsg(vhwndHSB, SBM_SETSCROLLBAR,
- 0L, MPFROM2SHORT(0, vcMaxHSB));
- WinSendMsg(vhwndVSB, SBM_SETSCROLLBAR,
- MPFROMSHORT(vcMaxVSB),
- MPFROM2SHORT(0, vcMaxVSB));
- }
- /*
- Draw the BITMAP, based on the scroll bar settings.
- */
- GpiSetBitmap(vhpsMemory, (HBITMAP) hItem);
-
- aptl[0].x = rclWindow.xLeft; /* Target bottom left */
- aptl[0].y = rclWindow.yBottom;
- aptl[1].x = rclWindow.xRight; /* Target top right */
- aptl[1].y = rclWindow.yTop;
- /* Source bottom left */
- aptl[2].x = (LONG) WinSendMsg(vhwndHSB, SBM_QUERYPOS, 0L, 0L);
- aptl[2].y = vcMaxVSB
- - (LONG) WinSendMsg(vhwndVSB, SBM_QUERYPOS, 0L, 0L);
-
- GpiBitBlt(hpsWindow, vhpsMemory, 3L, aptl, ROP_SRCCOPY, 0L);
- GpiSetBitmap(vhpsMemory, NULL);
- break;
-
- case CF_METAFILE:
- case CF_DSPMETAFILE:
- /*
- Set up the alOptions for displaying the metafile, and
- let the system do the rest of the work.
- */
- alOptions[PMF_SEGBASE] = 0L;
- alOptions[PMF_LOADTYPE] = LT_DEFAULT;
- alOptions[PMF_RESOLVE] = 0L;
- alOptions[PMF_LCIDS] = LC_LOADDISC;
- alOptions[PMF_RESET] = RES_DEFAULT;
- alOptions[PMF_SUPPRESS] = SUP_DEFAULT;
- alOptions[PMF_COLORTABLES] = CTAB_NOMODIFY;
- alOptions[PMF_COLORREALIZABLE] = CREA_DEFAULT;
- hmfCopy = GpiCopyMetaFile((HMF) hItem);
- GpiPlayMetaFile(hpsWindow, hmfCopy, 8L, alOptions, 0L, 0L, NULL);
- break;
-
- case CF_EMPTY:
- /*
- Don't do anything.
- */
- break;
-
- default:
- /*
- If it's an owner-draw format that we can display...
- ...try to get the owner to paint the clipboard.
- (return if we were successful or not)
- */
- fRendered = SendOwnerMsg(WM_PAINTCLIPBOARD, MPFROMHWND(hwnd), 0L)
- break;
- }
- }
- /*
- Tell everybody that the client area is valid now
- */
- WinValidateRect(hwnd, (PRECTL) NULL, FALSE);
- /*
- Clean up
- */
- GpiAssociate(hpsWindow, NULL);
- GpiDestroyPS(hpsWindow);
- WinCloseClipbrd(vhab);
- return fRendered;
- }
-
- BOOL UpdateScreen(HWND hwnd, USHORT usFormat) {
- /*
- Render the format, change the title bar.
- The title bar will look like: "<appname> (<format>)"
- */
- BOOL fRendered = TRUE;
- HPS hpsWindow;
- RECTL rcl;
- UCHAR szFormat[MAXLEN];
- UCHAR szTitle[MAXTITLELEN];
-
- if (vfUpdate) {
- /* If the MLE exists, destroy it */
- if (vhwndMLE) {
- WinDestroyWindow(vhwndMLE);
- vhwndMLE = NULL;
- }
-
- /* Clear the client area */
- WinQueryWindowRect(hwnd, &rcl);
- WinInvalidateRect(hwnd, &rcl, FALSE);
- hpsWindow = WinBeginPaint(hwnd, NULL, NULL);
- WinFillRect(hpsWindow, &rcl, CLR_BACKGROUND);
- WinEndPaint(hpsWindow);
- }
- if (usFormat) // Check that usFormat != CF_EMPTY
- fRendered = RenderFormat(hwnd, usFormat);
- /*
- Set the title bar appropriately
- */
- if (!vhwndTitlebar && vhwndClipFrame)
- vhwndTitlebar = WinWindowFromID(vhwndClipFrame, FID_TITLEBAR);
-
- if (vhwndTitlebar) {
- GetFormatName(usFormat, szFormat);
- LOADSTRING(IDS_APPNAME, szTitle);
- strcat(szTitle, "("); strcat(szTitle, szFormat); strcat(szTitle, ")")
- WinSetWindowText(vhwndTitlebar, szTitle);
- }
- /*
- Save the rendered format.
- */
- vusFormat = usFormat;
- return fRendered;
- }
-
- VOID GetAllFormats(VOID) {
- USHORT usFormat; // Temporary used when enumerating
- /*
- Put ourselves into a clean state
- */
- usFormat = vcFmts = 0;
- /*
- Cycle through the available clipboard formats
- */
- while (usFormat = WinEnumClipbrdFmts(vhab, usFormat)) {
- vausFormats[vcFmts++] = usFormat;
- }
- /*
- Set the current clipboard format to the first one, if possible
- (in preparation for the WM_PAINT which will follow).
- */
- vusFormat = (vcFmts ? vausFormats[0] : CF_EMPTY);
- }
-
- VOID GetFormatName(USHORT usFormat, UCHAR szFmtName[]) {
- /*
- GetFormatName()
-
- This routine returns a format name in szFmtName which corresponds
- to the format usFormat. Basically, either we know the format, or
- we get the name from the system atom table. If we can't find it,
- we set it to CF_UNKNOWN.
- */
- switch (usFormat) {
- /*
- If we know the format, we can read it from the string table.
- */
- case CF_EMPTY:
- case CF_TEXT:
- case CF_DSPTEXT:
- case CF_BITMAP:
- case CF_DSPBITMAP:
- case CF_METAFILE:
- case CF_DSPMETAFILE:
- LOADSTRING(usFormat, szFmtName);
- break;
-
- default:
- /*
- Get the format name from the system atom table.
- If not found, tag it as an unknown format.
- */
- if (!WinQueryAtomName(WinQuerySystemAtomTable(),
- usFormat, szFmtName, MAXLEN))
-
- LOADSTRING(CF_UNKNOWN, szFmtName);
-
- break;
- }
- }
-
- BOOL SendOwnerMsg(USHORT msg, MPARAM mp1, MPARAM mp2) {
- BOOL rc;
- HWND hwndOwner;
- /*
- If we are an OWNERDISPLAY format,
- lock the owner window, tell it to perform the operation, return
- */
- if ( rc = ( (vfsFmtInfo & CFI_OWNERDISPLAY)
- && (hwndOwner = WinQueryClipbrdOwner(vhab, TRUE)) ) ) {
-
- WinSendMsg(hwndOwner, msg, mp1, mp2);
- WinLockWindow(hwndOwner, FALSE);
- }
- return rc;
- }
-
- BOOL DoScrolling(HWND hwnd, BOOL fHorz, USHORT sbCmd) {
- /*
- This routine depends on the fact that the thumb cannot be set past the
- range of the scroll bar. Since this is handled in the system SBM_SETPOS
- code already, we need not worry about it.
-
- We return TRUE if the scroll bar message is processed.
- */
- HWND hwndSB; /* Scroll bar handle */
- USHORT cpels; /* Page length/width for PAGExxxx commands *
- SWP swp; /* Dimensions of the client area */
- USHORT usOld; /* The current scroll bar position */
- USHORT usNew; /* The new scroll bar position */
- /*
- Set the scroll bar-specific parameters
- */
- WinQueryWindowPos(hwnd, &swp);
- if (fHorz) { /* Horizontal scroll bar */
- hwndSB = vhwndHSB;
- cpels = swp.cx;
- } else { /* Vertical scroll bar */
- hwndSB = vhwndVSB;
- cpels = swp.cy;
- }
- /*
- Handle both scroll bars with one common routine
-
- Basically, the scroll bar has been set so that
- the thumb value corresponds to the offset that
- the bitmap is drawn from. So, to scroll by a
- page, compute the number of pels of the page,
- and move the thumb by that amount.
-
- This code is simplified by the fact that SB_SETPOS
- will not allow the thumb to be set outside of the
- range of the scroll bar, but will "stop" it at the
- appropriate bound.
- */
- usOld = SHORT1FROMMR( WinSendMsg(hwndSB, SBM_QUERYPOS, 0L, 0L));
-
- switch (sbCmd) {
- case SB_PAGERIGHT: /* SB_PAGEDOWN */
- WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld + cpels), 0L);
- break;
-
- case SB_PAGELEFT: /* SB_PAGEUP */
- WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld - cpels), 0L);
- break;
-
- case SB_LINERIGHT: /* SB_LINEDOWN */
- WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld + LINE), 0L);
- break;
-
- case SB_LINELEFT: /* SB_LINEUP */
- WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(usOld - LINE), 0L);
- break;
-
- case SB_SLIDERPOSITION:
- /*
- It would be nice to be consistent with the other
- SB_ cases, but the problem is that when this message
- is sent, the position is *already* set to "usPosition".
-
- So, just invalidate the entire region, and hope that most
- of these types of operations will be large scrolls.
- */
- // WinSendMsg(hwndSB, SBM_SETPOS, MPFROMSHORT(LOUSHORT(mp2)), 0L)
- WinInvalidateRect(hwnd, NULL, TRUE);
- break;
-
- default:
- return FALSE;
- }
- /*
- Now, we find out where the new thumb position is,
- scroll the window contents appropriately, and specify
- SW_INVALIDATERGN so that the remainder will be
- invalidated/repainted.
- */
- usNew = SHORT1FROMMR( WinSendMsg(hwndSB, SBM_QUERYPOS, 0L, 0L));
- if (fHorz)
- WinScrollWindow(hwnd, (SHORT) (usOld - usNew), 0,
- NULL, NULL, NULL, NULL, SW_INVALIDATERGN);
- else
- WinScrollWindow(hwnd, 0, (SHORT) (usNew - usOld),
- NULL, NULL, NULL, NULL, SW_INVALIDATERGN);
-
- return TRUE;
- }
-
-
- CLOCK.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CLOCK\CLOCK.C
-
- /*
- clock.c Presentation Manager Analog Clock Application
- Created by Microsoft Corporation, 1989
- */
- #define INCL_PM
- #include <os2.h>
- #include <string.h>
- #include "res.h"
-
- extern MRESULT EXPENTRY ClkWndProc ( HWND , USHORT , MPARAM , MPARAM ) ;
-
- int cdecl main ( int argc , char * argv [ ] ) ;
- BOOL ClkInit ( VOID ) ;
- HWND hwndFrame ;
- HAB hab ;
- HMQ hmq ;
- HSWITCH hsw ;
- extern HPS hps ;
- BOOL fStartAsIcon = FALSE ;
-
- /*
- main(argc, argv) Main program
- */
- int cdecl main ( int argc , char * argv [ ] )
- {
- QMSG qmsg ;
-
- /* have we been asked to start ourselves as an icon? */
- if (argc > 0) {
- if ( strcmpi ( argv [ 1 ] , "iconic" ) == 0 )
- fStartAsIcon = TRUE ;
- }
-
- if ( ClkInit ( ) ) {
-
- while ( WinGetMsg ( hab , & qmsg , NULL , 0 , 0 ) )
- WinDispatchMsg ( hab , & qmsg ) ;
-
- /* Clean up code */
- GpiDestroyPS( hps );
- WinRemoveSwitchEntry ( hsw ) ;
- WinDestroyWindow ( hwndFrame ) ;
- WinDestroyMsgQueue ( hmq ) ;
- WinTerminate ( hab ) ;
- }
-
- return 0 ;
- }
-
- /*
- ClkInit() Clock Initialization routine
- Returns TRUE if successful.
- */
- BOOL ClkInit ( )
- {
- /* application name, switch list info, and frame creation flags */
- static PSZ pszClkName = "Clock" ;
- static SWCNTRL swctl = { 0 , 0 , 0 , 0 , 0 , SWL_VISIBLE ,
- SWL_JUMPABLE , "Clock" , 0 } ;
- static LONG fcf = FCF_SIZEBORDER | FCF_TITLEBAR | FCF_MINMAX
- | FCF_SYSMENU ;
-
- HWND hwndClient ;
- PID pid ;
- TID tid ;
-
- if ( ( hab = WinInitialize ( 0 ) ) == NULL )
- return FALSE ;
-
- if ( ( hmq = WinCreateMsgQueue ( hab , 0 ) ) == NULL ) {
- WinTerminate ( hab ) ;
- return FALSE ;
- }
-
- if ( ! WinRegisterClass ( hab , pszClkName , ClkWndProc ,
- CS_SIZEREDRAW , 0 ) ) {
- WinDestroyMsgQueue ( hmq ) ;
- WinTerminate ( hab ) ;
- return FALSE ;
- }
-
- hwndFrame = WinCreateStdWindow ( HWND_DESKTOP , ( ULONG ) NULL , & fcf ,
- pszClkName , pszClkName , WS_VISIBLE ,
- (HMODULE) NULL , ID_RESOURCE , & hwndCli
-
- if ( hwndFrame == NULL ) {
- WinDestroyMsgQueue ( hmq ) ;
- WinTerminate ( hab ) ;
- return FALSE ;
- }
-
- /* add ourselves to the switch list */
- WinQueryWindowProcess ( hwndFrame , & pid , & tid ) ;
- swctl . hwnd = hwndFrame ;
- swctl . idProcess = pid ;
- hsw = WinAddSwitchEntry ( & swctl ) ;
-
- return TRUE ;
- }
-
-
- COMPORT.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\COMPORT.C
-
- /*
- comport.c -- This file contains the sources for COM port manipulation.
- Created by Microsoft Corporation, 1989
- */
- #define INCL_DOSFILEMGR
- #define INCL_DOSDEVICES
- #define INCL_DOSDEVIOCTL
- #include <os2.h>
- #include "global.h"
- #include "comport.h"
- /*
- Constants
- */
- XON 0x11 /* Ctrl Q */
- XOFF 0x13 /* Ctrl S */
- char CRLF[2] = { 0x0d, 0x0a };
-
- /*
- Variables
- */
- DCBINFO dcbinfo; /* Device control block for Ioctl 53H,
- HFILE hPort;
- LINECONTROL lnctlBuf;
- int rc;
- USHORT usErrWord;
-
- int ComFlush(void) {
- /*
- Flush the COM port with Category 11 functions
- */
- BYTE Data, Zero = 0;
-
- /* Call Category 11 Functions 1H, 2H Flush Input, Output Buffers */
- if (rc = DosDevIOCtl(&Data, &Zero, 0x01, 11, hPort)) return rc;
- if (rc = DosDevIOCtl(&Data, &Zero, 0x02, 11, hPort)) return rc;
- return 0;
- }
-
- int ComInit(COM comTerm) {
- /*
- Open the COM port according to the specifications
- */
- USHORT action;
-
- /* Get File Handle for COM port (shared read/write access) */
- if (rc = DosOpen(comTerm.szPort,&hPort, &action, 0L, 0, 0x0001, 0x0042, 0
- return rc;
-
- /* Call Category 1 Function 41H Set Baud Rate */
- if (rc = DosDevIOCtl(NULL, &comTerm.usBaud, 0x41, 1, hPort)) return rc;
-
- /* Call Category 1 Function 42H Set Line Characteristics */
- lnctlBuf.bDataBits = comTerm.bData;
- lnctlBuf.bParity = comTerm.bParity;
- lnctlBuf.bStopBits = (BYTE) (comTerm.bStop - 20); /* IDD_ON
- if (rc = DosDevIOCtl(NULL, &lnctlBuf, 0x42, 1, hPort)) return rc;
-
- /* Call Category 1 Function 73H Query Device Control Block */
- if (rc = DosDevIOCtl(&dcbinfo, 0L, 0x73, 1, hPort)) return rc;
-
- /*
- Do we want software handshaking?
- */
- dcbinfo.fbFlowReplace &= ~(0x03); /* Clear bits 0 and 1 */
- dcbinfo.fbFlowReplace |=
- (comTerm.fSoftware) ? (MODE_AUTO_TRANSMIT | MODE_AUTO_RECEIVE)
- /*
- Do we want hardware handshaking?
- */
- /* Turn on DTR, if appropriate */
- dcbinfo.fbCtlHndShake &= ~(0x03); /* Clear bits 0 and 1 */
- dcbinfo.fbCtlHndShake |= ((comTerm.fHardware) ? MODE_DTR_CONTROL :
-
- /* Turn on RTS, if appropriate */
- dcbinfo.fbFlowReplace &= ~(0xc0); /* Clear bits 6 and 7 */
- dcbinfo.fbFlowReplace |= ((comTerm.fHardware) ? MODE_RTS_CONTROL :
-
- /* Adjust CTS output handshaking */
- dcbinfo.fbCtlHndShake &= ~MODE_CTS_HANDSHAKE; /* Clear bit 3 *
- dcbinfo.fbCtlHndShake |= ((comTerm.fHardware)?MODE_CTS_HANDSHAKE:0
-
- /* Adjust DSR output handshaking */
- dcbinfo.fbCtlHndShake &= ~MODE_DSR_HANDSHAKE; /* Clear bit 4 *
- dcbinfo.fbCtlHndShake |= ((comTerm.fHardware)?MODE_DSR_HANDSHAKE:0
-
- /* Turn off DCD output handshaking */
- dcbinfo.fbCtlHndShake &= ~MODE_DCD_HANDSHAKE; /* Clear bit 5 *
-
- /* Adjust DSR input sensitivity */
- dcbinfo.fbCtlHndShake &= ~MODE_DSR_SENSITIVITY; /* Clear bit 6 *
- dcbinfo.fbCtlHndShake |= ((comTerm.fHardware)?MODE_DSR_SENSITIVITY
- /*
- Set the line to Wait for Character, Read mode
- */
- dcbinfo.fbTimeout &= ~(0x06); /* Clear bits, then s
- dcbinfo.fbTimeout |= MODE_WAIT_READ_TIMEOUT;
- dcbinfo.usReadTimeout = -1; /* Never! */
-
- /* Call Category 1 Function 53H Set Device Control Block */
- if (rc = DosDevIOCtl(0L, &dcbinfo, 0x53, 1, hPort)) return rc;
-
- /* Get ready to start */
- return ComFlush();
- }
-
- USHORT ComRead(Line pli) {
- /*
- Reads all characters present
- Returns: 0 if successful
- nonzero (Dos Error or Com Error Word) if unsuccessful
- */
- /* Read from the port... And snatch as many as you can! (blocking read) *
- if (rc = DosRead(hPort, pli->szText, MAXLINELEN, &(pli->cch))) return rc;
-
- /* Check the COM Error Word */
- if (rc = DosDevIOCtl(&usErrWord, NULL, 0x6d, 1, hPort)) return rc;
-
- /* ...then return it */
- return usErrWord;
- }
-
- int ComWrite(char ch) {
- /*
- Write a character at a time
-
- Okay as long as you don't type too fast
- */
- USHORT nCharsWritten;
-
- return DosWrite(hPort, &ch, 1, &nCharsWritten);
- }
-
- int ComClose(void) {
- /*
- Close the COM port
- */
- if (rc = ComFlush()) return rc;
- return DosClose(hPort);
- }
-
- int ComBreak(void) {
- /*
- Set BREAK mode ON
- */
- USHORT ComErr;
-
- /* Call Category 1 Function 4BH -- Set Break On */
- return DosDevIOCtl(&ComErr, NULL, 0x4b, 1, hPort);
- }
-
- int ComUnbreak(void) {
- /*
- Set BREAK mode OFF
- */
- USHORT ComErr;
-
- /* Call Category 1 Function 45H -- Set Break Off */
- return DosDevIOCtl(&ComErr, NULL, 0x45, 1, hPort);
- }
-
- int ComError(void) { return (int) usErrWord; }
-
-
- COMTALK.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\COMTALK\COMTALK.C
-
- /*
- comtalk.c -- Main routines
- Created by Microsoft Corporation, 1989
-
- This file contains the sources for the dialog box manipulation, and menu
- managment, and other aspects of interfacing with the user.
- */
- #define INCL_WIN
- #include <os2.h>
- "comtalk.h" /* definition of COM from Global, and Resource IDs */
- "avio.h" /* Routines needed to manage AVIO Presentation Space */
- "threads.h" /* Thread initialization and control routines */
- <stdio.h> /* Only needed for file I/O */
- <string.h> /* one strcpy call */
- /*
- Variables
- */
- CHAR szCaption[] = "";
- HAB hAB;
- COM comTerm;
- COM comTemp;
- HWND hWndMenu;
- CLASSINFO clsi;
- PFNWP pfnOldFrameWndProc;
- BOOL fConnected = FALSE;
- BOOL fPaging;
- int iUpdate;
- BOOL fFreeze = TRUE;
- int iError;
- /*
- Macros
- */
- #define InRange(x, a, b) ((x >= a) && (x <= b))
-
- /*
- Shorthand for sending messages, querying
- */
- #define Parent(h) \
- WinQueryWindow(h, QW_PARENT, FALSE)
-
- #define EnableMenuItem(id) \
- WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
- MPFROM2SHORT(MIA_DISABLED,0))
-
- #define DisableMenuItem(id) \
- WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
- MPFROM2SHORT(MIA_DISABLED, MIA_DISABLED))
-
- #define CheckMenuItem(id) \
- WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
- MPFROM2SHORT(MIA_CHECKED, MIA_CHECKED))
-
- #define UnCheckMenuItem(id) \
- WinSendMsg(hWndMenu, MM_SETITEMATTR, MPFROM2SHORT(id, TRUE), \
- MPFROM2SHORT(MIA_CHECKED, 0))
-
- #define PushButton(h, id) \
- WinSendDlgItemMsg(h, id, BM_SETCHECK, MPFROM2SHORT(TRUE, 0), 0L)
-
- #define Valid(bData, bStop) \
- (((bData == IDD_FIVE) && (bStop != IDD_TWOSTOP)) \
- || ((bData != IDD_FIVE) && (bStop != IDD_ONEFIVE)))
-
- #define ErrMsg(h, s) \
- WinMessageBox(HWND_DESKTOP, h, s, NULL, 0, MB_OK | MB_ICONEXCLAMATION)
-
- char Ctrl(char ch) {
- return (CHAR) ((('a' <= ch) && (ch <= 'z')) ? (ch - 'a' + '\001') :
- ((('A' <= ch) && (ch <= 'Z')) ? (ch - 'A' + '\001') : ch));
- }
-
- /*
- Local/Private routines
- */
- void ReadOpts(HWND);
- void InitTerm(void);
- void Initialize(HWND);
- void ChangeSystemMenu(HWND);
- BOOL Filter(USHORT, char, USHORT);
-
- void main (void) {
- static CHAR szClientClass[] = "Terminal";
- HMQ hmq;
- HWND hWndClient, hWndFrame;
- QMSG qmsg;
- ULONG flFrameFlags = FCF_STANDARD | FCF_HORZSCROLL | FCF_VERTSCRO
- ULONG flFrameStyle = WS_VISIBLE | FS_SCREENALIGN;
-
- hAB = WinInitialize(0);
- hmq = WinCreateMsgQueue(hAB, 0);
-
- WinRegisterClass(hAB, szClientClass, ClientWndProc, CS_SYNCPAINT, 0);
-
- hWndFrame = WinCreateStdWindow(HWND_DESKTOP, flFrameStyle,
- &flFrameFlags, szClientClass, szCaption,
- 0L, (HMODULE) NULL, ID_RESOURCE, &hWndCl
-
- /* Setup AVIO PS and force a paint */
- AvioInit(hWndFrame, hWndClient);
- WinSendMsg(hWndClient, WM_PAINT, NULL, NULL);
-
- /* Try to subclass the Frame window... */
- pfnOldFrameWndProc = WinSubclassWindow(hWndFrame, NewFrameWndProc);
-
- while (WinGetMsg(hAB, &qmsg, NULL, 0, 0)) WinDispatchMsg(hAB, &qmsg);
-
- /* Blast the AVIO PS */
- AvioClose();
-
- WinDestroyWindow(hWndFrame);
- WinDestroyMsgQueue(hmq);
- WinTerminate(hAB);
- DosExit(EXIT_PROCESS, 0);
- }
-
- MRESULT CALLBACK ClientWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- /*
- Window Procedure which traps messages to the Client area
- */
- switch (msg) {
- case WM_AVIOUPDATE:
- fNoUpdate = AvioUpdateLines(FALSE, &fPaging);
- if (fConnected && fPaging) {
- CheckMenuItem(IDM_PAGING);
- }
- break;
-
- case WM_MSGBOX:
- iUpdate = (int)SHORT1FROMMP( mp2);
- switch ((int)SHORT1FROMMP(mp1)) {
- case (int) MBE_COMREAD:
- if (iError = iUpdate) EnableMenuItem(IDM_ERRORS);
- iUpdate = 0;
- break;
-
- default:
- ErrMsg(hWnd, aszMessage[SHORT1FROMMP(mp1)]);
- break;
- }
- if (iUpdate) { /* Page down because queue is full */
- fNoUpdate = AvioUpdateLines(TRUE, &fPaging);
- if (fConnected && fPaging) CheckMenuItem(IDM_PAGING);
- else UnCheckMenuItem(IDM_PAGING);
- ThdReset();
- }
- break;
-
- case WM_CREATE:
- ChangeSystemMenu(hWnd);
- /*
- Initialize the Dialog Options
- */
- Initialize(hWnd);
- /*
- Get the Handle so you can enable/disable menu items
- Thanks again to Charles Petzold
- */
- hWndMenu = WinWindowFromID(Parent(hWnd), FID_MENU);
- /*
- Disable some entries (can do this in the resource file)
- */
- DisableMenuItem(IDM_CLOSE);
- DisableMenuItem(IDM_BREAK);
- DisableMenuItem(IDM_COMMANDMENU);
- break;
-
- case WM_PAINT: /* Paint the AVIO way! */
- AvioPaint(hWnd);
- break;
-
- case WM_SIZE: /* Size the AVIO way! */
- fNoUpdate = AvioUpdateLines(FALSE, &fPaging);
- if (fConnected && fPaging) {
- CheckMenuItem(IDM_PAGING);
- }
- return AvioSize(hWnd, msg, mp1, mp2);
- break;
-
- case WM_HSCROLL:
- AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), TRUE);
- break;
-
- case WM_VSCROLL:
- AvioScroll(HIUSHORT(mp2), LOUSHORT(mp2), FALSE);
- break;
-
- case WM_ERASEBACKGROUND:
- return 0;
- break;
-
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
- case IDM_ABOUT:
- WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,
- (HMODULE) NULL, IDD_ABOUT, NULL);
- return 0;
-
- case IDM_HELP:
- WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,
- (HMODULE) NULL, IDD_MAINHELPBOX, NULL);
- return 0;
-
- case IDM_SETTINGS:
- WinDlgBox(HWND_DESKTOP, hWnd, SetDlgProc,
- (HMODULE) NULL, IDD_SET, NULL);
- return 0;
-
- case IDM_CONNECT:
- AvioStartup(hWnd);
- ThdInitialize(hWnd, comTerm); /* Spawn 3 threa
- /*
- Disable/Enable Menu Items
- */
- DisableMenuItem(IDM_CONNECT);
- DisableMenuItem(IDM_SETTINGS);
- DisableMenuItem(IDM_ERRORS);
-
- EnableMenuItem(IDM_CLOSE);
- EnableMenuItem(IDM_BREAK);
- EnableMenuItem(IDM_COMMANDMENU);
- fConnected = TRUE;
- return 0;
-
- case IDM_CLOSE:
- fConnected = FALSE;
- ThdTerminate(); /* Might have to wait?
- /*
- Update menu items
- */
- UnCheckMenuItem(IDM_BREAK);
-
- DisableMenuItem(IDM_CLOSE);
- DisableMenuItem(IDM_BREAK);
- DisableMenuItem(IDM_COMMANDMENU);
-
- EnableMenuItem(IDM_CONNECT);
- EnableMenuItem(IDM_SETTINGS);
-
- return 0;
-
- case IDM_BREAK:
- ThdDoBreak();
- return 0;
-
- case IDM_ERRORS:
- if (iError & 1)
- ErrMsg(hWnd, "Receive Queue Overrun");
- if (iError & 2)
- ErrMsg(hWnd, "Receive Hardware Overrun");
- if (iError & 4)
- ErrMsg(hWnd, "Parity Error");
- if (iError & 8)
- ErrMsg(hWnd, "Framing Error");
- DisableMenuItem(IDM_ERRORS);
- return 0;
-
- case IDM_PAGE:
- fNoUpdate = AvioUpdateLines(TRUE, &fPaging);
- if (fPaging) CheckMenuItem(IDM_PAGING);
- else UnCheckMenuItem(IDM_PAGING);
- return 0;
-
- case IDM_UP:
- AvioPageUp();
- return 0;
-
- case IDM_PAGING:
- if (fPaging = !fPaging) {
- CheckMenuItem(IDM_PAGING);
- } else {
- UnCheckMenuItem(IDM_PAGING);
- }
- return 0;
-
- default: return 0;
- }
-
- case WM_CHAR: /* Put characters in typeahead buffer
- if (fConnected && !(CHARMSG(&msg)->fs & KC_KEYUP))
- if (Filter( CHARMSG(&msg)->fs,
- (char) CHARMSG(&msg)->chr,
- CHARMSG(&msg)->vkey))
- ErrMsg(hWnd, "Error Writing COM Port");
- break;
-
- case WM_TRACKFRAME:
- AvioTrackFrame(hWnd, mp1);
- break;
-
- case WM_MINMAXFRAME: /* Trap MAXIMIZE messages */
- AvioMinMax((PSWP) mp1);
-
- default: return WinDefWindowProc(hWnd, msg, mp1, mp2);
- }
- return 0;
- }
-
- MRESULT CALLBACK AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
- /*
- Dialog box control for the ABOUT COMTALK... dialog box
- */
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hDlg, TRUE); break;
- default: break;
- }
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
- void WriteOpts(void) {
- /*
- Write Settings to file COMTALK.INI
- */
- FILE *fp;
-
- fp = fopen("comtalk.ini", "w+");
- fprintf(fp, "%d %d %d %d %d %d %d %s\n", comTerm.usBaud, comTerm.bParity,
- comTerm.bData, comTerm.bStop, comTerm.fWrap,
- comTerm.fHardware, comTerm.fSoftware, comTerm.szPort);
- fclose(fp);
- }
-
- void ReadOpts(HWND hWnd) {
- /*
- Read Settings from COMTALK.INI
- */
- FILE *fp;
-
- /* Use InitTerm() if we have reading problems */
- if ((fp = fopen("comtalk.ini", "r")) == NULL) InitTerm();
- else if (fscanf(fp, "%d%d%d%d%d%d%d%s", &comTerm.usBaud, &comTerm.bParity
- &comTerm.bData, &comTerm.bStop, &comTerm.fWrap,
- &comTerm.fHardware, &comTerm.fSoftware, comTerm.szPort) == EOF)
- InitTerm();
- if (!Valid(comTerm.bData, comTerm.bStop)) {
- ErrMsg(hWnd, "Invalid terminal setting");
- InitTerm();
- }
- fclose(fp);
- }
-
- void InitTerm(void) {
- /*
- Initialize the TERM structure to DosDevIOCtl defaults
- */
- strcpy(comTerm.szPort, "com1");
- comTerm.usBaud = 9600; comTerm.bParity = IDD_EVENP;
- comTerm.bData = IDD_SEVEN; comTerm.bStop = IDD_ONESTOP;
- comTerm.fWrap = comTerm.fSoftware = TRUE; comTerm.fHardware = FALSE;
- }
-
- MRESULT CALLBACK SetDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2) {
- /*
- The Settings Dialog Box control routine
- */
- BOOL rc;
- BYTE bTemp;
-
- switch(msg) {
- case WM_INITDLG:
- WinSetDlgItemText(hDlg, IDD_PORT, comTerm.szPort);
- WinSetDlgItemShort(hDlg, IDD_BAUD, comTerm.usBaud, FALSE);
-
- PushButton(hDlg, comTerm.bParity);
- PushButton(hDlg, comTerm.bData);
- PushButton(hDlg, comTerm.bStop);
- if (comTerm.fWrap) PushButton(hDlg, IDD_WRAP);
- if (comTerm.fHardware) PushButton(hDlg, IDD_HW);
- if (comTerm.fSoftware) PushButton(hDlg, IDD_SW);
-
- comTemp.bParity = comTerm.bParity;
- comTemp.bData = comTerm.bData;
- comTemp.bStop = comTerm.bStop;
- comTemp.fWrap = comTerm.fWrap;
- comTemp.fHardware = comTerm.fHardware;
- comTemp.fSoftware = comTerm.fSoftware;
- break;
-
- case WM_HELP:
- WinDlgBox(HWND_DESKTOP, hDlg, AboutDlgProc,
- (HMODULE) NULL, IDD_SETHELPBOX, NULL);
- break;
-
- case WM_CONTROL:
- /*
- The fact that these are AutoRadioButtons makes life easy.
- */
- bTemp = (BYTE) SHORT1FROMMP(mp1); /* Which button pushed?
- if InRange(bTemp, IDD_NOP, IDD_SPACEP)
- {
- comTemp.bParity = bTemp;
- }
- else
- {
- if InRange(bTemp, IDD_FIVE, IDD_EIGHT)
- {
- comTemp.bData = bTemp;
- }
- else
- {
- if InRange(bTemp, IDD_ONESTOP, IDD_TWOSTOP)
- {
- comTemp.bStop = bTemp;
- }
- else
- {
- switch (bTemp) {
- case IDD_WRAP: comTemp.fWrap = !c
- case IDD_HW : comTemp.fHardware = !c
- case IDD_SW : comTemp.fSoftware = !c
- default:
- }
- }
- }
- }
- break;
- case WM_COMMAND: /* Ready to exit... */
- switch(COMMANDMSG(&msg)->cmd) {
- case IDD_SAVE:
- case DID_OK:
- if (!Valid(comTemp.bData, comTemp.bStop)) {
- ErrMsg(hDlg,"Data and Stop Bits Incompatible");
- break; /* No-op...Dialog not dismissed */
- }
- WinQueryDlgItemText(hDlg, IDD_PORT, 5, comTerm.szPort);
- WinQueryDlgItemShort(hDlg, IDD_BAUD, &comTerm.usBaud, rc)
- comTerm.bParity = comTemp.bParity;
- comTerm.bData = comTemp.bData;
- comTerm.bStop = comTemp.bStop;
- comTerm.fWrap = comTemp.fWrap;
- comTerm.fHardware = comTemp.fHardware;
- comTerm.fSoftware = comTemp.fSoftware;
- if (COMMANDMSG(&msg)->cmd == IDD_SAVE) WriteOpts();
- case DID_CANCEL: WinDismissDlg(hDlg, FALSE);
- default: break;
- }
- break;
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
- void Initialize(HWND hWnd) {
- ReadOpts(hWnd);
- fPaging = FALSE;
- }
-
- void ChangeSystemMenu(HWND hWnd) {
- /*
- Insert items into the System Menu (with thanks to Charles Petzold)
- */
- static CHAR *x[2] = { NULL, "~About ComTalk..." }; /* Items to add */
- static MENUITEM mi[2] = { /* The RESOURCE definitions */
- MIT_END, MIS_SEPARATOR, 0x0000, 0, NULL, 0,
- MIT_END, MIS_TEXT, 0x0000, IDM_ABOUT, NULL, 0
- };
- HWND hSM, hSSM; /* Menu and submenu handles */
- MENUITEM miSM; /* System Menu Menuitem */
- SHORT idSM; /* ID of the System Menu */
- /*
- Get ahold of the system menu
- */
- hSM = WinWindowFromID(Parent(hWnd), FID_SYSMENU);
- idSM = SHORT1FROMMR( WinSendMsg(hSM, MM_ITEMIDFROMPOSITION, NULL, NULL));
- WinSendMsg(hSM, MM_QUERYITEM, MPFROM2SHORT(idSM, FALSE), MPFROMP(&miSM));
- /*
- Manipulate the System SubMenu
- */
- hSSM = miSM.hwndSubMenu;
- WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi), MPFROMP(x[0]));
- WinSendMsg(hSSM, MM_INSERTITEM, MPFROMP(mi+1), MPFROMP(x[1]));
- }
-
- MRESULT CALLBACK NewFrameWndProc(HWND hWnd, USHORT msg, MPARAM mp1, MPARAM mp
- /*
- Force the frame to stay small enough
- */
- BOOL rc; /* Return code for WM_QueryTrackInfo */
-
- switch(msg) {
- case WM_ADJUSTWINDOWPOS: /* Calculate, then show scrollbars */
- AvioAdjustFrame(mp1);
- break;
- case WM_QUERYTRACKINFO:
- rc = (BOOL)SHORT1FROMMR ((*pfnOldFrameWndProc)(hWnd, msg, mp1, mp
- AvioQueryTrackInfo((PTRACKINFO) mp2);
- return (MRESULT) rc;
- default: break;
- }
- return (*pfnOldFrameWndProc)(hWnd, msg, mp1, mp2);
- }
-
- BOOL Filter(USHORT fs, char ch, USHORT vkey) {
- BOOL rc = FALSE;
-
- if (fs & KC_VIRTUALKEY) {
- switch(vkey) {
- case VK_HOME:
- if (fs & KC_CTRL) rc = ThdPutString("\033[2J",4);
- return (rc || ThdPutString("\033[H", 3));
- case VK_UP:
- return ThdPutString("\033[A", 3);
- case VK_DOWN:
- return ThdPutString("\033[B", 3);
- case VK_RIGHT:
- return ThdPutString("\033[C", 3);
- case VK_LEFT:
- return ThdPutString("\033[D", 3);
- default: break;
- }
- }
-
- if (fs & KC_CTRL) {
- switch (ch) {
- case 'l':
- case 'L': AvioRedraw();
- case '\0': return FALSE; break;
- default: ch = Ctrl(ch); break;
- }
- } else {
- switch (ch) {
- case '\0': return FALSE; break;
- default: break;
- }
- }
- return(rc || ThdPutChar(ch));
- }
-
-
- CPGREP.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CPGREP\CPGREP.C
-
- /* cpgrep - string searches
- *
- * Created by Microsoft Corp. 1986
- *
- *
- */
-
- #include <os2def.h>
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSQUEUES
- #define INCL_DOSMEMMGR
- #define INCL_DOSMISC
- #include <bsedos.h>
- #include <stdio.h>
- #include <fcntl.h>
- #include <ctype.h>
-
- #define BEGLINE 0x40
- #define DEBUG 0x08
- #define ENDLINE 0x80
- #define FILBUFLEN (SECTORLEN*30)
- #define FILNAMLEN 80
- #define INVERT 0x10
- #define ISCOT 0x0002
- #define LG2SECLEN 9
- #define LINELEN 128
- #define LINENOS 0x04
- #define LNOLEN 8
- #define MAXSTRLEN 128
- #define NAMEONLY 0x02
- #define OUTBUFLEN (SECTORLEN*4)
- #define SECTORLEN (1 << LG2SECLEN)
- #define SHOWNAME 0x01
- #define STKLEN 256
- #define TIMER 0x20
- #define TRTABLEN 256
- #define s_text(x) (((char *)(x)) - ((x)->s_must))
-
- typedef struct stringnode
- {
- struct stringnode *s_alt; /* List of alternates */
- struct stringnode *s_suf; /* List of suffixes */
- int s_must; /* Length of portion th
- }
- STRINGNODE;
-
- char filbuf[(FILBUFLEN + 2)*2];
- char *bufptr[] = { filbuf, filbuf + FILBUFLEN + 2 };
- char outbuf[OUTBUFLEN*2];
- char *obuf[] = { outbuf, outbuf + OUTBUFLEN };
- char *optr[] = { outbuf, outbuf + OUTBUFLEN };
- USHORT ocnt[] = { OUTBUFLEN, OUTBUFLEN };
- int oi = 0;
- char transtab[TRTABLEN] = { 0 };
- STRINGNODE *stringlist[TRTABLEN/2];
- USHORT arrc; /* I/O return code for Dos
- USHORT awrc; /* I/O return code for Dos
- int casesen = 1; /* Assume case-sensitivity */
- USHORT cbread; /* Bytes read by DosRead */
- USHORT cbwrite; /* Bytes written by DosWrite */
- int clists = 1; /* One is first available index
- int flags; /* Flags */
- int lineno; /* Current line number */
- char pmode; /* Protected mode flag */
- LONG readdone; /* Async read done semaphore */
- LONG readpending; /* Async read pending semapho
- int status = 1; /* Assume failure */
- char *t2buf; /* Async read buffer */
- USHORT t2buflen; /* Async read buffer length */
- HFILE t2fd; /* Async read file */
- char *t3buf; /* Async write buffer */
- USHORT t3buflen; /* Async write buffer length *
- HFILE t3fd; /* Async write file */
- LONG writedone; /* Async write done semaphore *
- LONG writepending; /* Async write pending semap
- char target[MAXSTRLEN];
- /* Last string added */
- int targetlen; /* Length of last string added *
-
- int countlines(); /* See CPGREPSB.ASM */
- int countmatched(); /* See CPGREPSB.ASM */
- char *findlist(); /* See CPGREPSB.ASM */
- char *findone(); /* See CPGREPSB.ASM */
- void flush1buf(); /* See below */
- int grepbuffer(); /* See below */
- int revfind(); /* See CPGREPSB.ASM */
- void write1buf(); /* See below */
- char *(*find)() = findlist;
- void (*flush1)() = flush1buf;
- int (*grep)() = grepbuffer;
- void (*write1)() = write1buf;
-
- void freenode(x)
- register STRINGNODE *x; /* Pointer to node to free */
- {
- register STRINGNODE *y; /* Pointer to next node in
-
- while(x != NULL) /* While not at end of list */
- {
- if(x->s_suf != NULL) freenode(x->s_suf);
- /* Free suffix list */
- y = x; /* Save pointer */
- x = x->s_alt; /* Move down the list */
- free(y); /* Free the node */
- }
- }
-
-
- STRINGNODE *newnode(s,n)
- char *s; /* String */
- int n; /* Length of string */
- {
- register STRINGNODE *new; /* Pointer to new node */
- char *t; /* String pointer */
- char *malloc(); /* Storage allocator */
-
- if((t = malloc(sizeof(STRINGNODE) + n + (n & 1))) == NULL)
- { /* If allocation fails */
- fprintf(stderr,"Out of memory\n");
- DosExit( EXIT_PROCESS, 2); /* Print error message and die */
- }
- if(n & 1) ++t; /* END of string word-aligned */
- strncpy(t,s,n); /* Copy string text */
- new = (STRINGNODE *)(t + n); /* Set pointer to node */
- new->s_alt = NULL; /* No alternates yet */
- new->s_suf = NULL; /* No suffixes yet */
- new->s_must = n; /* Set string length */
- return(new); /* Return pointer to new node */
- }
-
-
- void reallocnode(node,s,n)
- register STRINGNODE *node; /* Pointer to node */
- char *s; /* String */
- register int n; /* Length of string */
- {
- if(n > node->s_must) /* If node must grow */
- {
- fprintf(stderr,"Internal error\n");
- /* Error message */
- DosExit( EXIT_PROCESS, 2); /* Error exit */
- }
- node->s_must = n; /* Set new length */
- memcpy(s_text(node),s,n); /* Copy new text */
- }
-
-
- void addstring(s,n)
- char *s; /* String to add */
- int n; /* Length of string */
- {
- register STRINGNODE *cur; /* Current string */
- register STRINGNODE **pprev; /* Pointer to previous link */
- STRINGNODE *new; /* New string */
- int i; /* Index */
- int j; /* Count */
- int k; /* Count */
-
- if(n <= 0 || n > 127) return; /* Should never happen */
- i = transtab[*s]; /* Get current index */
- if(i == 0) /* If no existing list */
- {
- /*
- * We have to start a new list
- */
- if((i = clists++) >= TRTABLEN/2)
- { /* If too many string lists */
- fprintf(stderr,"Too many string lists\n");
- /* Error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- stringlist[i] = NULL; /* Initialize */
- transtab[*s] = i; /* Set pointer to new list */
- if(!casesen && isalpha(*s)) transtab[*s ^ '\x20'] = i;
- /* Set pointer for other case */
- }
- else if(stringlist[i] == NULL) return;
- /* Check for existing 1-byte string *
- if(--n == 0) /* If 1-byte string */
- {
- freenode(stringlist[i]); /* Free any existing stuff */
- stringlist[i] = NULL; /* No record here */
- return; /* Done */
- }
- ++s; /* Skip first char */
- pprev = stringlist + i; /* Get pointer to link */
- cur = *pprev; /* Get pointer to node */
- while(cur != NULL) /* Loop to traverse match tree
- {
- i = (n > cur->s_must)? cur->s_must: n;
- /* Find minimum of string lengths */
- matchstrings(s,s_text(cur),i,&j,&k);
- /* Compare the strings */
- if(j == 0) /* If complete mismatch */
- {
- if(k < 0) break; /* Break if insertion point found
- pprev = &(cur->s_alt); /* Get pointer to alternate link */
- cur = *pprev; /* Follow the link */
- }
- else if(i == j) /* Else if strings matched */
- {
- if(i == n) /* If new is prefix of current
- {
- reallocnode(cur,s_text(cur),n);
- /* Shorten text of node */
- if(cur->s_suf != NULL) /* If there are suffixes */
- {
- freenode(cur->s_suf);
- /* Suffixes no longer needed */
- cur->s_suf = NULL;
- }
- return; /* All done */
- }
- pprev = &(cur->s_suf); /* Get pointer to suffix link */
- if((cur = *pprev) == NULL) return;
- /* Done if current is prefix of new *
- s += i; /* Skip matched portion */
- n -= i;
- }
- else /* Else partial match */
- {
- /*
- * We must split an existing node.
- * This is the trickiest case.
- */
- new = newnode(s_text(cur) + j,cur->s_must - j);
- /* Unmatched part of current string *
- reallocnode(cur,s_text(cur),j);
- /* Set length to matched portion */
- new->s_suf = cur->s_suf; /* Current string's suffixes */
- if(k < 0) /* If new preceded current */
- {
- cur->s_suf = newnode(s + j,n - j);
- /* FIrst suffix is new string */
- cur->s_suf->s_alt = new;/* Alternate is part of current */
- }
- else /* Else new followed current */
- {
- new->s_alt = newnode(s + j,n - j);
- /* Unmatched new string is alternate
- cur->s_suf = new; /* New suffix list */
- }
- return;
- }
- }
- *pprev = newnode(s,n); /* Set pointer to new node */
- (*pprev)->s_alt = cur; /* Attach alternates */
- }
-
-
- int addfancy(buffer,buflen,seplist)
- register char *buffer; /* Buffer */
- int buflen; /* Length of buffer */
- char *seplist; /* List of separators */
- {
- register char *bufend; /* Pointer to end of buffer */
- int strcnt = 0; /* String count */
- int len; /* String length */
- char c; /* One char buffer */
-
- bufend = buffer + buflen; /* Set end pointer */
- while(buffer < bufend) /* Loop through all strings */
- {
- len = strncspn(buffer,seplist,bufend - buffer);
- /* Length of string */
- if(flags & ENDLINE) /* If match must be at end of line
- {
- c = buffer[len]; /* Save 1st character past string
- buffer[len++] = '\r'; /* Carriage return marks end of line
- }
- if(findlist(buffer,buffer + len) == NULL)
- { /* If no match within string */
- addstring(buffer,len); /* Add string to list */
- if(strcnt++ == 0) /* If first string */
- {
- memcpy(target,buffer,len);
- /* Save first string in buffer */
- targetlen = len; /* Remember length */
- }
- }
- buffer += len; /* Skip over string */
- if(flags & ENDLINE) (--buffer)[0] = c;
- /* Restore saved character */
- buffer += strnspn(buffer,seplist,bufend - buffer);
- /* Skip over trailing separators */
- }
- return(strcnt); /* Return string count */
- }
-
-
- int addplain(buffer,buflen,seplist)
- register char *buffer; /* String list buffer */
- int buflen; /* Buffer length */
- char *seplist; /* List of separators */
- {
- int strcnt; /* String count */
- register int len; /* String length */
- char c; /* One char buffer */
-
- strcnt = 0;
- while((len = strncspn(buffer,seplist,buflen)) > 0)
- { /* While not at end of input l
- if(flags & ENDLINE) /* If match must be at end of line
- {
- c = buffer[len]; /* Save 1st character past string
- buffer[len++] = '\r'; /* Carriage return marks end of line
- }
- if(strcnt == 0) /* Save first string */
- {
- strncpy(target,buffer,len); /* Save string in buffer */
- targetlen = len; /* Save string length */
- }
- addstring(buffer,len); /* Add the string to the table
- if(flags & ENDLINE) buffer[--len] = c;
- /* Restore saved character */
- buffer += len; /* Skip the string */
- buflen -= len;
- len = strnspn(buffer,seplist,buflen);
- /* Skip separators */
- buffer += len;
- buflen -= len;
- ++strcnt; /* Increment string count */
- }
- return(strcnt); /* Return string count */
- }
-
-
- void dumplist(node,indent)
- register STRINGNODE *node; /* Pointer to list to dump *
- int indent; /* Current length of buffer
- {
- int i; /* Counter */
-
- while(node != NULL) /* While not at end of list */
- {
- for(i = 0; i < indent; ++i) fputc(' ',stderr);
- fwrite(s_text(node),sizeof(char),node->s_must,stderr);
- fprintf(stderr,"\n");
- if(node->s_suf != NULL)
- dumplist(node->s_suf,indent + node->s_must);
- /* Recurse to do suffixes */
- node = node->s_alt; /* Do next alternate in list */
- }
- }
-
-
- void dumpstrings()
- {
- int i; /* Index */
-
- for(i = 0; i < TRTABLEN; ++i) /* Loop through translation table */
- {
- if(transtab[i] == 0) continue; /* Skip null entries */
- fprintf(stderr,"%c\n",i); /* Print the first byte */
- dumplist(stringlist[transtab[i]],1);
- /* Dump the list */
- }
- }
-
-
- HFILE openfile(name)
- char *name; /* File name */
- {
- HFILE fd; /* File descriptor */
-
- if((fd = open(name,0)) == -1) /* If error opening file */
- {
- fprintf(stderr,"Cannot open %s\r\n",name);
- /* Print error message */
- }
- return(fd); /* Return file descriptor */
- }
-
-
- void far thread2() /* Read thread */
- {
- while(DosSemRequest( &readpending, -1L) == 0)
- { /* While there is work to do *
- arrc = DosRead( t2fd, t2buf, t2buflen, &cbread);
- /* Do the read */
- DosSemClear( &readdone); /* Signal read completed */
- }
- fprintf(stderr,"Thread 2: DosSemRequest failed\n");
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
-
-
- void far thread3() /* Write thread */
- {
- while(DosSemRequest((long far *) &writepending,-1L) == 0)
- { /* While there is work to do *
- awrc = DosWrite(t3fd, t3buf, t3buflen, &cbwrite);
- /* Do the write */
- DosSemClear( &writedone); /* Signal write completed */
- }
- fprintf(stderr,"Thread 3: DosSemRequest failed\n");
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
-
-
- void startread(fd,buffer,buflen)
- HFILE fd; /* File handle */
- char *buffer; /* Buffer */
- USHORT buflen; /* Buffer length */
- {
- if(pmode) /* If protected mode */
- {
- if(DosSemRequest( &readdone, -1L) != 0)
- { /* If we fail to get the semaphore
- fprintf(stderr,"DosSemRequest failed\n");
- /* Error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- t2fd = fd; /* Set parameters for read */
- t2buf = buffer;
- t2buflen = buflen;
- DosSemClear( &readpending); /* Wake thread 2 for read */
- DosSleep(0L); /* Yield the CPU */
- }
- else arrc = DosRead( fd, buffer, buflen, &cbread);
- }
-
-
- int finishread()
- {
- if(pmode && DosSemWait( &readdone, -1L) != 0)
- { /* If protected mode and wait
- fprintf(stderr,"DosSemWait failed\n");
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- return((arrc == 0)? cbread: -1); /* Return number of bytes read */
- }
-
-
- void startwrite(fd,buffer,buflen)
- HFILE fd; /* File handle */
- char *buffer; /* Buffer */
- USHORT buflen; /* Buffer length */
- {
- if(pmode) /* If protected mode */
- {
- if(DosSemRequest( &writedone, -1L) != 0)
- { /* If we fail to get the semaphore
- fprintf(stderr,"DosSemRequest failed\n");
- /* Error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- t3fd = fd; /* Set parameters for write */
- t3buf = buffer;
- t3buflen = buflen;
- DosSemClear( &writepending); /* Wake thread 3 for read */
- DosSleep(0L); /* Yield the CPU */
- }
- else awrc = DosWrite(fd, buffer, buflen, &cbwrite);
- }
-
-
- int finishwrite()
- {
- if(pmode && DosSemWait( &writedone, -1L) != 0)
- { /* If protected mode and wait
- fprintf(stderr,"DosSemWait failed\n");
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- return((awrc == 0)? cbwrite: -1); /* Return number of bytes writte
- }
-
-
- void write1nobuf(buffer,buflen)
- char *buffer; /* Buffer */
- USHORT buflen; /* Buffer length */
- {
- int cb; /* Count of bytes written *
-
- if( DosWrite(1, buffer, buflen, &cb) != 0 || cb != buflen)
- /* If write fails */
- {
- fprintf(stderr,"write error %d\n",awrc);
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- }
-
-
- void write1buf(buffer,buflen)
- char *buffer; /* Buffer */
- USHORT buflen; /* Buffer length */
- {
- USHORT cb; /* Byte count */
-
- while(buflen > 0) /* While bytes remain */
- {
- if(awrc != 0) /* If previous write failed */
- {
- fprintf(stderr,"write error %d\n",awrc);
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- if((cb = ocnt[oi]) == 0) /* If buffer full */
- {
- startwrite(1,obuf[oi],OUTBUFLEN);
- /* Write the buffer */
- ocnt[oi] = OUTBUFLEN; /* Reset count and pointer */
- optr[oi] = obuf[oi];
- oi ^= 1; /* Switch buffers */
- cb = ocnt[oi]; /* Get space remaining */
- }
- if(cb > buflen) cb = buflen; /* Get minimum */
- memcpy(optr[oi],buffer,cb); /* Copy bytes to buffer */
- ocnt[oi] -= cb; /* Update buffer length and po
- optr[oi] += cb;
- buflen -= cb;
- buffer += cb;
- }
- }
-
-
- void flush1nobuf()
- {
- }
-
-
- void flush1buf()
- {
- int cb; /* Byte count */
-
- if((cb = OUTBUFLEN - ocnt[oi]) > 0) /* If buffer not empty */
- {
- startwrite(1,obuf[oi],cb); /* Start write */
- if(finishwrite() != cb) /* If write failed */
- {
- fprintf(stderr,"write error %d\n",awrc);
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- }
- }
-
-
- int grepnull(cp,endbuf,name)
- register char *cp; /* Buffer pointer */
- char *endbuf; /* End of buffer */
- char *name; /* File name */
- {
- return(0); /* Do nothing */
- }
-
-
- int grepbuffer(startbuf,endbuf,name)
- char *startbuf; /* Start of buffer */
- char *endbuf; /* End of buffer */
- char *name; /* File name */
- {
- register char *cp; /* Buffer pointer */
- char *lastmatch; /* Last matching line */
- int linelen; /* Line length */
- int namlen = 0; /* Length of name */
- char lnobuf[LNOLEN]; /* Line number buffer */
- char nambuf[LINELEN];/* Name buffer */
-
- cp = startbuf; /* Initialize to start of buffer */
- lastmatch = cp; /* No previous match yet */
- while((cp = (*find)(cp,endbuf)) != NULL)
- { /* While matches are found */
- if((flags & BEGLINE) && cp[-1] != '\n' && cp > startbuf)
- { /* If begin line conditions not me
- ++cp; /* Skip first char of match */
- continue; /* Keep looking */
- }
- status = 0; /* Match found */
- if(flags & NAMEONLY) /* If filename only wanted */
- {
- (*write1)(nambuf,sprintf(nambuf,"%s\r\n",name));
- /* Print the name */
- return(1); /* Punt remainder of buffer */
- }
- cp -= revfind(cp,'\n',cp - startbuf);
- /* Point at last linefeed */
- if(*cp == '\n') ++cp; /* Point at start of line */
- if(flags & SHOWNAME) /* If name wanted */
- {
- if(namlen == 0) namlen = sprintf(nambuf,"%s:",name);
- /* Format name if not done already */
- (*write1)(nambuf,namlen); /* Show name */
- }
- if(flags & LINENOS) /* If line number wanted */
- {
- lineno += countlines(lastmatch,cp);
- /* Count lines since last match */
- (*write1)(lnobuf,sprintf(lnobuf,"%d:",lineno));
- /* Print line number */
- lastmatch = cp; /* New last match */
- }
- linelen = strncspn(cp,"\n",endbuf - cp) + 1;
- /* Calculate line length */
- (*write1)(cp,linelen); /* Print the line */
- cp += linelen; /* Skip the line */
- }
- if(flags & LINENOS) lineno += countlines(lastmatch,endbuf);
- /* Count remaining lines in buffer */
- return(0); /* Keep searching */
- }
-
-
- void showv(name,lastmatch,thismatch)
- char *name;
- register char *lastmatch;
- char *thismatch;
- {
- register int linelen;
- int namlen = 0; /* Length of name */
- char lnobuf[LNOLEN]; /* Line number buffer */
- char nambuf[LINELEN];/* Name buffer */
-
- if(flags & (SHOWNAME | LINENOS))
- {
- while(lastmatch < thismatch)
- {
- if(flags & SHOWNAME) /* If name wanted */
- {
- if(namlen == 0) namlen = sprintf(nambuf,"%s:",name);
- /* Format name if not done already */
- (*write1)(nambuf,namlen);
- /* Write the name */
- }
- if(flags & LINENOS)
- {
- (*write1)(lnobuf,sprintf(lnobuf,"%d:",lineno++));
- }
- linelen = strncspn(lastmatch,"\n",thismatch - lastmatch) + 1;
- (*write1)(lastmatch,linelen);
- lastmatch += linelen;
- }
- }
- else (*write1)(lastmatch,thismatch - lastmatch);
- }
-
-
- int grepvbuffer(startbuf,endbuf,name)
- char *startbuf; /* Start of buffer */
- char *endbuf; /* End of buffer */
- char *name; /* File name */
- {
- register char *cp; /* Buffer pointer */
- register char *lastmatch; /* Pointer to line after last mat
-
- cp = startbuf; /* Initialize to start of buffer */
- lastmatch = cp;
- while((cp = (*find)(cp,endbuf)) != NULL)
- {
- if((flags & BEGLINE) && cp[-1] != '\n' && cp > startbuf)
- { /* If begin line conditions not me
- ++cp; /* Skip first char of match */
- continue; /* Keep looking */
- }
- status = 1; /* Match found */
- if(flags & NAMEONLY) return(1); /* Skip rest of file if NAMEON
- cp -= revfind(cp,'\n',cp - startbuf);
- /* Point at last linefeed */
- if(*cp == '\n') ++cp; /* Point at start of line */
- showv(name,lastmatch,cp); /* Show from last match to this */
- cp += strncspn(cp,"\n",endbuf - cp) + 1;
- /* Skip over line with match */
- lastmatch = cp; /* New "last" match */
- ++lineno; /* Increment line count */
- }
- if(!(flags & NAMEONLY)) showv(name,lastmatch,endbuf);
- /* Show buffer tail if not NAMEONLY *
- return(0); /* Keep searching file */
- }
-
-
- void qgrep(name,fd)
- char *name; /* File name */
- HFILE fd; /* File descriptor */
- {
- register int cb; /* Byte count */
- register char *cp; /* Buffer pointer */
- char *endbuf; /* End of buffer */
- int taillen; /* Length of buffer tail */
- int bufi; /* Buffer index */
- char line[LINELEN]; /* Line buffer */
-
- lineno = 1; /* File starts on line 1 */
- taillen = 0; /* No buffer tail yet */
- bufi = 0; /* Initialize buffer index */
- cp = bufptr[0]; /* Initialize to start of buffer *
- finishread(); /* Make sure no I/O activity */
- arrc = DosRead( fd, cp, FILBUFLEN, &cbread);
- /* Do first read synchronously */
- while((cb = finishread()) + taillen > 0)
- { /* While search incomplete */
- if(cb == 0) /* If buffer tail is all that's le
- {
- taillen = 0; /* Set tail length to zero */
- *cp++ = '\r'; /* Add end of line sequence */
- *cp++ = '\n';
- endbuf = cp; /* Note end of buffer */
- }
- else /* Else start next read */
- {
- taillen = revfind(cp + cb - 1,'\n',cb);
- /* Find length of partial line */
- endbuf = cp + cb - taillen; /* Get pointer to end of buffe
- cp = bufptr[bufi ^ 1]; /* Pointer to other buffer */
- memcpy(cp,endbuf,taillen); /* Copy tail to head of other b
- cp += taillen; /* Skip over tail */
- startread(fd,cp,(FILBUFLEN - taillen) & (~0 << LG2SECLEN));
- /* Start next read */
- }
- if((*grep)(bufptr[bufi],endbuf,name)) return;
- /* Done if NAMEONLY and match found *
- bufi ^= 1; /* Switch buffers */
- }
- if((flags & (NAMEONLY | INVERT)) == (NAMEONLY | INVERT))
- (*write1)(line,sprintf(line,"%s\r\n",name));
- /* Write name if -lv */
- }
-
-
- void usage(verbose)
- int verbose; /* Verbose message flag */
- {
- static char *opts[] =
- {
- "-? - print this message",
- "-B - match pattern if at beginning of line",
- "-E - match pattern if at end of line",
- "-l - print only file name if file contains match",
- "-n - print line number before each matching line",
- "-v - print only lines not containing a match",
- "-x - print lines that match exactly (-BE)",
- "-y - treat upper and lower case as equivalent",
- "-e - treat next argument as the search string",
- "-f - read search strings from file named by next argument",
- "-i - read file list from file named by next argument",
- 0
- };
- register char **opt = opts; /* Option list */
-
- fprintf(stderr,"usage: CPGREP [-?BElnvxy][-e][-f <file>][-i <file>][<stri
- if(verbose) /* If verbose message wanted *
- {
- while(*opt != 0) fprintf(stderr,"%s\n",*opt++);
- /* Print option list */
- }
- DosExit( EXIT_PROCESS, 2); /* Error exit */
- }
-
-
- void main(argc,argv)
- int argc;
- char **argv;
- {
- register char *cp;
- HFILE fd;
- FILE *fi;
- char filnam[FILNAMLEN];
- USHORT handType;
- USHORT handAttrib;
- int i;
- char *inpfile = NULL;
- int j;
- char *seplist = " \t";
- int strcnt;
- char *strfile = NULL;
- long start; /* Start time */
- int (*add)();
- BYTE t2stk[2*STKLEN]; /* Read thread stack */
- BYTE t3stk[2*STKLEN]; /* Write thread stack */
- long time(); /* Time and date in seconds */
-
- DosGetMachineMode((char far *) &pmode);
- flags = 0;
- for(i = 1; i < argc && argv[i][0] == '-'; ++i)
- {
- switch(argv[i][1])
- {
- case 'f':
- case 'i':
- if(i == argc - 1)
- {
- fprintf(stderr,"File name missing after -%c\n",argv[i][1]);
- DosExit( EXIT_PROCESS, 2);
- }
- if(argv[i++][1] == 'i') inpfile = argv[i];
- else strfile = argv[i];
- break;
-
- case '?':
- case 'B':
- case 'E':
- case 'N':
- case 'S':
- case 'd':
- case 'l':
- case 'n':
- case 't':
- case 'v':
- case 'x':
- case 'y':
- for(cp = &argv[i][1]; *cp != '\0'; ++cp)
- {
- switch(*cp)
- {
- case '?':
- usage(1); /* Verbose usage message */
-
- case 'B':
- flags |= BEGLINE;
- break;
-
- case 'E':
- flags |= ENDLINE;
- break;
-
- case 'N':
- grep = grepnull;
- break;
-
- case 'S':
- pmode = 0; /* Force synchronous I/O */
- break;
-
- case 'd':
- flags |= DEBUG;
- break;
-
- case 'l':
- flags |= NAMEONLY;
- break;
-
- case 'n':
- flags |= LINENOS;
- break;
-
- case 't':
- flags |= TIMER;
- break;
-
- case 'v':
- status = 0; /* Assume success */
- flags |= INVERT;
- grep = grepvbuffer;
- break;
-
- case 'x':
- flags |= BEGLINE | ENDLINE;
- break;
-
- case 'y':
- casesen = 0;
- break;
-
- default:
- fprintf(stderr,"-%c ignored\n",*cp);
- break;
- }
- }
- break;
-
- case 'e':
- if(strfile == NULL)
- {
- ++i;
- seplist = ""; /* Allow anything in string */
- goto endfor0;
- }
- /* Drop through to "default" */
-
- default:
- fprintf(stderr,"%s ignored\n",argv[i]);
- break;
- }
- }
- endfor0:
-
- if(i == argc && strfile == NULL) usage(0);
- /* Simple usage message if arg error
- if(flags & TIMER) start = time(NULL);
- /* Get start time if timer on */
- if(pmode) /* Initialize semaphores and thr
- {
- TID threadId;
-
- DosSemClear( &readdone);
- DosSemClear( &writedone);
- DosSemSet( &readpending);
- DosSemSet( &writepending);
- if(DosCreateThread(thread2, &threadId, t2stk + 2*STKLEN) != 0 ||
- DosCreateThread(thread3, &threadId, t3stk + 2*STKLEN) != 0)
- { /* If thread creation fails */
- fprintf(stderr,"Failed to create child threads\n");
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- }
- setmode(fileno(stdout),O_BINARY);
- add = addplain; /* Assume plain string adds */
- if(strfile != NULL) /* If strings from file */
- {
- if(!(flags & BEGLINE)) add = addfancy;
- /* Try to add intelligently */
- if((fd = open(strfile,0)) == -1)
- { /* If open fails */
- fprintf(stderr,"Cannot read strings from %s\n",strfile);
- DosExit( EXIT_PROCESS, 2); /* Print mess
- }
- for(cp = filbuf, j = 0; (j = read(fd,cp,FILBUFLEN*2 - j)) > 0; cp +=
- /* Read strings file into buffer */
- j = cp - filbuf; /* Get total length of buffer */
- close(fd); /* Close strings file */
- filbuf[j] = '\0'; /* Null-terminate the buffer */
- cp = filbuf; /* Set pointer to string list */
- seplist = "\r\n"; /* Only '\r' and '\n' are separators
- }
- else /* Else strings on command line */
- {
- cp = argv[i++]; /* Set pointer to strings */
- j = strlen(cp); /* Get length of strings */
- }
- if((strcnt = (*add)(cp,j,seplist)) == 0)
- { /* If no strings */
- fprintf(stderr,"No search strings\n");
- DosExit( EXIT_PROCESS, 2); /* Print error message and die */
- }
-
- /*
- * Check type of handle for std. out.
- */
- if(DosQHandType(fileno(stdout), &handType, &handAttrib) != 0)
- { /* If error */
- fprintf(stderr,"Standard output bad handle\n");
- /* Print error message */
- DosExit( EXIT_PROCESS, 2); /* Die */
- }
- if(handType != 0 && (handAttrib & ISCOT))
- { /* If handle is console output */
- write1 = write1nobuf; /* Use unbuffered output */
- flush1 = flush1nobuf;
- }
-
- if(strcnt > 1) /* If more than one string */
- {
- if(flags & DEBUG) /* Print debug info maybe */
- {
- fprintf(stderr,"Here are the strings:\n");
- dumpstrings();
- }
- }
- else if(casesen) find = findone; /* Else use findone() */
- if(inpfile != NULL) /* If file list from file */
- {
- flags |= SHOWNAME; /* Always show name of file */
- if((fi = fopen(inpfile,"r")) == NULL)
- { /* If open fails */
- fprintf(stderr,"Cannot read file list from %s\r\n",inpfile);
- /* Error message */
- DosExit( EXIT_PROCESS, 2); /* Error exit */
- }
- while(fgets(filnam,FILNAMLEN,fi) != NULL)
- { /* While there are names */
- filnam[strcspn(filnam,"\r\n")] = '\0';
- /* Null-terminate the name */
- if((fd = openfile(filnam)) == -1) continue;
- /* Skip file if it cannot be opened *
- qgrep(filnam,fd); /* Do the work */
- close(fd); /* Close the file */
- }
- fclose(fi); /* Close the list file */
- }
- else if(i == argc)
- {
- flags &= ~(NAMEONLY | SHOWNAME);
- setmode(fileno(stdin),O_BINARY);
- qgrep(NULL,fileno(stdin));
- }
- if(argc > i + 1) flags |= SHOWNAME;
- for(; i < argc; ++i)
- {
- if((fd = openfile(argv[i])) == -1) continue;
- qgrep(argv[i],fd);
- close(fd);
- }
- (*flush1)();
- if(flags & TIMER) fprintf(stderr,"%ld seconds\n",time(NULL) - start);
- /* Print elapsed time if timer on */
- DosExit( EXIT_PROCESS, status);
- }
-
-
- CPGREPSB.ASM
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CPGREP\CPGREPSB.ASM
-
- ; Created by Microsoft Corp. 1986
- name cpgrepsub
-
- retlen equ 2 ; Size of return address on
-
- dgroup group _data
-
- extrn _casesen: word ; Case-sensitivity flag
- extrn _stringlist: word ; Table of string lists
- extrn _target: byte ; Target string
- extrn _targetlen: word ; Length of target string
- extrn _transtab: byte ; Translation table for _f
-
- ; This segment is puposely word-aligned. See note
- ; in _findlist below.
-
- _text segment word public 'code'
- assume cs:_text, ds:dgroup, es:nothing, ss:dgroup
-
- ; char *findone(buffer,bufend)
- ; char *buffer /* Buffer in which to se
- ; char *bufend; /* End of buffer */
- ;
- ; NOTE: targetlen MUST BE greater than zero
-
- buffer equ word ptr [bp+retlen+2]
- bufend equ word ptr [bp+retlen+4]
-
- EVEN
-
- public _findone
- _findone proc near
- push bp
- mov bp,sp
- push di
- push si
- push es
- push ds ; ES = DS
- pop es
- mov cx,bufend ; CX = end of buffer
- mov di,buffer ; ES:DI = buffer
- sub cx,di ; CX = length of buffer
- jbe sfnomatch ; length less than or equal to z
- mov dx,_targetlen ; DX = length of target
- dec dx ; Decrement it
- sub cx,dx ; target must fit in buffer
- jbe sfnomatch ; (no match if buffer too short)
-
- ; CX = buffer length
- ; DX = target length (minus first character)
- ; ES:DI = buffer pointer
-
- sf0: jcxz sfnomatch ; No match if count zero
- mov si,offset dgroup:_target ; DS:SI = target
- lodsb ; AL = first byte of target
- repne scasb ; Look for first character
- jne sfnomatch ; jump if not found
- mov bx,cx ; BX = buffer length
- mov ax,di ; AX = buffer pointer
- mov cx,dx ; Get count for cmpsb
- or cx,cx ; Zero? (JCXZ doesn't set flag
- je sf1 ; yes, skip compare
- repe cmpsb ; Do string compare
- sf1: mov di,ax ; DI = buffer pointer
- mov cx,bx ; CX = buffer length
- jne sf0 ; Loop if no match
- dec ax ; AX = offset of start of match
- jmp short sf4
-
- sfnomatch:
- xor ax,ax ; No match
- sf4: pop es
- pop si
- pop di
- pop bp
- ret
- _findone endp
-
-
- ; int revfind(s,c,slen)
- ; char *s; /* String to search */
- ; int c; /* Char to search for */
- ; int slen; /* Length of s */
-
- s equ [bp+retlen+2]
- c equ [bp+retlen+4]
- slen equ [bp+retlen+6]
-
- EVEN
-
- public _revfind
- _revfind proc near
- push bp
- mov bp,sp
- push di
- push es
- push ds
- pop es
- mov di,s
- mov ax,c
- mov cx,slen
- jcxz rf1
- std
- repne scasb
- cld
- mov cx,s
- jne rf0
- inc di
- rf0: sub cx,di
- rf1: mov ax,cx
- pop es
- pop di
- pop bp
- ret
- _revfind endp
-
-
- ; int countlines(start,finish)
- ; char *start;
- ; char *finish;
-
- start equ [bp+retlen+2]
- finish equ [bp+retlen+4]
-
- EVEN
-
- public _countlines
- _countlines proc near
- push bp
- mov bp,sp
- push di
- push es
- push ds
- pop es
- xor dx,dx ; Accumulate count in DX
- mov di,start ; ES:DI points to start
- mov cx,finish ; Put length in CX
- sub cx,di
- jbe cl1 ; branch if no bytes
- mov al,0Ah ; Search for linefeeds
- cl0: jcxz cl1 ; Exit loop if count zero
- repne scasb ; Do search
- jne cl1 ; branch if none found
- inc dx ; Increment count
- jmp short cl0 ; Loop
- cl1: mov ax,dx ; Return line count in AX
- pop es
- pop di
- pop bp
- ret
- _countlines endp
-
-
- ; char *findlist(buffer,bufend)
- ; char *buffer; /* Buffer to search */
- ; char *bufend; /* End of buffer */
-
- savesi equ word ptr [bp-2]
- endbyte equ byte ptr [bp-4]
-
- stringnode struc
- s_alt dw ? ; List of alternate portions
- s_suf dw ? ; Pointer to suffix string li
- s_must dw ? ; Length of portion that mus
- stringnode ends
-
- EVEN
-
- flworker dw findsubi, findsub ; Worker dispatch table
-
- public _findlist
- _findlist proc near
- ASSUME DS:DGROUP, ES:NOTHING, SS:DGROUP
-
- push bp
- mov bp,sp
- sub sp,4 ; Make room for local vars
- push di
- push si
- push ds
- pop es
- ASSUME ES:DGROUP
-
- ; We mark the end of our search buffer with 0FFh so that
- ; any comparisons that might run past the end of the buffer
- ; will fail on the 0FFh. We choose 0FFh so that if the
- ; comparison fails on it, it will always appear as though
- ; the string in the buffer is greater that the string in
- ; the search list. This will prevent us from stopping
- ; the search too soon. Of course, we must restore the byte
- ; when we're done.
-
- mov bx,bufend ; BX = end of buffer
- mov al,0FFh ; End marker
- xchg byte ptr [bx],al ; AL = byte after end of buffer
- mov endbyte,al ; Save the byte
-
- mov cx,bx ; CX = end of buffer
- mov si,buffer ; SI = buffer
- sub cx,si ; CX = buffer length
- jbe fl1 ; no match if empty buffer
- mov bx,offset dgroup:_transtab ; BX = translation table addres
-
- mov di,_casesen ; Get flag
- shl di,1 ; Scale to word index
- call cs:flworker[di] ; Call helper
- jc fl1 ; branch if no match
-
- ; We have a match
- ;
- ; SI = offset of first character past end of matched string
- ; savesi = offset of first character past start of matched string
-
- mov ax,savesi ; AX = 1st char past start
- dec ax ; AX = start of matched string
- jmp short fl2
-
- ; We did not find a match
-
- fl1:
- xor ax,ax ; Return NULL
-
- ; Restore end byte before leaving
-
- fl2:
- mov bx,bufend ; BX = end of buffer
- mov dl,endbyte ; DL = end byte
- mov [bx],dl ; Restore byte
-
- pop si
- pop di
- mov sp,bp
- pop bp
- ret
-
- _findlist endp
-
-
- ;*** findsub - case-sensitive worker for _findlist
- ;
- ; This function does most of the work for
- ; case-sensitive multi-string searches.
- ;
- ; ENTRY BX = address of translation table
- ; CX = number of bytes left in buffer
- ; DS:SI = buffer pointer
- ; SS:BP = pointer to stack frame for _findlist
- ; EXIT Carry set
- ; No match
- ; Carry clear
- ; DS:SI = pointer to first character after match
- ; USES AX, CX, DX, DI, SI, Flags
-
- EVEN
-
- public findsub, fs0, fs1, fs2, fs3, fs4, fs5, fs6
- findsub proc near
- ASSUME DS:DGROUP, ES:DGROUP, SS:DGROUP
-
- fs0:
- xor ax,ax ; AH = 0
-
- ; AH = 0
- ; BX = address of translation table
- ; CX = number of bytes left in buffer
- ; SI = buffer pointer
- ; DS = ES = SS = DGROUP
-
- fs1:
- lodsb ; Character in AL
- xlat byte ptr [bx] ; Translate character to index
- or al,al ; Zero means invalid 1st byte
- loopz fs1 ; if so, try next character
-
- ; Either the zero bit is set, meaning the buffer is empty,
- ; or the zero bit is clear, meaning we have a valid first
- ; character. Either way, CX has been decremented.
-
- jz fs6 ; branch if buffer empty
- mov savesi,si ; Save buffer pointer
- shl ax,1 ; Scale to word index
- mov di,ax
- mov di,_stringlist[di] ; DI points to string record
- or di,di ; One byte match? (OR clears c
- jz fs3 ; yes, skip ahead
-
- ; Loop to search for match.
- ; BX = address of translation table
- ; DI = pointer to string record
- ; SI = pointer into buffer
-
- fs2:
- mov cx,[di].s_must ; CX = length of string
- sub di,cx ; DI = pointer to string
- mov dx,si ; Save pointer to start of su
- repe cmpsb ; Strings match?
- ja fs4 ; no, try alternate if follows
- jb fs5 ; no, cannot be in this list
- add di,cx ; DI = pointer to string reco
- mov di,[di].s_suf ; Get pointer to suffix strin
- or di,di ; Is there one? (OR clears car
- jnz fs2 ; yes, keep looking
-
- ; Match found
-
- fs3:
- ret ; no, we have a match
-
- ; Try alternate suffix
-
- fs4:
- add di,cx ; DI = pointer to string reco
- mov di,[di].s_alt ; Get pointer to alternate
- mov si,dx ; Restore SI to start of suff
- or di,di ; Is there one?
- jnz fs2 ; yes, loop
-
- ; Try new first character
-
- fs5:
- mov cx,bufend ; CX = end of buffer
- mov si,savesi ; Restore SI to saved value
- sub cx,si ; CX = length of buffer
- ja short fs0 ; Try next character in buffer
-
- ; No match
-
- fs6:
- stc ; No match
- ret
-
- findsub endp
-
-
- ;*** findsubi - case-insensitive worker for _findlist
- ;
- ; This function does most of the work for
- ; case-insensitive multi-string searches.
- ;
- ; ENTRY BX = address of translation table
- ; CX = number of bytes left in buffer
- ; DS:SI = buffer pointer
- ; SS:BP = pointer to stack frame for _findlist
- ; EXIT Carry set
- ; No match
- ; Carry clear
- ; DS:SI = pointer to first character after match
- ; USES AX, CX, DX, DI, SI, Flags
-
- EVEN
-
- public findsubi
- findsubi proc near
- ASSUME DS:DGROUP, ES:DGROUP, SS:DGROUP
-
- fsi0:
- xor ax,ax ; AH = 0
-
- ; AH = 0
- ; BX = address of translation table
- ; CX = number of bytes left in buffer
- ; SI = buffer pointer
- ; DS = ES = SS = DGROUP
-
- fsi1:
- lodsb ; Character in AL
- xlat byte ptr [bx] ; Translate character to index
- or al,al ; Zero means invalid 1st byte
- loopz fsi1 ; if so, try next character
-
- ; Either the zero bit is set, meaning the buffer is empty,
- ; or the zero bit is clear, meaning we have a valid first
- ; character. Either way, CX has been decremented.
-
- jz fsi7 ; branch if buffer empty
- mov savesi,si ; Save buffer pointer
- shl ax,1 ; Scale to word index
- mov di,ax
- mov di,_stringlist[di] ; DI points to string record
- or di,di ; One byte match? (OR clears c
- jz fsi4 ; yes, skip ahead
-
- ; Loop to search for match.
- ; BX = address of translation table
- ; DI = pointer to string record
- ; SI = pointer into buffer
-
- fsi2:
- mov cx,[di].s_must ; CX = length of string
- sub di,cx ; DI = pointer to string
- mov dx,si ; Save pointer to start of su
- fsi3: lodsb ; Byte in AL, SI = SI + 1
- mov ah,[di] ; Byte in AH, DI = DI + 1
- inc di
- or ax,2020h ; Fold bytes onto lower case
- cmp al,ah ; Compare bytes
- loope fsi3 ; Loop while same
- ja fsi5 ; no, try alternate if follows
- jb fsi6 ; no, cannot be in this list
- add di,cx ; DI = pointer to string reco
- mov di,[di].s_suf ; Get pointer to suffix strin
- or di,di ; Is there one? (OR clears car
- jnz fsi2 ; yes, keep looking
-
- ; Match found
-
- fsi4:
- ret ; no, we have a match
-
- ; Try alternate suffix
-
- fsi5:
- add di,cx ; DI = pointer to string reco
- mov di,[di].s_alt ; Get pointer to alternate
- mov si,dx ; Restore SI to start of suff
- or di,di ; Is there one?
- jnz fsi2 ; yes, loop
-
- ; Try new first character
-
- fsi6:
- mov cx,bufend ; CX = end of buffer
- mov si,savesi ; Restore SI to saved value
- sub cx,si ; CX = length of buffer
- ja short fsi0 ; Try next character in buffer
-
- ; No match
-
- fsi7:
- stc ; No match
- ret
-
- findsubi endp
-
-
- ; int strnspn(s,t,n)
- ; char *s; /* String to search */
- ; char *t; /* Target list */
- ; int n; /* Length of s */
-
- s equ word ptr [bp+retlen+2]
- t equ word ptr [bp+retlen+4]
- n equ word ptr [bp+retlen+6]
-
- EVEN
-
- public _strnspn
- _strnspn proc near
- push bp
- mov bp,sp
- push di
- push si
- push ds
- pop es
- cld
- mov bx,t ; BX = t
- mov di,bx ; DI = t
- xor al,al ; Search for 0 byte
- mov cx,0FFFFh
- repne scasb
- dec di ; Back up to 0
- sub di,bx ; DI = length of t
- jz spn1 ; Done if length of t is 0
- mov dx,di ; DX = length of t
- mov si,s ; SI = s
- mov cx,n ; CX = length of s
- jcxz spn1 ; Check for null string
- push bp
- spn0: lodsb ; AL = next char in s
- mov bp,cx ; BP = length of s
- mov cx,dx ; CX = length of t
- mov di,bx ; DI = t
- repne scasb ; Scan until match found
- mov cx,bp ; CX = length of s
- loope spn0 ; Loop if match found
- pop bp
- je spn1 ; Skip ahead if end of s reache
- dec si ; Back up one char
- spn1: sub si,s ; SI = length of prefix
- mov ax,si ; AX = length of prefix
- pop si
- pop di
- pop bp
- ret
- _strnspn endp
-
-
- ; int strncspn(s,t,n)
- ; char *s; /* String to search */
- ; char *t; /* Target list */
- ; int n; /* Length of s */
-
- EVEN
-
- public _strncspn
- _strncspn proc near
- push bp
- mov bp,sp
- push di
- push si
- push ds
- pop es
- cld
- mov bx,t ; BX = t
- mov di,bx ; DI = t
- xor al,al ; Search for 0 byte
- mov cx,0FFFFh
- repne scasb
- dec di ; Back up to 0
- sub di,bx ; DI = length of t
- mov ax,n ; Assume length of t is 0
- jz cspn2 ; Done if length of t is 0
- mov dx,di ; DX = length of t
- mov si,s ; SI = s
- mov cx,ax ; CX = length of s
- jcxz cspn1 ; Check for null string
- push bp
- cspn0: lodsb ; AL = next char in s
- mov bp,cx ; BP = length of s
- mov cx,dx ; CX = length of t
- mov di,bx ; DI = t
- repne scasb ; Scan until match found
- mov cx,bp ; CX = length of s
- loopne cspn0 ; Loop if match not found
- pop bp
- jne cspn1 ; Skip ahead if end of s reac
- dec si ; Back up one char
- cspn1: sub si,s ; SI = length of prefix
- mov ax,si ; AX = length of prefix
- cspn2: pop si
- pop di
- pop bp
- ret
- _strncspn endp
-
-
- ; cmpsen - case-sensitive comparison
- ;
- ; ENTRY DS:SI = buffer
- ; ES:DI = string
- ; CX = length of string
- ; EXIT CX = length of string unused
- ; DI = unused portion of string
- ; Z set
- ; match found
- ; Z clear
- ; no match
- ; USES CX, DI, SI, Flags
-
- EVEN
-
- cmpsen proc near
- repe cmpsb
- ret
- cmpsen endp
-
-
- ; cmpinsen - case-insensitive comparison
- ;
- ; ENTRY DS:SI = buffer
- ; ES:DI = string
- ; CX = length of string
- ; EXIT CX = length of string unused
- ; DI = unused portion of string
- ; Z set
- ; match found
- ; Z clear
- ; no match
- ; USES AX, CX, DI, SI, Flags
-
- EVEN
-
- cmpinsen proc near
- cmpi0: lodsb ; Byte in AL, SI = SI + 1
- mov ah,[di] ; Byte in AH, DI = DI + 1
- inc di
- or ax,2020h ; Fold bytes onto lower case
- cmp al,ah ; Compare bytes
- loope cmpi0 ; Loop while same
- ret
- cmpinsen endp
-
-
- ; void matchstrings(s1,s2,len,nmatched,leg)
- ; char *s1; /* First string */
- ; char *s2; /* Second string */
- ; int len; /* Length */
- ; int *nmatched; /* Number of bytes matched */
- ; int *leg; /* Less than, equal, greate
-
- cm_s1 equ word ptr [bp+retlen+2]
- cm_s2 equ word ptr [bp+retlen+4]
- cm_len equ word ptr [bp+retlen+6]
- cm_nmatched equ word ptr [bp+retlen+8]
- cm_leg equ word ptr [bp+retlen+10]
-
- EVEN
-
- public _matchstrings
- _matchstrings proc near
- ASSUME DS:DGROUP, ES:NOTHING, SS:DGROUP
-
- push bp
- mov bp,sp
- push di
- push si
- push ds
- pop es
- ASSUME ES:DGROUP
- mov di,cm_s2
- mov si,cm_s1
- mov cx,cm_len
- cmp _casesen,0
- je cm0
- call cmpsen
- jmp short cm1
- cm0: call cmpinsen
- cm1: mov bx,cm_leg
- mov word ptr [bx],0 ; Assume equal
- jz cm2 ; yes, skip ahead
- mov word ptr [bx],1 ; Assume greater than
- jg cm1a ; yes, skip ahead
- mov word ptr [bx],-1 ; Less than
- cm1a: dec si
- cm2: sub si,cm_s1
- mov bx,cm_nmatched
- mov [bx],si
- pop si
- pop di
- pop bp
- ret
-
- _matchstrings endp
-
-
- ; int strcmp(s1,s2)
- ; char *s1; /* First string */
- ; char *s2; /* Second string */
-
- public _strcmp
- _strcmp proc near
- push bp
- mov bp,sp
- push di
- push si
- push ds
- pop es
- mov si,[bp+4] ; DS:SI = s1
- mov di,[bp+6] ; ES:DI = s2
- sc0: lodsb ; AL = *s1++
- scasb ; AL - *s2++
- jne sc1 ; branch if no match
- or al,al ; End of s1?
- jne sc0 ; no, loop
- cbw ; AX = 0
- jmp short sc2 ; Exit
- sc1: mov ax,1 ; Assume s1 > s2
- jg sc2 ; yes, branch
- neg ax ; s1 < s2
- sc2: pop si
- pop di
- pop bp
- ret
- _strcmp endp
-
-
- public _bpt
- _bpt proc near
- int 3
- ret
- _bpt endp
-
- _text ends
-
- _data segment word public 'data'
- _data ends
-
- end
-
-
- DATA.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\OPENDLG\DATA.C
-
- /***************************************************************************\
- * DATA.C -- This file contains per process global variables
- * Created by Microsoft Corporation, 1989
- \***************************************************************************/
-
- #define NO_DOS
- #define NO_GPI
- #include "tool.h"
-
- /*
- This library uses a NON SHARED DATA selector. This means each
- process using the library gets its own selector, and also that
- values cannot be shared and must be recreated for each process.
- */
-
- HMODULE vhModule; /* Library module handle */
- HHEAP vhheap; /* Library heap */
-
- PSTR vrgsz[CSTRINGS]; /* Array of pointer to our strings (indexed
- by IDS_... */
-
-
- DCALC.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CALC\DCALC\DCALC.C
-
- /****************************** Module Header ******************************\
- * Module Name: dcalc.c - Dialog form of the Calc application
- *
- * OS/2 Presentation Manager version of Calc, ported from Windows version
- *
- * Created by Microsoft Corporation, 1989
- *
- \***************************************************************************/
-
- #define INCL_DEV
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSNLS
- #define INCL_ERRORS
- #define INCL_WINBUTTONS
- #define INCL_WINCLIPBOARD
- #define INCL_WINDIALOGS
- #define INCL_WINFRAMEMGR
- #define INCL_WININPUT
- #define INCL_WINMENUS
- #define INCL_WINMESSAGEMGR
- #define INCL_WINPOINTERS
- #define INCL_WINSWITCHLIST
- #define INCL_WINTRACKRECT
- #define INCL_WINWINDOWMGR
- #include <os2.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include "dcalc.h"
-
- /************* GLOBAL VARIABLES */
-
- char chLastKey, currkey;
- char szCalcClass[] = "Calculator";
- char szTitle[30];
- char szreg1[20], szreg2[20], szmem[20], szregx[20];
- /* hope 20 is enough for kanji error string */
- char szErrorString[20], szPlusMinus[2];
- short charwidth, charheight;
- int aspectx, aspecty, nchszstr;
- extern BOOL fError = FALSE;
- BOOL fValueInMemory = FALSE;
- BOOL fMDown = FALSE;
- UCHAR mScan = 0;
-
- #define TOLOWER(x) ( (((x) >= 'A') && ((x) <= 'Z')) ? (x)|0x20 : (x))
- #define WIDTHCONST 28
- #define CXCHARS 37
- #define CYCHARS 13
-
- HAB hab;
- HDC hdcLocal; /* Local used for button bitmap */
- HPS hpsLocal;
- HDC hdcSqr; /* Sqr used for square-root bitmap */
- HPS hpsSqr;
- HBITMAP hbmLocal, hbmSqr;
- HMQ hmqCalc = NULL;
-
- HWND hwndCalc = NULL,
- hwndMenu = NULL;
-
- HPOINTER hptrFinger = NULL,
- hptrIcon = NULL;
-
- DEVOPENSTRUC dop = /* used by DevOpenDC */
- {
- NULL, "DISPLAY", NULL, NULL, NULL, NULL, NULL, NULL, NULL
- };
-
- static char bButtonValues[] = /* Button values */
- {
- 0xBC, 0xBB, 0xBA, 0xB9, '0', '1', '2', '3', '4',
- '5', '6', '7', '8', '9', '.', '/', '*', '-',
- '+', 'q', '%', 'c', '=', 0xB1, NULL
- };
-
- /************* PROCEDURE DECLARATIONS */
-
- MPARAM EXPENTRY AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);
- BOOL CalcInit(VOID);
- VOID CalcPaint( HWND, HPS);
- MRESULT EXPENTRY fnDlgCalc(HWND, USHORT, MPARAM, MPARAM);
- VOID cdecl main(VOID);
- VOID DataXCopy( VOID);
- VOID DataXPaste( VOID);
- VOID DrawNumbers( HPS);
- VOID Evaluate(BYTE);
- VOID InitCalc( VOID);
- BOOL InterpretChar( CHAR);
- VOID ProcessKey(HWND, WPOINT *);
- char Translate(WPOINT *);
- VOID UpdateDisplay( VOID);
-
-
-
- /********************************************************************
- Write the appropriate number or error string to the display area
- and mark memory-in-use if appropriate.
- */
-
- BYTE aszDisplayBuff[20];
-
- VOID UpdateDisplay()
- {
- strcpy(aszDisplayBuff, fError? "Error" :szreg1);
- strcat(aszDisplayBuff, fValueInMemory? " M" : " ");
-
- WinSetDlgItemText(hwndCalc, TXT_RESULT_DISPLAY, aszDisplayBuff);
- }
-
-
- /**********************************************************************
- Display helpful info
- */
-
- MPARAM EXPENTRY AboutDlgProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- if (msg == WM_COMMAND)
- {
- WinDismissDlg(hwnd, TRUE);
- return(MPFROMSHORT(TRUE));
- }
- else return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- }
-
-
- /**********************************************************************
- General initialization
- */
-
- BOOL CalcInit()
- {
- hab = WinInitialize(0);
-
- hmqCalc = WinCreateMsgQueue( hab, 0);
-
- return(TRUE);
- }
-
- /**********************************************************************
- main procedure
- */
-
- VOID cdecl main()
- {
- QMSG qmsg;
-
- if (!CalcInit()) { /* general initialization *
- WinAlarm(HWND_DESKTOP, 0xffff);
- goto exit;
- }
-
- WinLoadDlg(HWND_DESKTOP, HWND_DESKTOP, fnDlgCalc, NULL, CALCDLG, NULL);
-
- if (hwndCalc)
- while (WinGetMsg( hab, (PQMSG)&qmsg, NULL, 0, 0))
- WinDispatchMsg( hab, (PQMSG)&qmsg);
-
- exit: /* clean up */
-
- if (hwndMenu) WinDestroyWindow(hwndMenu);
-
- WinDestroyMsgQueue(hmqCalc);
- WinTerminate(hab);
-
- DosExit(EXIT_PROCESS, 0); /* exit without error */
- }
-
-
- /*************************************************************************
- Calc Dialog Window Procedure
- */
-
-
- USHORT idProcess, idThread;
- SWCNTRL swc;
- HSWITCH hsw;
- USHORT usWidthCalc, usHeightCalc;
-
- MRESULT EXPENTRY fnDlgCalc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- RECTL rectl;
- BOOL fClip;
- USHORT fi, idCtrl;
- MRESULT mresult;
- USHORT afSWP;
- PSWP pswp;
-
- static BOOL fMinimized;
-
-
- switch (msg)
- {
- case WM_INITDLG:
-
- /* Set up the global state assumed by the dialog.
- */
- hwndCalc = hwnd;
- hwndMenu = WinLoadMenu(hwnd, NULL, IDR_CALC);
-
- fMinimized = FALSE;
-
- hptrFinger = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDP_FINGER);
- hptrIcon = WinLoadPointer(HWND_DESKTOP, (HMODULE)NULL, IDR_CALC);
-
- WinSetWindowULong(hwndCalc, QWL_STYLE,
- FS_ICON | WinQueryWindowULong(hwndCalc, QWL_STYLE)
- );
-
- WinSendMsg(hwndCalc, WM_SETICON, (MPARAM) hptrIcon, 0L);
- WinSendMsg(hwndCalc, WM_UPDATEFRAME, (MPARAM) 0L, 0L);
-
- WinQueryWindowRect(hwndCalc, &rectl);
- usWidthCalc= (SHORT) (rectl.xRight - rectl.xLeft);
- usHeightCalc= (SHORT) (rectl.yTop - rectl.yBottom);
-
- WinQueryWindowProcess(hwndCalc, &idProcess, &idThread);
-
- WinLoadString(NULL, NULL, 1, 30, (PSZ)szTitle);
- WinLoadString(NULL, NULL, 2, 20, (PSZ)szErrorString);
- WinLoadString(NULL, NULL, 3, 2, (PSZ)szPlusMinus);
-
- strcpy(swc.szSwtitle, szTitle);
- swc.hwnd = hwndCalc;
- swc.hwndIcon = hptrIcon;
- swc.hprog = (ULONG)NULL;
- swc.idProcess = idProcess;
- swc.idSession = (USHORT)0;
- swc.uchVisibility = SWL_VISIBLE;
- swc.fbJump = SWL_JUMPABLE;
- hsw = WinAddSwitchEntry((PSWCNTRL)&swc);
-
- InitCalc(); /* arithmetic initialization *
-
- WinSetActiveWindow(HWND_DESKTOP, hwndCalc);
-
- WinSetFocus(HWND_DESKTOP, hwndCalc);
-
- break;
-
- case WM_MINMAXFRAME:
-
- pswp= PVOIDFROMMP(mp1);
-
- if (pswp->fs & SWP_MINIMIZE) fMinimized= TRUE;
- else
- if (pswp->fs & SWP_RESTORE) fMinimized= FALSE;
-
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
-
- break;
-
- case WM_DESTROY:
-
- WinDestroyPointer(hptrIcon ); hptrIcon = NULL;
- WinDestroyPointer(hptrFinger); hptrFinger= NULL;
-
- break;
-
- case WM_INITMENU:
-
- fClip = FALSE;
-
- if (WinOpenClipbrd(NULL))
- {
- fClip = WinQueryClipbrdFmtInfo(NULL, CF_TEXT, (USHORT FAR *)&fi);
- WinCloseClipbrd(NULL);
- }
-
- WinSendMsg((HWND)mp2, MM_SETITEMATTR,
- (MPARAM) MAKELONG(CMD_PASTE, TRUE),
- (MPARAM) MAKELONG(MIA_DISABLED, fClip ? 0 : MIA_DISABLED))
- break;
-
- case WM_ADJUSTWINDOWPOS:
-
- mresult= WinDefDlgProc(hwnd, msg, mp1, mp2);
-
- if (fMinimized) return(mresult);
-
- afSWP= (pswp= (PSWP) mp1)->fs;
-
- if ( afSWP & (SWP_SIZE | SWP_MAXIMIZE)
- && !(afSWP & SWP_MINIMIZE)
- )
- {
- pswp->y += pswp->cy - usHeightCalc;
- pswp->cx = usWidthCalc;
- pswp->cy = usHeightCalc;
- }
-
- return(mresult);
-
-
- case WM_COMMAND:
-
- fError = FALSE;
-
- idCtrl= SHORT1FROMMP(mp1);
-
- if ( SHORT1FROMMP(mp2) == BN_CLICKED
- && idCtrl >= BUTTON_MC
- && idCtrl <= BUTTON_CHANGE_SIGN
- )
- {
- Evaluate(bButtonValues[idCtrl-BUTTON_MC]);
- UpdateDisplay();
- }
- else
- switch(idCtrl)
- {
- case CMD_COPY:
- DataXCopy(); /* copy to clipboard */
- break;
- case CMD_PASTE:
- DataXPaste(); /* paste from clipboard
- break;
- case CMD_EXIT:
- WinPostMsg(hwndCalc, WM_QUIT, 0L, 0L);
- break;
- case CMD_ABOUT:
- WinDlgBox(HWND_DESKTOP, hwndCalc, (PFNWP)AboutDlgProc, NULL,
- 1, (PSZ)NULL);
- break;
- }
- break;
-
- case WM_CLOSE:
- WinPostMsg(hwndCalc, WM_QUIT, 0L, 0L);
- break;
-
- case WM_CONTROLPOINTER:
- if (!fMinimized) return(hptrFinger);
- else return(WinDefDlgProc(hwnd, msg, mp1, mp2));
-
- case WM_MOUSEMOVE:
- if (!fMinimized) WinSetPointer(HWND_DESKTOP, hptrFinger);
- break;
-
- case WM_BUTTON1DOWN:
-
- return(WinDefDlgProc(hwnd, WM_TRACKFRAME, (MPARAM) TF_MOVE, mp2));
-
- break;
-
- case WM_CHAR:
-
- fError = FALSE;
- if (SHORT1FROMMP(mp1) & KC_KEYUP)
- {
- if (CHAR4FROMMP(mp1) == mScan)
- fMDown = FALSE; /* 'm' key went up */
- }
- else
- {
- if (SHORT1FROMMP(mp1) & KC_CHAR)
- {
- if (InterpretChar((UCHAR)(ULONG)(mp2)))
- {
- UpdateDisplay();
- }
- else
- {
- if (((UCHAR)(ULONG)(mp2)== 'm') || ((UCHAR)
- {
- mScan = CHAR4FROMMP(mp1); /
- fMDown = TRUE;
- }
- }
- }
- }
- break;
-
-
- case WM_ERASEBACKGROUND:
- if (WinQueryWindowULong(hwnd, QWL_STYLE) & WS_MINIMIZED)
- WinValidateRect(hwnd, (PRECTL) mp2, TRUE);
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- break;
-
- case WM_SETFOCUS:
- if ((HWNDFROMMP(mp1)==hwndCalc) && !mp2);
- fMDown = FALSE; /* since we are losing foc
-
- default:
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0L);
- }
-
-
- /*************************************************************************
- translate & interpret keys (ie. locate in logical keyboard)
- */
-
- BOOL InterpretChar(ch)
- register CHAR ch;
- {
- BOOL fDone;
- CHAR *chstep;
-
- fDone = FALSE;
- chstep = bButtonValues;
- switch (ch)
- {
- case 'n':
- ch = szPlusMinus[0];
- break;
- case 27: /* xlate Escape into 'c' */
- ch = 'c';
- break;
- case '\r': /* xlate Enter into '=' */
- ch = '=';
- break;
- }
-
- if (fMDown) /* Do memory keys */
- {
- switch (ch)
- {
- case 'c':
- case 'C':
- ch = '\274';
- break;
- case 'r':
- case 'R':
- ch = '\273';
- break;
- case '+':
- ch = '\272';
- break;
- case '-':
- ch = '\271';
- break;
- }
- }
-
- while (!fDone && *chstep)
- {
- if (*chstep++ == ch)
- fDone = TRUE; /* char found in logical keyboard */
- }
-
- if (fDone)
- {
- Evaluate(ch);
- }
-
- return (fDone);
- }
-
-
- DDEML.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DDEML.C
-
- /****************************** Module Header ******************************\
- * Module Name: DDE.C
- *
- * DDE Manager main module - Contains all exported Dde functions.
- *
- * Created: 12/12/88 Sanford Staab
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- * 4/5/89 sanfords removed need for hwndFrame registration param
- * 6/5/90 sanfords Fixed callbacks so they are blocked during
- * timeouts.
- * Fixed SendDDEInit allocation bug.
- * Added hApp to ConvInfo structure.
- * Allowed QueryConvInfo() to work on server hCo
- * Added FindFrame() to provide an hApp for Serv
- * hConvs.
- * 6/14/90 sanfords Altered hDatas so they will work when shared
- * between threads of the same process. Also
- * added optimization to only have the hsz
- * in the hData for local conversations.
- * 6/21/90 sanfords Renamed APIs to Dde....
- * Finished DdeAppNameServer() implementation.
- *
- \***************************************************************************/
-
- #include "ddemlp.h"
- #include "version.h"
-
- /****** Globals *******/
-
- HMODULE hmodDmg = 0; /* initialized by LoadProc on DLL initialization
- PFNWP lpfnFrameWndProc = 0; /* system Frame window procedure */
-
- HHEAP hheapDmg = 0; /* main DLL heap */
-
- PHATOMTBL aAtbls;
- USHORT cAtbls = 0;
- USHORT iAtblCurrent = 0;
- USHORT cMonitor = 0;
- DOSFSRSEM FSRSemDmg; /* used to protect globals */
- USHORT cAtoms = 0; /* for debugging! */
-
- PAPPINFO pAppInfoList = NULL; /* registered thread data list */
- USHORT usHugeShift; /* for huge segment support */
- USHORT usHugeAdd; /* for huge segment support */
- COUNTRYCODE syscc;
-
- BOOL fInSubset(PCQDATA pcqd, ULONG afCmd);
-
- /* PUBDOC START *\
- DLL overview:
-
- This DLL supports standard DDE communication on behalf of its client
- applications. It is compatable with most existing DDE programs. The
- API interface features object-like abstractions that allow its implementation
- on and across a variety of platforms.
-
- Main features:
-
- * HSZ manager: Allows more efficient handling of numerous character
- strings without the limitations of the atom manager.
-
- * HDATA manager: Data container objects allow easy filling, accessing
- and reuse of huge amounts of data and allow a
- server to efficiently support several clients.
-
- * Controled initiates: Supports client to multi-server initiates and
- allows a client application to pick and choose which
- conversations to keep.
-
- * Debugging support: Allows monitoring applications to be easily written
- and provides readable error messages.
-
- * Huge Segment support: Exports a useful huge segment copy function and
- properly handles huge data transfers.
-
- * Synchronous communication: Clients may use a very simple form of
- transaction processing that requires little application
- support.
-
- * Asynchronous communication: Clients may opt to use queued transfers
- freeing them to do other tasks in parellel with DDE.
-
- * Callback control: Applications may selectively suspend DLL callbacks
- to themselves when in time critical sections. Selected
- conversations can be blocked while being serviced so
- others can be processed by the same thread.
-
- * registration notification: All applications using this DLL are notified
- whenever any other application registers or unregisters
- itself with this DLL. This enables nameserver support
- for DDE.
-
- * multiple DDE entity support: An application can register itself with
- any number of application names and can change what
- application names it responds to at any time. Each
- registered thread is a seperate DDE entity.
-
- * advise loop control: Advise loops are tracked by the DLL, however
- server applications have complete control over
- advise loop initiation.
-
- * network agent support: Special agent applications can register with this
- DLL to represent multiple applications on other machines
- or platforms.
-
- API specifications:
-
- Callback function:
-
- EXPENTRY Callback(
- HCONV hConv, // holds server conversation handle in most cases
- HSZ hszTopic, // holds topic hsz for transaction
- HSZ hszItem, // holds item or application hsz for transaction
- USHORT usFormat, // holds data format when applicable
- USHORT usType, // holds transaction type code
- HDMGDATA hDmgData); // holds incomming data in most cases
-
- This is the definition of the data call-back function that an
- application must export so that the DDE can initiate interaction
- with the application when necessary. This function is refered to in
- the DdeInitialize() call.
-
- The application callback function is very much like a PM window
- procedure for DDE. The usType specifies the type of transaction being
- done. By ANDing this parameter with XCLASS_MASK and comparing the
- result with the XCLASS_ constants, the transaction return type
- expected can be classified.
-
- XTYP_ constants also may contain the XTYPF_NOBLOCK flag. The presence
- of this flag indicates that the CBR_BLOCK return value from the callback
- will not be honored by the DDE. (see DdeEnableCallback() for more
- information on this concept.)
-
- The various transactions are explained below:
-
-
- -----XCLASS_NOTIFICATION class:
- These are strictly notification messages to an application. The return
- value is ignored except in the case of CBR_BLOCK. (if the notification
- is blockable)
-
- XTYP_RTNPKT
-
- This transaction is sent to agent applications. hDmgData contains a
- packet to send to the agent who's handle is in the hszItem parameter.
-
- XTYP_REGISTER
-
- Another server name has just been registered with the DLL application
- name server. hszItem is set to the application name being
- registered. If this is NULL, an application has registered itself as
- WILD. hDmgData is set to the application handle that registered.
- This is not blockable by CBR_BLOCK because no hConv is
- associated with it. Only if all callbacks are disabled is this
- transaction blocked.
-
- XTYP_UNREGISTER
-
- Another server application has just unregistered a name with this
- DLL. hszItem is set to the application name being unregistered.
- hDmgData is set to the app handle of the unregistering application.
- This is not blockable by CBR_BLOCK because no hConv is associated
- with it. Only if all callbacks are disabled is this transaction
- blocked.
-
- XTYP_INIT_CONFIRM
-
- Sent to let a server know that a conversation on application hszItem
- and Topic hszTopic has been established on hConv. hConv uniquely
- identifies this conversation from the server's prospective. This
- call cannot be blocked because it is part of the DDE initiate
- sequence. This callback is generated by the results of XTYP_INIT and
- XTYP_WILDINIT callbacks.
-
- XTYP_TERM
-
- This is a notification telling a server application that a
- conversation has been terminated. hConv is set to identify which
- conversation was terminated.
-
- XTYP_ADVSTOP
-
- This notifies a server that an advise loop is stopping. hszTopic,
- hszItem, and usFormat identify the advise loop within hConv.
-
- XTYP_XFERCOMPLETE
-
- This notifictaion is sent to a client when an asynchronous data
- DdeClientXfer() transaction is completed. hDmgData is the client
- queue ID of the completed transaction. hConv is the client
- conversation handle.
-
- XTYP_MONITOR
-
- This notifies an app registered as DMGCMD_MONITOR of DDE data that is
- being transmitted. hDmgData contains a text string representing the
- transaction suitable for printing on a terminal, file, or window.
- Note that this monitors ALL DDE communication and may be extensive.
- This call cannot be delayed by disabled callbacks. This transaction
- is not blockable.
-
- XTYP_ACK
-
- This notifies a server that it has received an acknowledge from data
- it has sent a client. The hConv, topic, item, and format are set
- apropriately. LOUSHORT(hDmgData) will contain the dde flags from the
- ack.
-
- -----XCLASS_DATA class:
-
- Transactions in this class are expected to return an HDMGDATA or 0 as
- apropriate.
-
- XTYP_PKT
-
- This transaction is sent to agent applications. hDmgData contains a
- packet to send. hszItem contains the agent handle to send the data
- to. hConv is set to the associated conversation handle. The return
- packet received from the partner agent should be returned. This
- call is blockable.
-
- If blocked, the conversation will be unblocked and processed by
- DdeProcessPkt() when the return packet is received. It is a good
- idea for the agent to remember the hConv parameter in case the return
- packet does not arrive within a reasonable amount of time via
- XTYP_RTNPKT. If an agent determines that it wishes to kill a
- conversation, it should call DdeDisconnect().
-
- XTYP_REQUEST
- XTYP_ADVREQ
-
- Data is being requested from a server application. The function
- should create a hDmgData using the DdePutData() function and
- return it. XTYP_ADVREQ origonates from a DdePostAdvise() call
- while XTYP_REQUEST origonates from a client data request.
-
- XTYP_WILDINIT
-
- This is asking a DDE server permission to make multiple connections
- with a specific client.
-
- hszItem may be the application name the client is requesting or it
- may be NULL indicating a wild application name. hszTopic may be the
- Topic requested or NULL indicating a wild topic. If not NULL,
- hDmgData contains a CONVCONTEXT structure. All other parameters are
- 0 or NULL.
-
- For local initiates, (initiates with the server application itself)
- The server should return a 0 terminated (ie hszApp = hszTopic = 0)
- array of HSZPAIR structures using DdePutData() and
- DdeAddData(). Each hsz pair represents an app/topic the server
- wishes to support. Each created conversation will result in an
- XTYP_INIT_CONFIRM notification. If 0 is returned, no connections are
- made with the requesting client. This call is made even if callbacks
- are disabled due the the synchronous nature of DDE initiates. This
- callback cannot be blocked by returning CBR_BLOCK.
-
- Agent applications may also process this transaction as a
- representative initiate. The agent is expected to package this
- transaction using DdeCreateInitPkt() and broadcast it to all
- apropriate agents along its communication channel. It then must
- collect the return packets and for each packet and call
- DdeProcessPkt(). Representative initiates are synchronous in that
- the agent cannot return from this callback until all initiate return
- packets are returned. Representative initiates do NOT result in any
- XTYP_INIT_CONFIRM notifications to the agent. The agent is then free
- to process this transaction for local connections as described.
-
- -----XCLASS_BOOL class:
-
- Transactions in this class expect a BOOL return of TRUE or FALSE.
-
- XTYP_INIT
-
- This is a query asking a DDE server permission to connect to a
- specific client. hszItem is set to the Application name. hszTopic
- is set to the topic name. hDmgData if not NULL, contains CONVCONTEXT
- data. All other parameters are 0 or NULL. A TRUE return value
- allows the Dde to start up a server on the app/topic specified.
- This will result in an XTYP_INIT_CONFIRM callback. This call is made
- even if callbacks are disabled due the the synchronous nature of DDE
- initiates.
-
- Agent applications may process this transaction as a representative
- transaction. The agent is expected to package this transaction using
- DdeCreateInitPkt() and broadcast it to all apropriate agents along
- its communication channel. It then must collect the return packets
- and for each packet call DdeProcessPkt(). This will NOT result in
- any XTYP_INIT_CONFIRM notifications to the agent. The agent is then
- free to process this transaction for local connections.
-
- A FALSE return implies no local initiate permissions are granted.
-
- XTYP_ADVSTART
-
- This transaction requests permission to start a DDE advise loop with
- a server. The hszTopic, hszItem, and usFormat identify the advise
- loop. If FALSE is returned, the advise loop will not be started.
-
- -----XCLASS_FLAGS Class:
-
- Transactions in this class have hDmgData set. An application should
- use the DLL Data functions to extract the data from hDmgData. The
- return value should be the DDE fsStatus flags the app desires to
- return to the client application. If DDE_FACK is set, DDE_FBUSY and
- DDE_FNOTPROCESSED are ignored.
-
- The only flags the Dde expects to be returned are:
- DDE_FACK
- DDE_FBUSY
- DDE_FNOTPROCESSED
- any DDE_APPSTATUS bits
-
- All other bits will be stripped out by the Dde before sending an
- ack message.
-
- A 0 return is equivalent to DDE_NOTPROCESSED.
-
- XTYP_EXEC
-
- hDmgData contains an execute string from a client. hConv, hszTopic,
- hszItem are set. If the WM_DDE_EXECUTE message received had the same
- string for the itemname as for the data, hszItem will be 0L. This
- provides for EXCEL EXECUTE compatibility without requireing the
- creation of an HSZ for the data string. Applications are advised to
- ignore the hszItem parameter for execute transactions since newer DDE
- specifications ignore this value.
-
- XTYP_POKE
-
- Similar to XTYP_EXEC but hDmgData contains data poked to the server.
-
- XTYP_ADVDATA - advise data for a client!
-
- Note that XTYP_ADVDATA is for advise loop data intended for the
- CLIENT not the server. If the advise loop in progress is of the
- NODATA type, hDmgData will be 0.
-
- -----Agent Transfers:
-
- A DDE agent application is one which registers itself with the
- DMGCMD_AGENT flag. Agent applications represent any number of other
- applications across its communications channel. Agent applications
- are only allowed to communicate locally with other non-agent
- applications. This prevents communication loops from forming across
- communication channels. Any number of agents may register with the
- DLL but each agent should represent a different communication
- channel, one which is orthogonal to all other agents. It is the
- users responsability to only start up orthogonal agents.
-
- Agents are responsible for handling and updating any DDE nameservers
- associated with their communicaton channels. Since agent
- applications can converse directly with non-agent applications, they
- can set up advise loops on the SysTopic/Topics items of local
- applications to update the nameserver for the communication channel
- if they wish to support DDE topics. This may be impossible with some
- DDE applications which either do not support the SysTopic/Topics item
- or which have an unenumerable set of topics they support. For
- application name servers the DdeAppNameServer() function is
- provided to give agents a local application name server from which to
- draw on.
-
- In general, an agent administers two classes of conversations. One
- is direct conversations with itself and local non-agent applications.
- These transactions would be handled by the agent exactly like any
- non-agent application would handle them.
-
- The other class is representative conversations which the agent
- passes over its communication channel. In general, representative
- conversation callbacks to the agent are only XTYP_PKT or XTYP_RTNPKT
- type transactions or specially handled initiate transactions.
-
- Agent applications are responsible for providing a unique ULONG agent
- handle for every agent it is communicating with on its communication
- channel. The handle is provided by the agent whenever it calls
- DdeProcessPkt(). Agent handles need not be global to the channel
- since only the agent that created the handle will be expected to use
- it. Agent handles should not change over the life of a conversation.
-
- Should it be necessary to allow agents to alter or convert packet
- data, the format of the packets can be documented later.
-
- To show how an agent would handle its callback function, the
- following pseudo code is offered as a model:
-
- ReceivePkt(pBits, cb, hAgentFrom) \\ gets called when a packet arrives
- {
- hPkt = DdePutData(pBits, cb, 0, 0, 0, 0);
- if (hDmgData = ProcessPkt(hPkt, hAgentFrom))
- PassPkt(hDmgData, hAgentFrom); \\ agent function to send pkt
- }
-
- AgentCallback(hConv, hszTopic, hszItem, usFormat, usType, hDmgData)
- {
- switch (usType) {
- case XTYP_INIT:
- case XTYP_WILDINIT:
- \\
- \\ process representative initiates
- \\
- QueryInterestedAgents(hszApp, hszTopic, pAgents);
- hDmgData = DdeCreateInitPkt(hszTopic, hszItem, hDmgData);
- BroadcastPkt(hDmgData, pAgents);
- \\
- \\ agent blocks here till all are in or timeout.
- \\ Packets get sent to ReceivePkt()
- \\
- CollectRtnPkts(pAgents);
- \\
- \\ now agent does his own processing of local inits.
- \\ retval == 0 if not interested.
- \\
- return(retval);
- break;
-
- case XTYP_RTNPKT:
- RemoveFromDeadCheckQ(hConv);
- PassPkt(hDmgData, hszItem); \\ hDmgData==Pkt, hszItem==hAgentTo
- return(0);
- break;
-
- case XTYP_PKT:
- if (FindIgnoreList(hConv) { \\ was this unblocked due to no rtn pkt?
- RemoveFromIgnoreList(hConv);
- return(0); \\ rtn pkt failure.
- }
- if (!PassPkt(hDmgData, hszItem)) \\ hDmgData==Pkt, hszItem==hAgentTo
- return(0); \\ packet send failure.
- AddToDeadCheckQ(hConv, timenow());
- return(CBR_BLOCK); \\ will be unblocked and handled by ProcessPkt()
- break;
-
- case XTYP_REGISTER:
- case XTYP_UNREGISTER:
- \\
- \\ agent updates its communications name server.
- \\
- return(0);
- break;
-
- default:
- \\
- \\ the rest would reference local conversatoins that the agent
- \\ is maintaining.
- \\
- break;
- }
- }
-
- UnblockDeadTransaction(hConv) \\ called when no rtn pkt for hConv has been
- \\ received for a long time.
- {
- RemoveFromDeadCheckQ(hConv);
- AddToIgnoreList(hConv);
- DdeEnableCallback(CBK_ENABLE, hConv);
- }
-
- \* PUBDOC END */
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * USHORT EXPENTRY DdeInitialize(pfnCallback, afCmd, ulRes)
- * PFNCALLBACK pfnCallback; // address to application callback function
- * ULONG afCmd; // registration command flags
- * ULONG ulRes; // currently reserved, must be 0L.
- *
- * This API is used to initialize the DDEML for an application thread.
- *
- * afCmd - is a set of DMGCMD_ flags for special initialization instructio
- *
- * DMGCMD_AGENT
- * The registering application represents more than one DDE applicatio
- * Agents are never allowed to establish a conversation with
- * another agent. See Agent Transactions.
- *
- * DMGCMD_MONITOR
- *
- * This defines the registered application as a DDE transaction
- * monitor. This is primarily used for debugging DDE
- * applications. A monitoring application will have its Callback
- * function called every time a DDE message is sent.
- *
- * This flag is exclusive of all others. No other flags should be
- * or'ed in with this one.
- *
- * DMGCMD_CLIENTONLY
- * This should be specified when the application only intends to
- * be a DDE client. This reduces the resource consumption of the DLL.
- *
- * Registration is on a per-thread basis. Thus a multi-threaded applicati
- * could register several threads as seperate DDE entities.
- *
- * returns any applicable DMGERR_ error code or 0 on success.
- *
- * Most other DLL APIs will fail if the calling thread has not called this
- *
- * PUBDOC END
- *
- * Registration causes the following windows to be created:
- *
- * HWND_OBJECT
- * hwndDmg(s)
- * hwndClient(s)
- * hwndTopicServer(s)
- * hwndServer(s)
- * hwndMonitor(s)
- * HWND_DESKTOP
- * hwndFrame(s)
- *
- * See api.doc file for usage info.
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- USHORT EXPENTRY DdeInitialize(pfnCallback, afCmd, ulRes)
- PFNCALLBACK pfnCallback;
- ULONG afCmd;
- ULONG ulRes;
- {
- if (ulRes != 0L || CheckSel(SELECTOROF(pfnCallback)) == 0)
- return(DMGERR_INVALIDPARAMETER);
-
- return(Register(pfnCallback, afCmd, ulRes, FALSE));
- }
-
-
-
- USHORT EXPENTRY Register(pfnCallback, afCmd, ulRes, f32bit)
- PFNCALLBACK pfnCallback;
- ULONG afCmd;
- ULONG ulRes;
- BOOL f32bit; /* set if calling app is a 32bit app. */
- {
- BOOL fInit;
- PAPPINFO pai = 0L, paiT;
- PIDINFO pidInfo;
- USHORT usRet = DMGERR_PMWIN_ERROR;
- ULONG ctlFlags;
- CLASSINFO ci;
- USHORT cb;
-
- UNUSED ulRes;
-
- SemEnter();
- if (fInit = (hheapDmg == 0L)) {
- /*
- * First time only
- */
- syscc.codepage = syscc.country = 0;
- DosGetCtryInfo(sizeof(COUNTRYCODE), &syscc, (PCOUNTRYINFO)&syscc, &cb
- if (DosGetHugeShift(&usHugeShift))
- goto Abort;
- usHugeAdd = (1 << usHugeShift) - 1;
- if (!(hheapDmg = MyCreateHeap(0, 4096, 0, 0, 0, HEAPFLAGS)))
- goto Abort;
- if (!WinQueryClassInfo(DMGHAB, WC_FRAME, &ci))
- goto Abort;
- lpfnFrameWndProc = ci.pfnWindowProc;
- if (!AddAtomTable(TRUE))
- goto Abort;
- } else {
-
- if ((pai = GetCurrentAppInfo(FALSE)) != NULL) {
- /*
- * re-registration
- */
- return(DMGERR_DLL_USAGE);
- }
-
- /*
- * share the main heap with this process.
- */
- if (DosGetSeg(SELECTOROF(hheapDmg))) {
- SemLeave();
- return(DMGERR_PMWIN_ERROR);
- }
- }
-
-
- if (DosGetPID(&pidInfo))
- goto Abort;
-
- if (!(pai = (PAPPINFO)FarAllocMem(hheapDmg, sizeof(APPINFO))))
- goto Abort;
-
- if (!(pai->hheapApp = MyCreateHeap(0, 4096, 0, 0, 0, HEAPFLAGS))) {
- FarFreeMem(hheapDmg, pai, sizeof(APPINFO));
- pai = 0L;
- goto Abort;
- }
-
- pai->pAppNamePile = NULL; /* responds to nothing */
- pai->pSvrTopicList = CreateLst(pai->hheapApp, sizeof(HWNDHSZLI));
- pai->pHDataPile = CreatePile(pai->hheapApp, sizeof(HDMGDATA), 8);
- pai->afCmd = (USHORT)afCmd | (f32bit ? DMGCMD_32BIT : 0);
- pai->hwndDmg =
- pai->hwndFrame =
- pai->hwndMonitor =
- pai->hwndTimer = 0;
- pai->pid = pidInfo.pid;
- pai->tid = pidInfo.tid;
- pai->pfnCallback = pfnCallback;
- pai->cInCallback = 0;
- pai->LastError = DMGERR_NO_ERROR;
- pai->fEnableCB = TRUE;
- pai->plstCB = CreateLst(pai->hheapApp, sizeof(CBLI));
- pai->plstCBExceptions = NULL;
-
- /*
- * make nextThread link.
- */
- paiT = pAppInfoList;
- while (paiT && paiT->pid != pai->pid) {
- paiT = paiT->next;
- }
- pai->nextThread = paiT; /* paiT is NULL or of the same process */
-
- if (paiT) {
- while (paiT->nextThread->tid != pai->nextThread->tid) {
- paiT = paiT->nextThread;
- }
- paiT->nextThread = pai;
- } else {
- /*
- * We must reregister each class for each process that invokes this
- * DLL because we can't register public classes unless we are the
- * shell.
- * Since pai->nextThread is NULL, this is a new process.
- */
- WinRegisterClass(0, SZCLIENTCLASS, ClientWndProc, 0L, 4);
- WinRegisterClass(0, SZSERVERCLASS, ServerWndProc, 0L, 4);
- WinRegisterClass(0, SZDMGCLASS, DmgWndProc, 0L, 4);
- WinRegisterClass(0, SZDEFCLASS, WinDefWindowProc, 0L, 4);
- }
-
- pai->next = pAppInfoList;
- pAppInfoList = pai;
-
- if ((pai->hwndDmg = WinCreateWindow(HWND_OBJECT, SZDMGCLASS, "", 0L,
- 0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_APPROOT, 0L, 0L)) == 0L)
- goto Abort;
- }
-
- if (pai->afCmd & DMGCMD_MONITOR) {
- WinRegisterClass(0, SZMONITORCLASS, MonitorWndProc, 0L, 4);
- if ((pai->hwndMonitor = WinCreateWindow(HWND_OBJECT, SZMONITORCLASS,
- 0L, 0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_MONITOR, 0L, 0L)
- == 0L) {
- goto Abort;
- }
- if (++cMonitor) {
- WinSetHook(DMGHAB, NULL, HK_INPUT, (PFN)DdePostHookProc, hmodDmg)
- WinSetHook(DMGHAB, NULL, HK_SENDMSG, (PFN)DdeSendHookProc, hmodDm
- }
- }
-
- /*
- * create an invisible top-level frame for initiates. (if server ok)
- */
- usRet = DMGERR_PMWIN_ERROR;
- if (!(afCmd & DMGCMD_CLIENTONLY)) {
- ctlFlags = 0;
- if ((pai->hwndFrame = WinCreateStdWindow(HWND_DESKTOP, 0L, &ctlFlags,
- (PSZ)NULL, "", 0L, (HMODULE)NULL, 0, (PHWND)NULL)) == (HWND)N
- goto Abort;
- WinSubclassWindow(pai->hwndFrame, subframeWndProc);
- }
-
- DosExitList(EXLST_ADD, (PFNEXITLIST)ExlstAbort);
-
- SemLeave();
-
- return(DMGERR_NO_ERROR);
-
- Abort:
- SemLeave();
-
- if (pai)
- DdeUninitialize();
- else if (fInit && hheapDmg)
- hheapDmg = MyDestroyHeap(hheapDmg);
- return(usRet);
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeUninitialize(void);
- * This uninitializes an application thread from the DDEML.
- * All DLL resources associated with the application are destroyed.
- * Most other APIs will fail if called after this API by the same thread.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeUninitialize()
- {
- PAPPINFO pai, paiT;
- PMYDDES pmyddes;
- PIDINFO pi;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(FALSE);
-
- DosExitList(EXLST_REMOVE, (PFNEXITLIST)ExlstAbort);
-
- /*
- * get us out of the semaphore!
- * !!! NOTE: semaphore tid id -1 during exitlist processing!
- */
- DosGetPID(&pi);
- if (FSRSemDmg.cUsage > 0 && FSRSemDmg.pid == pi.pid &&
- (FSRSemDmg.tid == pi.tid || FSRSemDmg.tid == -1)) {
- while (FSRSemDmg.cUsage) {
- SemLeave();
- }
- }
-
- if (pai->hwndTimer)
- WinSendMsg(pai->hwndTimer, WM_TIMER, MPFROMSHORT(TID_ABORT), 0L);
-
- if (pai->hwndMonitor) {
- DestroyWindow(pai->hwndMonitor);
- if (!--cMonitor) {
- WinReleaseHook(DMGHAB, NULL, HK_INPUT, (PFN)DdePostHookProc, hmod
- WinReleaseHook(DMGHAB, NULL, HK_SENDMSG, (PFN)DdeSendHookProc, hm
- }
- }
-
- /*
- * inform others of DeRegistration
- */
- if (pai->pAppNamePile != NULL)
- DdeAppNameServer(NULL, ANS_UNREGISTER);
-
- UnlinkAppInfo(pai);
-
- DestroyWindow(pai->hwndDmg);
- DestroyWindow(pai->hwndFrame);
- DestroyHwndHszList(pai->pSvrTopicList);
- while (PopPileSubitem(pai->pHDataPile, (PBYTE)&pmyddes)) {
- if (CheckSel(SELECTOROF(pmyddes)) > sizeof(MYDDES) &&
- pmyddes->magic == MYDDESMAGIC &&
- pmyddes->pai == pai) {
- pmyddes->fs &= ~HDATA_APPOWNED;
- }
- FreeData(pmyddes, pai);
- }
- DestroyPile(pai->pHDataPile);
- if (pai->nextThread) {
- paiT = pai;
- while (paiT->nextThread != pai) {
- paiT = paiT->nextThread;
- }
- paiT->nextThread = pai->nextThread;
- if (paiT->nextThread == paiT) {
- paiT->nextThread = NULL;
- }
- }
- MyDestroyHeap(pai->hheapApp);
-
- DestroyPile(pai->pAppNamePile);
- FarFreeMem(hheapDmg, (PBYTE)pai, sizeof(APPINFO));
-
- if (pAppInfoList == NULL) { /* last guy out? - turn the lights out. *
- while (cAtbls--)
- WinDestroyAtomTable(aAtbls[cAtbls]);
- hheapDmg = MyDestroyHeap(hheapDmg);
- } else
- DosFreeSeg(SELECTOROF(hheapDmg));
-
- SemCheckOut();
-
- return(TRUE);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HCONVLIST EXPENTRY DdeBeginEnumServers(
- * HSZ hszAppName, // app name to connect to, NULL is wild.
- * HSZ hszTopic, // topic name to connect to, NULL is wild.
- * HCONV hConvList, // previous hConvList for reenumeration, NULL for initia
- * PCONVCONTEXT pCC, // language info or NULL for system default.
- * HAPP hApp); // target application handle or NULL for broadcast init.
- *
- * hszAppName - the DDE application name to connect to - may be 0 for wild.
- * hszTopic - the DDE topic name to connect to - may be 0 for wild.
- * hConvList - The conversation list handle to use for reenumeration.
- * If this is 0, a new hConvList is created.
- * pCC - pointer to CONVCONTEXT structure which provides conversation
- * information needed for international support. All DDEFMT_TEXT
- * strings within any conversation started by this call should use
- * the codepage referenced in this structure.
- * If NULL is given, the current system values are used.
- * hApp - if not NULL, this directs initiates to only be sent to hApp.
- *
- * This routine connects all available conversations on the given
- * app/topic pair. Hsz values of 0 indicate wild names. On reenumerati
- * old hConv's are kept and any new ones created are added to the
- * list. Duplicate connections are avoided where possible. A
- * duplicate connection is one which is to the same process and
- * thread on the same application/topic names. If hApp is provided,
- * initiates are given only to that application.
- * Reenumeration is primarily intended as a response
- * to registration of a new app name to the system. Reenumeration
- * also removes any terminated conversations from the list.
- *
- * returns NULL on failure, hConvList on success.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- HCONVLIST EXPENTRY DdeBeginEnumServers(hszAppName, hszTopic, hConvList,
- pCC, hApp)
- HSZ hszAppName;
- HSZ hszTopic;
- HWND hConvList;
- PCONVCONTEXT pCC;
- HAPP hApp;
- {
- PAPPINFO pai;
- HCONV hConv, hConvNext, hConvNew;
- HCONVLIST hConvListNew;
- PCLIENTINFO pciOld, pciNew;
- PID pidOld, pidNew;
- TID tidOld, tidNew;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == 0)
- return(0);
-
- /*
- * destroy any dead old clients
- */
- if (hConvList) {
- hConv = WinQueryWindow(hConvList, QW_TOP, FALSE);
- while (hConv != NULL) {
- hConvNext = WinQueryWindow(hConv, QW_NEXT, FALSE);
- if (!((USHORT)WinSendMsg(hConv, UM_QUERY, MPFROMSHORT(Q_STATUS),
- ST_CONNECTED))
- WinDestroyWindow(hConv);
- hConv = hConvNext;
- }
- }
-
- if ((hConvListNew = WinCreateWindow(pai->hwndDmg, SZDEFCLASS, "", 0L,
- 0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_CLROOT, 0L, 0L)) == NULL
- pai->LastError = DMGERR_PMWIN_ERROR;
- return(0L);
- }
-
- hConvNew = GetDDEClientWindow(hConvListNew, (HWND)hApp, NULL, hszAppName,
- hszTopic, pCC);
-
- /*
- * If no new hConvs created, quit now.
- */
- if (hConvNew == NULL) {
- if (hConvList && WinQueryWindow(hConvList, QW_TOP, FALSE) == NULL) {
- DestroyWindow(hConvList);
- hConvList = NULL;
- }
- if (hConvList == NULL)
- pai->LastError = DMGERR_NO_CONV_ESTABLISHED;
- return(hConvList);
- }
-
- /*
- * remove any new ones that duplicate old existing ones
- */
- if (hConvList && (hConv = WinQueryWindow(hConvList, QW_TOP, FALSE))) {
- while (hConv) {
- hConvNext = WinQueryWindow(hConv, QW_NEXT, FALSE);
- pciOld = (PCLIENTINFO)WinQueryWindowULong(hConv, QWL_USER);
- if (!WinIsWindow(DMGHAB, pciOld->ci.hwndPartner)) {
- WinDestroyWindow(hConv);
- hConv = hConvNext;
- continue;
- }
- WinQueryWindowProcess(pciOld->ci.hwndPartner, &pidOld, &tidOld);
- /*
- * destroy any new clients that are duplicates of the old ones.
- */
- hConvNew = WinQueryWindow(hConvListNew, QW_TOP, FALSE);
- while (hConvNew) {
- hConvNext = WinQueryWindow(hConvNew, QW_NEXT, FALSE);
- pciNew = (PCLIENTINFO)WinQueryWindowULong(hConvNew, QWL_USER)
- WinQueryWindowProcess(pciNew->ci.hwndPartner, &pidNew, &tidNe
- if (pciOld->ci.hszServerApp == pciNew->ci.hszServerApp &&
- pciOld->ci.hszTopic == pciNew->ci.hszTopic &&
- pidOld == pidNew &&
- tidOld == tidNew) {
- /*
- * assume same app, same topic, same process, same thread
- * is a duplicate.
- */
- WinDestroyWindow(hConvNew);
- }
- hConvNew = hConvNext;
- }
- /*
- * move the unique old client to the new list
- */
- WinSetParent(hConv, hConvListNew, FALSE);
- hConv = hConvNext;
- }
- WinDestroyWindow(hConvList);
- }
-
- /*
- * If none are left, fail because no conversations were established.
- */
- if (WinQueryWindow(hConvListNew, QW_TOP, FALSE) == NULL) {
- DestroyWindow(hConvListNew);
- pai->LastError = DMGERR_NO_CONV_ESTABLISHED;
- return(NULL);
- } else {
- return(hConvListNew);
- }
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HCONV EXPENTRY DdeGetNextServer(
- * HCONVLIST hConvList, // conversation list being traversed
- * HCONV hConvPrev) // previous conversation extracted or NULL for first
- *
- * hConvList - handle of conversation list returned by DdeBeginEnumServers().
- * hConvPrev - previous hConv returned by this API or 0 to start from the top
- * of hConvList.
- *
- * This API returns the next conversation handle associated with hConvList.
- * A 0 is returned if hConvPrev was the last conversation or if hConvList
- * has no active conversations within it.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- HCONV EXPENTRY DdeGetNextServer(hConvList, hConvPrev)
- HCONVLIST hConvList;
- HCONV hConvPrev;
- {
- if (!WinIsWindow(DMGHAB, hConvList))
- return(NULL);
- if (hConvPrev == NULL)
- return(WinQueryWindow(hConvList, QW_TOP, FALSE));
- else
- return(WinQueryWindow(hConvPrev, QW_NEXT, FALSE));
- }
-
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeEndEnumServers(hConvList)
- * HCONVLIST hConvList; // conversation list to destroy.
- *
- * hConvList - a conversation list handle returned by DdeBeginEnumServers().
- *
- * This API destroys hConvList and terminates all conversations associated
- * with it. If an application wishes to save selected conversations within
- * hConvList, it should call DdeDisconnect() on all hConv's it does not
- * want to use and not call this API.
- *
- * PUBDOC END
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeEndEnumServers(hConvList)
- HCONVLIST hConvList;
- {
- PAPPINFO pai;
- HCONV hConv, hConvNext;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(FALSE);
- if (WinIsWindow(DMGHAB, hConvList)) {
- hConv = WinQueryWindow(hConvList, QW_TOP, FALSE);
- while (hConv != NULL) {
- hConvNext = WinQueryWindow(hConv, QW_NEXT, FALSE);
- DestroyWindow(hConv);
- hConv = hConvNext;
- }
- DestroyWindow(hConvList);
- }
- return(TRUE);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HCONV EXPENTRY DdeConnect(hszAppName, hszTopic, pCC, hApp)
- * HSZ hszAppName; // app name to connect to, NULL is wild.
- * HSZ hszTopic; // topic name to connect to, NULL is wild.
- * PCONVCONTEXT pCC; // language information or NULL for sys default.
- * HAPP hApp; // target application or NULL for broadcast.
- *
- * hszAppName - DDE application name to connect to.
- * hszTopic - DDE Topic name to connect to.
- * pCC - CONVCONTEXT information pertinant to this conversation.
- * If NULL, the current system information is used.
- * hApp - if not NULL, directs connection to a specific app.
- *
- * returns - the conversation handle of the connected conversation or 0 on err
- *
- * This function allows the simpler aproach of allowing a client to
- * talk to the first server it finds on a topic. It is most efficient when
- * an hApp is provided.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/16/88 Sanfords
- \***************************************************************************/
- HCONV EXPENTRY DdeConnect(hszAppName, hszTopic, pCC, hApp)
- HSZ hszAppName;
- HSZ hszTopic;
- PCONVCONTEXT pCC;
- HAPP hApp;
- {
- PAPPINFO pai;
- HCONV hConv;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(0);
-
- hConv = GetDDEClientWindow(pai->hwndDmg, NULL, (HWND)hApp, hszAppName,
- hszTopic, pCC);
-
- if (hConv == 0)
- pai->LastError = DMGERR_NO_CONV_ESTABLISHED;
-
- return(hConv);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeDisconnect(hConv)
- * hConv; // conversation handle of conversation to terminate.
- *
- * This API terminates a conversation started by either DdeConnect() or
- * DdeBeginEnumServers(). hConv becomes invalid after this call.
- *
- * If hConv is a server conversation, any transactions for that conversation
- * found on the server callback queue will be deleted prior to terminating
- * the conversation.
- *
- * If hConv is a client conversation, any transactions on the Client Queue
- * are purged before termination.
- *
- * Note that client conversations that are terminated from the server end
- * go into a dormant state but are still available so that DdeQueryConvInfo()
- * can be used to determine why a conversation is not working.
- * Server conversations will destroy themselves if terminated from a client.
- *
- * returns fSuccess
- *
- * PUBDOC END
- * History:
- * Created 12/16/88 Sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeDisconnect(hConv)
- HCONV hConv;
- {
- PAPPINFO pai;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(FALSE);
-
- if (!WinIsWindow(DMGHAB, hConv)) {
- pai->LastError = DMGERR_NO_CONV_ESTABLISHED;
- return(FALSE);
- }
- SemCheckOut();
- return((BOOL)WinSendMsg(hConv, UMCL_TERMINATE, 0L, 0L));
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeQueryConvInfo(hConv, pConvInfo, idXfer)
- * HCONV hConv; // conversation hand to get info on.
- * PCONVINFO pConvInfo; // structure to hold info.
- * ULONG idXfer; // transaction ID if async, QID_SYNC if not.
- *
- * hConv - conversation handle of a conversation to query.
- * pConvInfo - pointer to CONVINFO structure.
- * idXfer - Should be a QID_ constant or an ID returned from DdeCheckQueue().
- * if id is QID_SYNC, then the synchronous conversation state is returne
- *
- * returns - fSuccess. The CONVINFO structure is filled in with the
- * conversation's status on success.
- *
- * Note that a client conversation may have several transactions in progress
- * at the same time. idXfer is used to choose which transaction to refer to.
- *
- * hConv may be a client or server conversation handle. Server conversation
- * handles ignore idXfer.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeQueryConvInfo(hConv, pConvInfo, idXfer)
- HCONV hConv;
- PCONVINFO pConvInfo;
- ULONG idXfer;
- {
- PCLIENTINFO pci;
- PAPPINFO pai;
- PXADATA pxad;
- PCQDATA pqd;
- BOOL fClient;
-
- if ((pai = GetCurrentAppInfo(FALSE)) == 0)
- return(FALSE);
-
- SemCheckOut();
-
- /*
- * note that pci may actually be a psi if fClient is false. Since
- * the common info portions are identical, we don't care except
- * where data is extracted from non-common portions.
- */
- if (!WinIsWindow(DMGHAB, hConv) ||
- !(pci = (PCLIENTINFO)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_ALL, 0
- !WinIsWindow(DMGHAB, pci->ci.hwndPartner)) {
- pai->LastError = DMGERR_NO_CONV_ESTABLISHED;
- return(FALSE);
- }
-
- fClient = (BOOL)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_CLIENT, 0L);
-
- if (idXfer == QID_SYNC || !fClient) {
- pxad = &pci->ci.xad;
- } else {
- if (pci->pQ != NULL &&
- (pqd = (PCQDATA)Findqi(pci->pQ, idXfer))) {
- pxad = &pqd->xad;
- } else {
- pai->LastError = DMGERR_UNFOUND_QUEUE_ID;
- return(FALSE);
- }
- }
- SemEnter();
- pConvInfo->cb = sizeof(CONVINFO);
- pConvInfo->hConvPartner = IsDdeWindow(pci->ci.hwndPartner);
- pConvInfo->hszAppName = pci->ci.hszServerApp;
- pConvInfo->hszAppPartner = fClient ? pci->ci.hszServerApp : 0;
- pConvInfo->hszTopic = pci->ci.hszTopic;
- pConvInfo->hAgent = pci->ci.hAgent;
- pConvInfo->hApp = pci->ci.hwndFrame;
- if (fClient) {
- pConvInfo->hszItem = pxad->pXferInfo->hszItem;
- pConvInfo->usFmt = pxad->pXferInfo->usFmt;
- pConvInfo->usType = pxad->pXferInfo->usType;
- pConvInfo->usConvst = pxad->state;
- pConvInfo->LastError = pxad->LastError;
- } else {
- pConvInfo->hszItem = NULL;
- pConvInfo->usFmt = 0;
- pConvInfo->usType = 0;
- pConvInfo->usConvst = pci->ci.xad.state;
- pConvInfo->LastError = pci->ci.pai->LastError;
- }
- pConvInfo->usStatus = pci->ci.fs;
- pConvInfo->fsContext = pci->ci.cc.fsContext;
- pConvInfo->idCountry = pci->ci.cc.idCountry;
- pConvInfo->usCodepage = pci->ci.cc.usCodepage;
- SemLeave();
- return(TRUE);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdePostAdvise(hszTopic, hszItem)
- * HSZ hszTopic; // topic of changed data, NULL is all topics
- * HSZ hszItem; // item of changed data, NULL is all items
- *
- * Causes any clients who have advise loops running on the topic/item name
- * specified to receive the apropriate data messages they require.
- *
- * This should be called by a server application anytime data associated with
- * a particular topic/item changes. This call results in XTYP_ADVREQ
- * callbacks being generated.
- *
- * hszTopic and/or hszItem may be NULL if all topics or items are to be update
- * This will result in callbacks for all active advise loops that fit the
- * hszTopic/hszItem pair.
- *
- * The API is intended for SERVERS only!
- *
- * PUBDOC END
- * History:
- * Created 12/16/88 Sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdePostAdvise(hszTopic, hszItem)
- HSZ hszTopic;
- HSZ hszItem;
- {
- PAPPINFO pai;
- HWND hwndTopic;
- HWND hwndSvr;
-
- // LATER - add wild hsz support
-
- if (((pai = GetCurrentAppInfo(TRUE)) == 0))
- return(FALSE);
-
- if (pai->afCmd & DMGCMD_CLIENTONLY) {
- pai->LastError = DMGERR_DLL_USAGE;
- return(FALSE);
- }
-
- if ((hwndTopic = HwndFromHsz((HSZ)hszTopic, pai->pSvrTopicList)) == 0)
- return(TRUE);
-
- hwndSvr = WinQueryWindow(hwndTopic, QW_TOP, FALSE);
- while (hwndSvr) {
- WinPostMsg(hwndSvr, UMSR_POSTADVISE, MPFROMSHORT(hszItem), 0L);
- hwndSvr = WinQueryWindow(hwndSvr, QW_NEXT, FALSE);
- }
-
- return(TRUE);
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HDMGDATA EXPENTRY DdeClientXfer(pSrc, cb, hConv, hszItem, usFmt,
- * usType, ulTimeout, pidXfer)
- * PBYTE pSrc; // data source, or NULL for non-data cases.
- * ULONG cb; // data size or 0 for non-data cases.
- * HCONV hConv; // associated conversation handle
- * HSZ hszItem; // item of transaction
- * USHORT usFmt; // format for transaction
- * USHORT usType; // transaction type code
- * ULONG ulTimeout; // timeout for synchronous, TIMEOUT_ASSYNC otherwise.
- * PULONG pidXfer; // OUTPUT: assync transfer id, NULL for no output.
- *
- * This API initiates a transaction from a client to the server connected
- * via the conversation specified by hConv.
- *
- * Currently usType may be:
- * XTYP_REQUEST
- * XTYP_POKE
- * XTYP_EXEC
- * XTYP_ADVSTART
- * XTYP_ADVSTART | XTYPF_NODATA
- * XTYP_ADVSTART | XTYPF_ACKREQ
- * XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ
- * XTYP_ADVSTOP
- *
- * ulTimeout specifies the maximum time to wait for a response in miliseconds
- * and applies to synchronous transactions only.
- * if ulTimeout is TIMEOUT_ASSYNC, then the transfer is asynchronous and
- * pidXfer may point to where to place the client transaction queue item
- * ID created by this request.
- * pidXfer may be NULL if no ID is desired.
- *
- * If usType is XTYP_REQUEST, synchronous transfers return a valid hDmgData
- * on success which holds the data received from the request.
- *
- * if usType is XTYP_EXEC and hszItem==NULL (wild) and usFmt==DDEFMT_TEXT,
- * the item name will be changed to the same as the text data.
- * This allows for EXCEL and porthole WINDOWS compatability
- * for XTYP_EXEC transactions. It is suggested that applications always set
- * hszItem to NULL for XTYP_EXEC transactions and that servers ignore the
- * hszItem perameter in their callback for execute transactions.
- *
- * returns hDmgData or ACK DDE flags on Success, 0 on failure.
- *
- * Note: the hDmgData passed in by this call is only valid for the duration
- * of the callback.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- HDMGDATA EXPENTRY DdeClientXfer(pSrc, cb, hConv, hszItem, usFmt,
- usType, ulTimeout, pidXfer)
- PBYTE pSrc;
- ULONG cb;
- HCONV hConv;
- HSZ hszItem;
- USHORT usFmt;
- USHORT usType;
- ULONG ulTimeout;
- PULONG pidXfer;
- {
- PAPPINFO pai;
- XFERINFO xi;
- HDMGDATA hDmgData;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(0);
-
- if (!WinIsWindow(DMGHAB, hConv)) {
- pai->LastError = DMGERR_NO_CONV_ESTABLISHED;
- return(0);
- }
-
- SemCheckOut();
-
- switch (usType) {
- case XTYP_REQUEST:
- case XTYP_POKE:
- case XTYP_EXEC:
- case XTYP_ADVSTART:
- case XTYP_ADVSTART | XTYPF_NODATA:
- case XTYP_ADVSTART | XTYPF_ACKREQ:
- case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:
- case XTYP_ADVSTOP:
- xi.pidXfer = pidXfer;
- xi.ulTimeout = ulTimeout;
- xi.usType = usType;
- xi.usFmt = usFmt;
- xi.hszItem = hszItem;
- xi.hConv = hConv;
- xi.cb = cb;
- xi.pData = pSrc;
- hDmgData = (HDMGDATA)WinSendMsg(hConv, UMCL_XFER, (MPARAM)&xi, 0L);
- if (ulTimeout == TIMEOUT_ASYNC) {
- /*
- * Increment the count of hszItem incase the app frees it on
- * return. This will be decremented when the client Queue
- * entry is removed.
- */
- IncHszCount(hszItem);
- }
-
- /*
- * add the hDmgData to the client's list of handles he needs
- * to eventually free.
- */
- if ((usType & XCLASS_DATA) && (CheckSel(SELECTOROF(hDmgData)))) {
- AddPileItem(pai->pHDataPile, (PBYTE)&hDmgData, CmpULONG);
- if (((PMYDDES)hDmgData)->magic == MYDDESMAGIC) {
- ((PMYDDES)hDmgData)->fs |= HDATA_READONLY;
- }
- }
-
- return(hDmgData);
- }
- pai->LastError = DMGERR_INVALIDPARAMETER;
- return(0);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * USHORT EXPENTRY DdeGetLastError(void)
- *
- * This API returns the most recent error registered by the DDE manager for
- * the current thread. This should be called anytime a DDE manager API
- * returns in a failed state.
- *
- * returns an error code which corresponds to a DMGERR_ constant found in
- * ddeml.h. This error code may be passed on to DdePostError() to
- * show the user the reason for the error or to DdeGetErrorString() to convert
- * the error code into an apropriate string.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- USHORT EXPENTRY DdeGetLastError(void)
- {
- PAPPINFO pai;
- SHORT err = DMGERR_DLL_NOT_INITIALIZED;
-
- pai = GetCurrentAppInfo(FALSE);
-
- if (pai) {
- err = pai->LastError;
- pai->LastError = DMGERR_NO_ERROR;
- }
- return(err);
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * void EXPENTRY DdePostError(err)
- * ULONG err; // error code to post.
- *
- * This API puts up a message box describing the error who's code was
- * passed in.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/20/88 sanfords
- \***************************************************************************/
- void EXPENTRY DdePostError(err)
- USHORT err;
- {
- char szError[MAX_ERRSTR + 1];
-
- if (err < DMGERR_FIRST || err > DMGERR_LAST)
- return;
- WinLoadString(DMGHAB, hmodDmg, err, MAX_ERRSTR + 1, szError);
- WinMessageBox(HWND_DESKTOP, NULL, szError, SZERRCAPTION, 0,
- MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * USHORT EXPENTRY DdeGetErrorString(err, cbMax, psz)
- * USHORT err; // error code to convert
- * USHORT cbMax; // size of string buffer provided by caller
- * PSZ psz; // string buffer address.
- *
- * This function fills psz with the error string referenced by err of up
- * to cbMax characters. All error strings are <= MAX_ERRSTR in length.
- * (not counting the NULL terminator.)
- *
- * returns length of copied string without NULL terminator or 0 on failure.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/20/88 sanfords
- \***************************************************************************/
- USHORT EXPENTRY DdeGetErrorString(err, cbMax, psz)
- USHORT err;
- USHORT cbMax;
- PSZ psz;
- {
- if (err < DMGERR_FIRST || err > DMGERR_LAST)
- return(0);
- return(WinLoadString(DMGHAB, hmodDmg, err, cbMax, psz));
- }
-
-
-
- /*\
- * HDATA stuff:
- *
- * Each thread has an hData list that contains all the hData's it has
- * been given by the DLL. This list indicates what hData's an app can
- * and must eventually free.
- *
- * If an app has multiple threads registered, each threads pai's are linked
- * via the nextThread pointer. The links are circular so the TID
- * should be used to know when all the lists are traversed.
- *
- * Each hData contains the following flags:
- *
- * HDATA_READONLY - set on any hData given to the DLL or created by the DLL.
- * This prevents AddData from working.
- *
- * HDATA_APPOWNED - set at creation time by app so app will keep access
- * until it frees it or unregistration happens.
- * This prevents the DLL from freeing the hData before an app is
- * through with it.
- *
- * HDATA_APPFREEABLE - set at creation time if logged into thread list.
- *
- * Each hData also contains the pai of the thread that created the hData.
- * (set by PutData) If APPOWNED is set, this identifies the
- * owner thread as well.
- *
- *
- * General rules for apps:
- *
- * hDatas from DLL calls are the apps responsibility to free and are
- * only valid till passed back into the DLL or freed.
- * hDatas from callback calls are only valid during the callback.
- * hDatas created by an app but not APPOWNED are only valid till
- * passed into the DLL.
- * hDatas created by an app that are APPOWNED are valid until
- * the creating thread frees it or till that thread unregister
- * itself.
- * A process will not loose access to an hData untill all threads that
- * have received the hData have freed it or passed it back to
- * the DLL (via callback)
- *
- *
- * Register: DONE
- * creates hDataList for app/thread.
- * creates nextThread links if applicable.
- *
- * DdePutData: DONE
- * Only allows HDATA_APPOWNED flag
- * sets HDATA_APPFREEABLE flag
- * ...Falls into....
- * PutData: DONE
- * Allocates selector
- * sets creator pai
- * sets HDATA_ flags specified
- * if (HDATA_APPFREEABLE)
- * adds to hDataList.
- *
- * DdeAddData: DONE
- * fails if HDATA_READONLY or a non-dll type selector
- *
- * Callback: DONE
- * Entry:
- * for hData to callback:
- * Sets HDATA_READONLY if hData valid DLL type selector.
- * (does NOT add hData to thread list so he can't free it duri
- * the callback)
- *
- * Exit:
- * for hData to callback:
- * nothing.
- * for hData from callback:
- * verifies creator == current
- *
- * DdeCreateInitPkt: DONE
- * DdeAppNameServer: NOT COMPLETE
- * DdeClientXfer: DONE
- * DdeCheckQ: DONE
- * if (valid selector)
- * add to thread list
- * if (valid DLL type selector)
- * Set READONLY flag.
- *
- * ProcessPkt: NOT IMP.
- * for hData in:
- * After used, calls FreeData()
- * for hData out:
- * before return, adds hData to thread list
- *
- * MyPostMsg: DONE
- * gives if target process != current
- * if target process is not a DLL process/thread, expand hszItem.
- * calls FreeData() on current process if MDPM_FREEHDATA is set.
- *
- *
- * DdeFreeData: DONE
- * if in thread list.
- * remove hData from list
- * if not in any thread lists for this process
- * free data
- * return pass
- * else
- * return fail
- *
- * FreeData: DONE
- * if (DLL type selector && HDATA_APPOWNED && creator == current)
- * exit
- * remove hData from thread list if found
- * if not in any thread lists for this process
- * free data
- *
- * UnRegister: DONE
- * for each item in the hDataList:
- * clear HDATA_APPOWNED flag if dll type selector and owned by thi
- * thread.
- * FreeData()
- * destroy list
- * unlink from other thread lists
- *
- \*/
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HDMGDATA EXPENTRY DdePutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd)
- * PBYTE pSrc; // address of data to place into data handle or NULL
- * ULONG cb; // amount of data to copy if pSrc is not NULL.
- * ULONG cbOff; // offset into data handle region to place pSrc data
- * HSZ hszItem; // item associated with this data
- * USHORT usFmt; // format associated with this data
- * USHORT afCmd; // HDATA_ flags.
- *
- * This api allows an application to create a hDmgData apropriate
- * for return from its call-back function.
- * The passed in data is stored into the hDmgData which is
- * returned on success. Any portions of the data handle not filled are
- * undefined. afCmd contains any of the HDATA_ constants described below:
- *
- * HDATA_APPOWNED
- * This declares the created data handle to be the responsability of
- * the application to free it. Application owned data handles may
- * be given to the DLL multiple times. This allows a server app to be
- * able to support many clients without having to recopy the data for
- * each request. If this flag is not specified, the data handle becomes
- * invalid once passed to the DLL via any API or the callback function.
- *
- * NOTES:
- * If an application expects this data handle to hold >64K of data via
- * DdeAddData(), it should specify a cb + cbOff to be as large as
- * the object is expected to get via DdeAddData() calls to avoid
- * unnecessary data copying or reallocation by the DLL.
- *
- * if psrc==NULL or cb == 0, no actual data copying takes place.
- *
- * Data handles given to an application via the DdeClientXfer() or
- * DdeCheckQueue() functions are the responsability of the client
- * application to free and MUST NOT be returned from the callback
- * function as server data! The DLL will only accept data handles
- * returned from the callback function that were created by the
- * called application.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- HDMGDATA EXPENTRY DdePutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd)
- PBYTE pSrc;
- ULONG cb;
- ULONG cbOff;
- HSZ hszItem;
- USHORT usFmt;
- USHORT afCmd;
- {
- PAPPINFO pai;
-
- if (!(pai = GetCurrentAppInfo(FALSE)))
- return(0L);;
-
- if (afCmd & ~(HDATA_APPOWNED)) {
- pai->LastError = DMGERR_INVALIDPARAMETER;
- return(0L);
- }
-
- return(PutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd | HDATA_APPFREEABLE
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HDMGDATA EXPENTRY DdeAddData(hDmgData, pSrc, cb, cbOff)
- * HDMGDATA hDmgData; // data handle to add data to
- * PBYTE pSrc; // pointer to data to add (if NULL, no data copying)
- * ULONG cb; // size of data to add
- * ULONG cbOff; // offset within hData to place data
- *
- * This routine allows an application to add data to a hDmgData it had
- * previously created using DdePutData(). The handle will be
- * grown as necessary to support the data addition. Data may be added
- * to a data handle multiple times and in any order of data locations.
- *
- * Once a data handle is given to the DLL via return from the callback
- * function or via a DLL API, it becomes readonly. Further attempts to
- * add data to the hData by any process will fail.
- *
- * This call will return 0 if it failed to allocate enough memory or if
- * the data handle is readonly. On success, the returned hDmgData should
- * replace the given hDmgData. On failure, the hDmgData given is left
- * in the state it was initially.
- *
- * NOTE: For huge segments, or segments expected to grow to greater than
- * 64K, it is best if DdePutData() be called with a cbOff + cb as
- * large as maximally expected so as not to force reallocation from a
- * normal to a huge segment in 16bit applications. This also avoids
- * the need of replaceing the hDmgData with the output each time
- * incase a new selector was needed to be allocated and copied to.
- *
- * PUBDOC END
- *
- * History:
- * Created 9/17/89 Sanfords
- \***************************************************************************/
- HDMGDATA EXPENTRY DdeAddData(hDmgData, pSrc, cb, cbOff)
- HDMGDATA hDmgData;
- PBYTE pSrc;
- ULONG cb;
- ULONG cbOff;
- {
- #define pmyddes ((PMYDDES)hDmgData)
- #define selIn (SELECTOROF(hDmgData))
-
- PAPPINFO pai;
- SEL sel;
- ULONG cbOffAbs;
-
- if (!(pai = GetCurrentAppInfo(FALSE)))
- return(0L);;
-
- if (!CheckSel(selIn) ||
- pmyddes->offszItemName != sizeof(MYDDES) ||
- pmyddes->magic != MYDDESMAGIC ||
- pmyddes->fs & HDATA_READONLY) {
- pai->LastError = DMGERR_INVALID_HDMGDATA;
- return(0L);
- }
-
- cbOffAbs = pmyddes->offabData + cbOff;
- if (pmyddes->cbData + pmyddes->offabData < cb + cbOffAbs) {
- /*
- * need to grow...
- */
- if (cbOffAbs + cb > 0xFFFFL) {
- /*
- * going to be huge...
- */
- if ((pmyddes->offabData + pmyddes->cbData < 0xFFFFL) ||
- DosReallocHuge(HIUSHORT(cb + cbOffAbs),
- LOUSHORT(cb + cbOffAbs), selIn)) {
- /*
- * Either we can't grow a huge seg or we need to make one.
- */
- if (DosAllocHuge(HIUSHORT(cb + cbOffAbs),
- LOUSHORT(cb + cbOffAbs), &sel, 0, SEG_GIVEABLE)) {
- pai->LastError = DMGERR_MEMORY_ERROR;
- return(0);
- }
- CopyHugeBlock(hDmgData, MAKEP(sel, 0), pmyddes->cbData +
- sizeof(MYDDES) + 1);
- FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDmgData,
- FPI_DELETE);
- DosFreeSeg(selIn);
- hDmgData = MAKEP(sel, 0);
- AddPileItem(pai->pHDataPile, (PBYTE)&hDmgData, NULL);
- }
- } else {
- /*
- * not going to be huge
- */
- if (DosReallocSeg((USHORT)(cb + cbOffAbs), selIn)) {
- pai->LastError = DMGERR_MEMORY_ERROR;
- return(0L);
- }
- }
- pmyddes->cbData = cbOff + cb;
- }
- if (pSrc)
- CopyHugeBlock(pSrc, HugeOffset((PBYTE)hDmgData, cbOffAbs), cb);
- return(hDmgData);
- #undef selIn
- #undef pmyddes
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * ULONG EXPENTRY DdeGetData(hDmgData, pDst, cbMax, cbOff)
- * HDMGDATA hDmgData; // data handle to extract data from
- * PBYTE pDst; // destination for extracted data
- * ULONG cbMax; // destination buffer size
- * ULONG cbOff; // offset into data to start extraction
- *
- * This copies up to cbMax bytes of data contained in the hDmgData data handle
- * at offset cbOff into application memory pointed to by pDst.
- * If pDst == NULL, no copying is performed.
- *
- * returns the size of the data contained in the data handle remaining after
- * cbOff or 0 if hDmgData is invalid or cbOff is too large.
- *
- * This API supports HUGE segments in 16 bit applications.
- *
- * PUBDOC END
- *
- * History:
- * Created 12/14/88 Sanfords
- \***************************************************************************/
- ULONG EXPENTRY DdeGetData(hDmgData, pDst, cbMax, cbOff)
- HDMGDATA hDmgData;
- PBYTE pDst;
- ULONG cbMax;
- ULONG cbOff;
- {
- PAPPINFO pai;
-
- if ((pai = GetCurrentAppInfo(FALSE)) == NULL)
- return(0L);
-
- if (!CheckSel(SELECTOROF(hDmgData))) {
- pai->LastError = DMGERR_INVALID_HDMGDATA;
- return(0L);
- }
- if (cbOff >= ((PMYDDES)hDmgData)->cbData) {
- pai->LastError = DMGERR_INVALIDPARAMETER;
- return(0L);
- }
- cbMax = min(cbMax, ((PMYDDES)hDmgData)->cbData - cbOff);
- if (pDst == NULL)
- return(((PMYDDES)hDmgData)->cbData - cbOff);
- CopyHugeBlock(HugeOffset(DDES_PABDATA(hDmgData), cbOff), pDst, cbMax);
- return(cbMax);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * PBYTE EXPENTRY DdeAccessData(hDmgData)
- * HDMGDATA hDmgData; // data handle to access
- *
- * This API returns a pointer to the data referenced by the data handle.
- * The pointer returned becomes invalid once the data handle is freed
- * or given to the DLL via callback return or API call.
- *
- * NOTE: applications MUST take care not to access beyond the limits of
- * the data handle. Only hDmgData's created by the application via
- * a DdePutData() call may write to this memory prior to passing on
- * to any DLL API or returning from the callback function. Any hDmgData
- * received from the DLL should be considered shared-readonly data and
- * should be treated as such. This applies whether the application owns
- * the data handle or not.
- *
- * 0L is returned on error.
- *
- * PUBDOC END
- *
- * History:
- * Created 8/24/88 Sanfords
- \***************************************************************************/
- PBYTE EXPENTRY DdeAccessData(hDmgData)
- HDMGDATA hDmgData;
- {
- PAPPINFO pai;
-
- if ((pai = GetCurrentAppInfo(FALSE)) == NULL)
- return(0L);
- if (CheckSel(SELECTOROF(hDmgData))) {
- return(DDES_PABDATA(hDmgData));
- }
- pai->LastError = DMGERR_ACCESS_DENIED;
- return(0L);
- }
-
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeFreeData(hDmgData)
- * HDMGDATA hDmgData; // data handle to destroy
- *
- * This routine should be called by an application wishing to release
- * custody of an hDmgData it owns.
- * An application owns any hDmgData
- * it created with the HDATA_APPOWNED flag or an hDmgData given to
- * it via DdeClientXfer(), DdeCheckQueue(), DdeAppNameServer(),
- * DdeCreateInitPkt() or DdeProcessPkt().
- *
- * Returns fSuccess. This function will fail if the hDmgData is not
- * owned by the calling app.
- *
- * PUBDOC END
- * History:
- * Created 12/14/88 Sanfords
- * 6/12/90 sanfords Fixed to work with non-DLL generated selectors
- \***************************************************************************/
- BOOL EXPENTRY DdeFreeData(hDmgData)
- HDMGDATA hDmgData;
- {
- PAPPINFO pai;
- USHORT cbSel;
- TID tid;
-
- if ((pai = GetCurrentAppInfo(FALSE)) == NULL)
- return(FALSE);
-
- cbSel = CheckSel(SELECTOROF(hDmgData));
- if (!cbSel) {
- pai->LastError = DMGERR_INVALID_HDMGDATA;
- return(FALSE);
- }
- SemEnter();
- /*
- * Apps can only free handles the DLL does not own or handles from extern
- * non-DLL DDE apps.
- */
- if (!FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDmgData, FPI_DELETE
- pai->LastError = DMGERR_INVALID_HDMGDATA;
- SemLeave();
- return(FALSE);
- }
-
- tid = pai->tid;
- do {
- if (FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDmgData, FPI_COU
- SemLeave();
- return(TRUE);
- }
- pai = pai->nextThread;
- } while (pai && pai->tid != tid);
- DosFreeSeg(SELECTOROF(hDmgData));
-
- SemLeave();
- return(TRUE);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeCopyBlock(pSrc, pDst, cb)
- * PBYTE pSrc; // source of copy
- * PBYTE pDst; // destination of copy
- * ULONG cb; // size in bytes of copy
- *
- * This copy utility can handle HUGE segments and can be used by any
- * application as a copy utility. This does not support overlapping huge
- * copies.
- *
- * Returns fSuccess.
- *
- * PUBDOC END
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeCopyBlock(pSrc, pDst, cb)
- PBYTE pSrc;
- PBYTE pDst;
- ULONG cb;
- {
- return(CopyHugeBlock(pSrc, pDst, cb));
- }
-
-
-
-
- /***************************************************************************\
- * PUBDOC START
- * HSZ management notes:
- *
- * HSZs are used in this DLL to simplify string handling for applications
- * and for inter-process communication. Since many applications use a
- * fixed set of Application/Topic/Item names, it is convenient to convert
- * them to HSZs and allow quick comparisons for lookups. This also frees
- * the DLL up from having to constantly provide string buffers for copying
- * strings between itself and its clients.
- *
- * HSZs are the same as atoms except they have no restrictions on length or
- * number and are 32 bit values. They are case preserving and can be
- * compared directly for case sensitive comparisons or via DdeCmpHsz()
- * for case insensitive comparisons.
- *
- * When an application creates an HSZ via DdeGetHsz() or increments its
- * count via DdeIncHszCount() it is essentially claiming the HSZ for
- * its own use. On the other hand, when an application is given an
- * HSZ from the DLL via a callback, it is using another application's HSZ
- * and should not free that HSZ via DdeFreeHsz().
- *
- * The DLL insures that during the callback any HSZs given will remain
- * valid for the duration of the callback.
- *
- * If an application wishes to keep that HSZ to use for itself as a
- * standard for future comparisons, it should increment its count so that,
- * should the owning application free it, the HSZ will not become invalid.
- * This also prevents an HSZ from changing its value. (ie, app A frees it
- * and then app B creates a new one that happens to use the same HSZ code,
- * then app C, which had the HSZ stored all along (but forgot to increment
- * its count) now is holding a handle to a different string.)
- *
- * Applications may free HSZs they have created or incremented at any time
- * by calling DdeFreeHsz().
- *
- * The DLL internally increments HSZ counts while in use so that they will
- * not be destroyed until both the DLL and all applications concerned are
- * through with them.
- *
- * IT IS THE APPLICATIONS RESPONSIBILITY TO PROPERLY CREATE AND FREE HSZs!!
- *
- * PUBDOC END
- \***************************************************************************/
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HSZ EXPENTRY DdeGetHsz(psz, country, codepage)
- * PSZ psz; // string to HSZize.
- * USHORT country; // country ID to use in comparisons.
- * USHORT codepage; // codepage to use in comparisons.
- *
- * This routine returns a string handle to the psz passed in.
- * 0 is returned on failure or for NULL strings.
- *
- * If country is 0, the default system country code is used.
- * If codepage is 0, the default system codepage code is used.
- *
- * String handles are similar to atoms but without the 255
- * character limit on strings. String handles are case preserving.
- * see DdeCmpHsz().
- *
- * String handles are consistant across all processes using the DLL.
- *
- * PUBDOC END
- *
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- HSZ EXPENTRY DdeGetHsz(psz, country, codepage)
- PSZ psz;
- USHORT country, codepage;
- {
- PAPPINFO pai;
-
- if ((pai = GetCurrentAppInfo(FALSE)) == NULL)
- return(0);
-
- return(GetHsz(psz, country, codepage, TRUE));
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeFreeHsz(hsz)
- * HSZ hsz; // string handle to free
- *
- * This function decrements the usage count for the HSZ given and frees
- * it if the count becomes 0.
- *
- * PUBDOC END
- *
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeFreeHsz(hsz)
- HSZ hsz;
- {
- PAPPINFO pai;
-
- if ((pai = GetCurrentAppInfo(FALSE)) == NULL)
- return(0);
- return(FreeHsz(hsz));
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeIncHszCount(hsz)
- * HSZ hsz; // string handle to increment.
- *
- * This function increments the usage count for the HSZ given. This is
- * useful when an application wishes to keep an HSZ given to it in its
- * callback.
- *
- * PUBDOC END
- *
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeIncHszCount(hsz)
- HSZ hsz;
- {
- PAPPINFO pai;
-
- if ((pai = GetCurrentAppInfo(FALSE)) == NULL)
- return(0);
-
- return(IncHszCount(hsz));
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * USHORT EXPENTRY DdeGetHszString(hsz, psz, cchMax)
- * HSZ hsz; // string handle to extract string from
- * PSZ psz; // buffer for case-sensitive string
- * ULONG cchMax; // buffer size.
- *
- * This API is the inverse of DdeGetHsz(). The actual length of the
- * string (without NULL terminator) referenced by hsz is returned.
- *
- * if psz is NULL, no string is returned in psz.
- * 0 is returned if hsz does not exist or is wild.
- * If hsz is wild, psz will be set to a 0 length string.
- *
- * PUBDOC END
- * History: Created 5/10/89 sanfords
- \***************************************************************************/
- USHORT EXPENTRY DdeGetHszString(hsz, psz, cchMax)
- HSZ hsz;
- PSZ psz;
- ULONG cchMax;
- {
- if (psz) {
- if (hsz) {
- return(QueryHszName(hsz, psz, (USHORT)cchMax));
- } else {
- *psz = '\0';
- return(0);
- }
- } else if (hsz) {
- return(QueryHszLength(hsz));
- } else {
- return(0);
- }
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * SHORT EXPENTRY DdeCmpHsz(hsz1, hsz2)
- * HSZ hsz1, hsz2; // string handles to compare.
- *
- * This routine returns:
- * 0 if hsz1 is of equal rank to hsz2
- * -2 if hsz1 is invalid.
- * -1 if hsz1 is of lower rank than hsz2
- * 1 if hsz1 is of higher rank than hsz2.
- * 2 if hsz2 is invalid.
- *
- * Note that direct comparison of hszs (ie (hsz1 == hsz2)) is a case sensitive
- * comparison. This function performs a case insensitive comparison. Thus
- * different valued hszs may actually be equal.
- * A ranking is provided for binary searching.
- *
- * PUBDOC END
- \***************************************************************************/
- SHORT EXPENTRY DdeCmpHsz(hsz1, hsz2)
- HSZ hsz1, hsz2;
- {
- return(CmpHsz(hsz1, hsz2));
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * ULONG EXPENTRY DdeCheckQueue(hConv, phDmgData, idXfer, afCmd)
- * HCONV hConv; // related convesation handle
- * PHDMGDATA phDmgData; // OUTPUT: for resultant data handle, or NULL
- * ULONG idXfer; // transaction ID or QID_NEWEST or QID_OLDEST
- * ULONG afCmd; // queue operation code.
- *
- * This routine checks a client conversation's assynchronous
- * transaction queue for queued transaction status. This allows a
- * client to extract data or monitor the status of any transaction
- * previously started asynchronously. (TIMEOUT_ASSYNC) hConv is
- * the client conversation who's queue is being checked.
- *
- * If phDmgData is not NULL and the referenced item has data to
- * return to the client, phDmgData is filled. Returned hDmgDatas
- * must be freed by the application. phDmgData will be filled with
- * 0L if no return data is applicable or if the transaction is not
- * complete.
- *
- * If the queue is not periodicly flushed by an application
- * issueing asynchronous transactions the queue is automaticly
- * flushed as needed. Oldest transactions are flushed first.
- * DdeProcessPkt() and DdeDisconnect() and DdeEndEnumServers
- * remove items from this queue.
- *
- * idXfer is the transaction id returned by an asynchronous call to
- * DdeClientXfer().
- *
- * afCmd = CQ_FLUSH - remove all items in the queue - return is fSuccess.
- * afCmd = CQ_REMOVE - the item referenced is removed from the queue.
- * afCmd = CQ_NEXT - references the idXfer AFTER (more recent than) the id
- * given. 0 is returned if the ID given was the newest in the
- * queue otherwise the next ID is returned.
- * afCmd = CQ_PREV - references the idXfer BEFORE (less recent than) the id
- * given. 0 is returned if the ID given was the oldest in the
- * queue otherwise the previous ID is returned.
- * afCmd = CQ_COUNT - returns the number of entries in the queue.
- *
- * By ORing in one of the following flags, the above flags can be
- * made to reference the apropriate subset of queue entries:
- *
- * afCmd = CQ_ACTIVEONLY - incomplete active transactions only.
- * afCmd = CQ_COMPLETEDONLY - completed transactions only.
- * afCmd = CQ_FAILEDONLY - transactions which had protocol violations or
- * communication failures.
- * afCmd = CQ_INACTIVEONLY - The complement of CQ_ACTIVEONLY which is the
- * union of CQ_COMPLETEDONLY and CQ_FAILEDONLY.
- *
- * if phdmgdata = NULL, no hdmgdata is returned.
- * if idXfer == QID_NEWEST, the top-most (most recent) entry in the
- * queue is referenced.
- * if idXfer == QID_OLDEST, the bottom-most (oldest) entry ID is
- * referenced.
- *
- * returns the ID of the item processed if it applies, or the count
- * of items or fSuccess.
- *
- *
- * Standard usage examples:
- *
- * To get the state of the oldest transaction:
- * id = DdeCheckQueue(hConv, &hDmgData, QID_OLDEST, 0)
- *
- * To get and flush the next completed transaction data, if there is
- * any:
- * id = DdeCheckQueue(hConv, &hDmgData, QID_OLDEST, CQ_REMOVE |
- * CQ_INACTIVEONLY)
- *
- * To flush all successfully completed transactions:
- * DdeCheckQueue(hConv, NULL, QID_OLDEST, CQ_FLUSH | CQ_COMPLETEDONLY)
- *
- * To see if a specific transaction is complete, and if so, to get the
- * information and remove the transaction from the queue:
- * if (DdeCheckQueue(hConv, &hDmgData, id, CQ_REMOVE | CQ_INACTIVEONLY))
- * ProcessAndFreeData(hDmgData);
- *
- * PUBDOC END
- * History: Created 6/6/89 sanfords
- \***************************************************************************/
- ULONG EXPENTRY DdeCheckQueue(hConv, phDmgData, idXfer, afCmd)
- HCONV hConv;
- PHDMGDATA phDmgData;
- ULONG idXfer;
- ULONG afCmd;
- {
- PAPPINFO pai;
- PCLIENTINFO pci;
- PCQDATA pcqd, pcqdT, pcqdEnd;
- USHORT err;
- ULONG retVal = TRUE;
- int i;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == 0)
- return(0);
-
- SemCheckOut();
- SemEnter();
-
- err = DMGERR_INVALIDPARAMETER;
- if (!WinIsWindow(DMGHAB, hConv) ||
- !(BOOL)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_CLIENT, 0L) ||
- idXfer == QID_SYNC) {
- goto failExit;
- }
-
- if (!(pci = (PCLIENTINFO)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_ALL, 0L)))
- goto failExit;
-
- err = DMGERR_UNFOUND_QUEUE_ID;
- if ((pcqd = (PCQDATA)Findqi(pci->pQ, idXfer)) == NULL)
- goto failExit;
-
- /*
- * if referencing an end item, make sure it fits any subset flags.
- * If it doesn't we alter afCmd to force us to the first qualifying
- * entry in the correct direction.
- */
- if (!fInSubset(pcqd, afCmd)) {
- if (idXfer & (QID_OLDEST))
- afCmd |= CQ_NEXT;
- else if (idXfer & (QID_NEWEST))
- afCmd |= CQ_PREV;
- else if (!(afCmd & (CQ_NEXT | CQ_PREV | CQ_COUNT | CQ_FLUSH)))
- goto failExit;
- }
-
- if (afCmd & CQ_NEXT) {
- pcqdEnd = (PCQDATA)pci->pQ->pqiHead->next;
- if ((pcqd = (PCQDATA)pcqd->next) == pcqdEnd)
- goto failExit;
- while (!fInSubset(pcqd, afCmd)) {
- if ((pcqd = (PCQDATA)pcqd->next) == pcqdEnd)
- goto failExit;
- }
- }
-
- if (afCmd & CQ_PREV) {
- pcqdEnd = (PCQDATA)pci->pQ->pqiHead;
- if ((pcqd = (PCQDATA)pcqd->prev) == pcqdEnd)
- goto failExit;
- while (!fInSubset(pcqd, afCmd)) {
- if ((pcqd = (PCQDATA)pcqd->prev) == pcqdEnd)
- goto failExit;
- }
- }
-
- /*
- * pcqd now points to the apropriate entry
- */
-
- if (afCmd & CQ_COUNT)
- retVal = 0;
- else
- retVal = MAKEID(pcqd);
-
- /*
- * Fill phDmgData if specified.
- */
- if (phDmgData != NULL)
- if ((pcqd->xad.state == CONVST_CONNECTED) &&
- CheckSel(SELECTOROF(pcqd->xad.pddes))) {
- *phDmgData = pcqd->xad.pddes;
- AddPileItem(pai->pHDataPile, (PBYTE)phDmgData, CmpULONG);
- if (((PMYDDES)*phDmgData)->magic == MYDDESMAGIC) {
- ((PMYDDES)*phDmgData)->fs |= HDATA_READONLY;
- }
- } else
- *phDmgData = NULL;
-
- /*
- * remove pcqd if apropriate.
- */
- if (afCmd & (CQ_REMOVE | CQ_FLUSH)) {
- if (!FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&pcqd->xad.pddes,
- 0))
- FreeData((PMYDDES)pcqd->xad.pddes, pai);
- /*
- * Decrement the use count we incremented when the client started
- * this transaction.
- */
- FreeHsz(pcqd->XferInfo.hszItem);
- Deleteqi(pci->pQ, MAKEID(pcqd));
- }
-
- /*
- * go through entire list and flush or count if specified.
- */
- if (afCmd & (CQ_FLUSH | CQ_COUNT)) {
- pcqd = (PCQDATA)pci->pQ->pqiHead;
- for (i = pci->pQ->cItems; i; i--) {
- if (fInSubset(pcqd, afCmd)) {
- if (afCmd & CQ_COUNT)
- retVal++;
- if (afCmd & CQ_FLUSH) {
- pcqdT = (PCQDATA)pcqd->next;
- /*
- * Only free the data if not logged - ie the user never g
- * copy.
- */
- if (!FindPileItem(pci->ci.pai->pHDataPile, CmpULONG,
- (PBYTE)&pcqd->xad.pddes, 0))
- FreeData((PMYDDES)pcqd->xad.pddes, pai);
- /*
- * Decrement the use count we incremented when the client
- * this transaction.
- */
- FreeHsz(pcqd->XferInfo.hszItem);
- Deleteqi(pci->pQ, MAKEID(pcqd));
- pcqd = pcqdT;
- continue;
- }
- }
- pcqd = (PCQDATA)pcqd->next;
- }
- }
-
- SemLeave();
- SemCheckOut();
- return(retVal);
-
- failExit:
- pai->LastError = err;
- SemLeave();
- SemCheckOut();
- return(0);
- }
-
-
-
- BOOL fInSubset(pcqd, afCmd)
- PCQDATA pcqd;
- ULONG afCmd;
- {
- if (afCmd & CQ_ACTIVEONLY && (pcqd->xad.state <= CONVST_INIT1))
- return(FALSE);
-
- if (afCmd & CQ_INACTIVEONLY && (pcqd->xad.state > CONVST_INIT1))
- return(FALSE);
-
- if (afCmd & CQ_COMPLETEDONLY && (pcqd->xad.state != CONVST_CONNECTED))
- return(FALSE);
-
- if (afCmd & CQ_FAILEDONLY && (pcqd->xad.state > CONVST_TERMINATED))
- return(FALSE);
- return(TRUE);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeEnableCallback(hConv, fEnable)
- * HCONV hConv; // server conversation handle to enable/disable or NULL
- * BOOL fEnable; // TRUE enables, FALSE disables callbacks.
- *
- * This routine is used by an application that does not want to be interrupted
- * by DLL calls to its Callback function. When callbacks are disabled,
- * all non critical attempts to call the Callback function instead result in
- * the call being placed on a server transaction queue until callbacks are
- * reenabled. An application should reenable callbacks in a timely manner
- * to avoid causing synchronous clients to time out.
- *
- * note that DdeProcessPkt() has the side effect of unblocking and removing
- * items from the server transaction queue when processing return packets.
- * DdeDisconnect() and DdeEndEnumServers() have the side effect of removing
- * any transactions for the disconnected conversation.
- *
- * If hConv is non-NULL, only the hConv conversation is affected.
- * If hConv is NULL, all conversations are affected.
- *
- * Callbacks can also be disabled on return from the callback function by
- * returning the constant CBR_BLOCK. This has the same effect as
- * calling DdeEnableCallback(hConv, FALSE) except that the callback
- * returned from is placed back on the callback queue for later re-submission
- * to the callback function when the conversations callbacks are reenabled.
- * This allows a server that needs a long time to process a request to delay
- * returning the result without blocking within the callback function.
- *
- * No callbacks are made within this function.
- *
- * Note: Callback transactions that have XTYPF_NOBLOCK set in their usType
- * parameter cannot be blocked by CBR_BLOCK.
- * These callbacks are issued to the server regardless of the state of
- * callback enableing.
- *
- * fSuccess is returned.
- *
- * PUBDOC END
- * History: Created 6/6/89 sanfords
- \***************************************************************************/
- BOOL EXPENTRY DdeEnableCallback(hConv, fEnable)
- HCONV hConv;
- BOOL fEnable;
- {
- PAPPINFO pai;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == 0)
- return(FALSE);
-
- SemCheckOut();
- SemEnter();
- if (hConv == NULL) {
- pai->fEnableCB = fEnable = fEnable ? TRUE : FALSE;
- FlushLst(pai->plstCBExceptions);
- } else if (pai->fEnableCB != fEnable) {
- if (pai->plstCBExceptions == NULL)
- pai->plstCBExceptions = CreateLst(pai->hheapApp, sizeof(HWNDLI));
- AddHwndList((HWND)hConv, pai->plstCBExceptions);
- }
- SemLeave();
- if (fEnable)
- WinPostMsg(pai->hwndDmg, UM_CHECKCBQ, (MPARAM)pai, 0L);
- return(TRUE);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HDMGDATA EXPENTRY DdeAppNameServer(hszApp, afCmd);
- * HSZ hszApp; // referenced app name
- * USHORT afCmd; // action code.
- *
- * Updates or queries the DDE DLL application name server. The DDE name
- * server acts as a filter for initiate messages on behalf of registered
- * applications and serves as a way for an application to determine what
- * other applications are available without the need for wild initiates.
- * Any change in the name server results in XTYP_REGISTER or XTYP_UNREGISTER
- * callbacks to all other applications. Agents will not be allowed to
- * know about any other agent registrations.
- *
- * afCmd:
- *
- * ANS_REGISTER
- * Adds hszApp to the name server. hszApp cannot be NULL.
- * All other applications will receive a registration notification
- * if their callback filters allow it.
- * fSuccess is returned.
- *
- * ANS_UNREGISTER
- * Remove hszApp from the name server. If hszApp==NULL the name server
- * is cleared for the calling application.
- * All other applications will receive a deregistration notification
- * if their callback filters allow it.
- * fSuccess is returned.
- *
- * ANS_QUERYALLBUTME
- * Returns a zero terminated array of hszApps/hApp pairs registered with
- * the name server by all other applications.
- * (Agent applications do not see other agent registered names.)
- * If hszApp is set, only names matching* hszApp are placed into the lis
- * 0 is returned if no applicable names were found.
- *
- * ANS_QUERYMINE
- * Returns a zero terminated array of hszApps registered with the name
- * server by the calling application. If hszApp is set, only names
- * matching hszApp are placed into the list. 0 is returned if no
- * applicable names were found.
- *
- * The following flags may be ORed in with one of the above flags:
- *
- * ANS_FILTERON
- * Turns on dde initiate callback filtering. Only wild app names or
- * those matching a registered name are given to the application for
- * initiate requests or registration notifications.
- *
- * ANS_FILTEROFF
- * Turns off dde initiate callback filtering. All initiate requests
- * and registration notifications are passed onto the application.
- *
- * A 0 is returned on error.
- *
- * PUBDOC END
- *
- * History:
- \***************************************************************************/
- HDMGDATA EXPENTRY DdeAppNameServer(hszApp, afCmd)
- HSZ hszApp;
- USHORT afCmd;
- {
- PAPPINFO pai, paiT;
- BOOL fAgent;
- HDMGDATA hData;
- HSZ hsz;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == 0)
- return(FALSE);
-
- if (afCmd & ANS_FILTERON)
- pai->afCmd |= DMGCMD_FILTERINITS;
-
- if (afCmd & ANS_FILTEROFF)
- pai->afCmd &= ~DMGCMD_FILTERINITS;
-
-
- if (afCmd & (ANS_REGISTER | ANS_UNREGISTER)) {
-
- if (pai->afCmd & DMGCMD_CLIENTONLY) {
- pai->LastError = DMGERR_DLL_USAGE;
- return(FALSE);
- }
-
- fAgent = pai->afCmd & DMGCMD_AGENT ? TRUE : FALSE;
-
- if (hszApp == NULL) {
- if (afCmd & ANS_REGISTER) {
- /*
- * registering NULL is not allowed!
- */
- pai->LastError = DMGERR_INVALIDPARAMETER;
- return(FALSE);
- }
- /*
- * unregistering NULL is just like unregistering each
- * registered name.
- */
- while (PopPileSubitem(pai->pAppNamePile, (PBYTE)&hsz)) {
- for (paiT = pAppInfoList; paiT; paiT = paiT->next) {
- if (pai == paiT || (fAgent && (paiT->afCmd & DMGCMD_AGENT
- continue;
- WinPostMsg(paiT->hwndFrame, UM_UNREGISTER, (MPARAM)hsz,
- (MPARAM)pai->hwndFrame);
- }
- }
- return(TRUE);
- }
-
- if (afCmd & ANS_REGISTER) {
- if (pai->pAppNamePile == NULL)
- pai->pAppNamePile = CreatePile(hheapDmg, sizeof(HSZ), 8);
- AddPileItem(pai->pAppNamePile, (PBYTE)&hszApp, NULL);
- } else
- FindPileItem(pai->pAppNamePile, CmpULONG, (PBYTE)&hszApp,
- FPI_DELETE);
-
- for (paiT = pAppInfoList; paiT; paiT = paiT->next) {
- if (pai == paiT ||
- (fAgent && (paiT->afCmd & DMGCMD_AGENT))) {
- continue;
- }
- WinPostMsg(paiT->hwndFrame,
- afCmd & ANS_REGISTER ? UM_REGISTER : UM_UNREGISTER,
- (MPARAM)hszApp, (MPARAM)pai->hwndFrame);
- }
- return(TRUE);
- }
-
- if (afCmd & ANS_QUERYMINE) {
- hData = PutData(NULL, 10L * sizeof(HSZ),
- 0L, 0L, 0, HDATA_APPOWNED | HDATA_APPFREEABLE, pai);
- if (QueryAppNames(pai, hData, hszApp, 0L)) {
- return(hData);
- } else {
- DdeFreeData(hData);
- return(0L);
- }
- }
-
- if (afCmd & ANS_QUERYALLBUTME) {
- ULONG offAdd, offAddNew;
-
- hData = PutData(NULL, 10L * sizeof(HSZ),
- 0L, 0L, 0, HDATA_APPOWNED | HDATA_APPFREEABLE, pai);
- *((PHSZ)DDES_PABDATA((PDDESTRUCT)hData)) = 0L;
- SemEnter();
- paiT = pAppInfoList;
- offAdd = 0L;
- while (paiT) {
- if (paiT != pai &&
- !(fAgent && (paiT->afCmd & DMGCMD_AGENT))) {
- offAddNew = QueryAppNames(paiT, hData, hszApp, offAdd);
- if (offAddNew == 0 && offAddNew < offAdd) {
- /*
- * memory error most likely.
- */
- SemLeave();
- DdeFreeData(hData);
- return(0L);
- }
- offAdd = offAddNew;
- }
- paiT = paiT->next;
- }
- SemLeave();
- return(hData);
- }
-
- return(0L);
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HDMGDATA EXPENTRY DdeCreateInitPkt(
- * HSZ hszApp, // initiate app string
- * HSZ hszTopic, // initiate topic string
- * HDMGDATA hDmgData) // packet data containing language information.
- *
- * This routine is called by agent applications from within their callback
- * functions which need to store transaction initiate data into a
- * network-portable packet. On return, HDMGDATA contains the packeted
- * data. The calling application must free this data handle when
- * through. Agents are given access to the app string so that they
- * can modify it if needed for their net protocol.
- *
- * PUBDOC END
- \***************************************************************************/
- HDMGDATA EXPENTRY DdeCreateInitPkt(hszApp, hszTopic, hDmgData)
- HSZ hszApp;
- HSZ hszTopic;
- HDMGDATA hDmgData;
- {
- PAPPINFO pai;
-
- hszApp;
- hszTopic;
- hDmgData;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(0);
- /*
- * Add hDataRet to thread list
- */
- pai->LastError = DMGERR_NOT_IMPLEMENTED;
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * BOOL EXPENTRY DdeProcessPkt(
- * HDMGDATA hPkt, // packet from net to process
- * ULONG hAgentFrom); // foreign agent handle associated with this packet.
- *
- * This routine is called by agent applications which have received a packet
- * from another agent. This call performs what actions are requested by the
- * hPkt. If the particular transaction can be done synchronously, a return
- * packet is returned. If not, an XTYP_RTNPKT callback will eventually be
- * sent to the agent and 0 is returned. 0 is also returned on error.
- *
- * hAgentFrom identifies the agent the packet came from.
- *
- * This call should NOT be made from within a callback.
- *
- * PUBDOC END
- \***************************************************************************/
- HDMGDATA EXPENTRY DdeProcessPkt(hPkt, hAgentFrom)
- HDMGDATA hPkt;
- ULONG hAgentFrom;
- {
- PAPPINFO pai;
-
- hPkt;
- hAgentFrom;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(0);
- pai->LastError = DMGERR_NOT_IMPLEMENTED;
- }
-
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * ULONG EXPENTRY DdeQueryVersion()
- *
- * Returns the DLL version number: 0xjjmmuuppL
- * jj = major release;
- * mm = minor release;
- * uu = update number;
- * pp = platform ID; 1=OS/2, 2=DOS, 3=WINDOWS, 4=UNIX, 5=MAC, 6=SUN
- *
- *
- * PUBDOC END
- \***************************************************************************/
- ULONG EXPENTRY DdeQueryVersion()
- {
- return(MAKEULONG(MAKESHORT(1, rup),MAKESHORT(rmm, rmj)));
- }
-
-
-
- /* PUBDOC START
- * ----------------------- Platform specific APIs -----------------------
- * PUBDOC END
- */
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HCONV EXPENTRY DdeConverseWithWindow(
- * HWND hwnd, // server window to converse with
- * HSZ hszApp, // app name to converse on
- * HSZ hszTopic, // topic name to converse on
- * PCONVCONTEXT pCC) // language information to converse on
- *
- * This creates a pre-initiated client conversation with the given hwnd.
- * The conversation is assumed to be on the given app, topic and context.
- * This is useful for implementing such things as drag and drop DDE
- * protocols. hszApp and hszTopic cannot be NULL. See
- * DdeCreateServerWindow().
- *
- * PUBDOC END
- \***************************************************************************/
- HCONV EXPENTRY DdeConverseWithWindow(hwnd, hszApp, hszTopic, pCC)
- HWND hwnd;
- HSZ hszApp, hszTopic;
- PCONVCONTEXT pCC;
- {
- PAPPINFO pai;
-
- UNUSED hwnd;
- UNUSED hszApp;
- UNUSED hszTopic;
- UNUSED pCC;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(0);
-
- if (QuerylatomLength((LATOM)hszApp) == 0 ||
- QuerylatomLength((LATOM)hszTopic) == 0) {
- pai->LastError = DMGERR_INVALIDPARAMETER;
- return(0);
- }
-
- }
-
-
- /***************************** Public Function ****************************\
- * PUBDOC START
- * HWND DdeCreateServerWindow(hszApp, hszTopic, pCC)
- * HSZ hszApp, // app name to accept conversations on.
- * HSZ hszTopic; // topic name to accept conversations on.
- * PCONVCONTEXT pCC; // language information to accept or NULL for sys default
- *
- * This creates a pre_initiated server DDE window for the caller. The
- * server window does not know what client window it will be talking to. As
- * soon as any DDE message is received by the DDE server window, its
- * companion client hwnd is remembered and the conversation is 'locked in'.
- * The hwnd of the server window is returned. hszApp and hszTopic cannot
- * be NULL.
- *
- * Typically, the server app would call CreateServerWindow() and pass the
- * hwnd to some prospective client via some other transport mechanism. The
- * client would then call ConverseWithWindow() with the hwnd it received
- * from the server and then begin DDE transactions using the HCONV returned.
- *
- * A server may pass this hwnd to many potential clients. Only the first
- * one that responds would get 'locked in'. The rest would be out of luck
- * and their API calls would fail. The server window ignores messages that
- * to not fit the app and topic given.
- *
- * PUBDOC END
- \****************************************************************************
- HWND EXPENTRY DdeCreateServerWindow(hszApp, hszTopic, pCC)
- HSZ hszApp, hszTopic;
- PCONVCONTEXT pCC;
- {
- PAPPINFO pai;
- INITINFO ii;
- HWND hwndServer;
-
- hszApp;
- hszTopic;
- pCC;
-
- if ((pai = GetCurrentAppInfo(TRUE)) == NULL)
- return(0);
-
- if (QuerylatomLength((LATOM)hszApp) == 0 ||
- QuerylatomLength((LATOM)hszTopic) == 0) {
- pai->LastError = DMGERR_INVALIDPARAMETER;
- return(0);
- }
-
- if ((hwndServer = CreateServerWindow(pai, hszTopic)) == NULL)
- return(0);
-
- ii.hszAppName = hszApp;
- ii.hszTopic = hszTopic;
- ii.hwndSend =
- ii.hwndFrame = NULL;
- ii.pCC = pCC;
- WinSendMsg(hwndServer, UMSR_INITIATE, 0L, 0L);
- }
-
-
- DDESPY.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DDESPY\DDESPY.C
-
- /***************************** Module Header ******************************\
- * Module Name: ddespy
- *
- * This is a small DDE ddespyr which lets me see whats going on.
- *
- * Created: sanfords
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
- #include "ddespy.h"
-
- /*********** declares *********/
-
- HWND hwndExec = NULL;
-
- SWP gswp[IW_LAST - IW_FIRST + 1];
- PSZ apszTitles[] = {
- "Applications", "Topics", "System Items", "Data"
- };
-
-
- PSZ apszType[] = {
- "0-Type" ,
- "ACK" ,
- "ADVDATA" ,
- "ADVREQ" ,
- "ADVSTART" ,
- "ADVSTOP" ,
- "EXEC" ,
- "INIT" ,
- "INITCONF" ,
- "MONITOR" ,
- "PKT" ,
- "POKE" ,
- "REGISTER" ,
- "REQUEST" ,
- "RTNPKT" ,
- "TERM" ,
- "UNREGISTER" ,
- "WILDINIT" ,
- "XFERCOMP" ,
- "19" ,
- "20" ,
- "21" ,
- "22" ,
- "23" ,
- "24" ,
- "25" ,
- "26" ,
- "27" ,
- "28" ,
- "29" ,
- "30" ,
- "31" ,
- };
-
- PSZ apszState[] = { /* corresponds to convinfo.usStatus */
- "DISCONNECTED" ,
- "CONNECTED" ,
- "NOADVISE" ,
- "ADVISE" ,
- };
-
- PSZ apszStatus[] = { /* corresponds to convionfi.usConvst */
- "NOACTIVITY" ,
- "INCOMPLETE" ,
- "TERMINATED" ,
- "CONNECTED" ,
- "INITIATING" ,
- "REQSENT" ,
- "DATARCVD" ,
- "POKESENT" ,
- "POKEACKRCVD" ,
- "EXECSENT" ,
- "EXECACKRCVD" ,
- "ADVSENT" ,
- "UNADVSENT" ,
- "ADVACKRCVD" ,
- "UNADVACKRCVD" ,
- "ADVDATASENT" ,
- "ADVDATAACKRCVD",
- };
-
-
- #define GetLBCount(hw) (SHORT)WinSendMsg((hw), LM_QUERYITEMCOUNT, 0L, 0L)
- #define GetLBSelectedItem(hw) \
- (SHORT)WinSendMsg((hw), LM_QUERYSELECTION, (MPARAM)LIT_FIRST, 0L)
- #define GetLBItemHandle(hw, i) \
- (ULONG)WinSendMsg((hw), LM_QUERYITEMHANDLE, (MPARAM)(i), 0L)
- #define GetLBItemText(hw, i, cch, psz) \
- (ULONG)WinSendMsg((hw), LM_QUERYITEMTEXT, MPFROM2SHORT((i),(cch))
- #define DeleteLBItem(hw, i) WinSendMsg(hw, LM_DELETEITEM, MPFROMSHORT(i), 0L)
- #define NotifyOwner(hwnd, msg, mp1, mp2) \
- (WinSendMsg(WinQueryWindow(hwnd, QW_OWNER, FALSE), msg, mp1, mp2)
-
-
- void cdecl main(int argc, char **argv);
- void ResizeChildren(USHORT cxNew, USHORT cyNew);
- HDMGDATA EXPENTRY dataxfer(HCONV hConv, HSZ hszTopic, HSZ hszItem,
- USHORT usFmt, USHORT usType, HDMGDATA hDmgData);
- MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- MRESULT EXPENTRY GetTimeoutDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM
- MRESULT EXPENTRY EnhancedEFWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM
- MRESULT EXPENTRY ExecDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2);
- void Refresh(void);
- SHORT InsertLBItem(HWND hwndLB, PSZ psz, ULONG ulHandle);
- void SetLBEntries(HCONV hConv, HSZ hszItem, USHORT iwlb);
- void UpdateQueue(HWND hwndCB, HCONV hConv);
- void ConvInfoToString(PCONVINFO pci, PSZ psz, USHORT cbMax);
- PSZ mylstrcat(PSZ psz1, PSZ psz2, PSZ pszLast);
- int lstrlen(PSZ psz);
-
- /************* GLOBAL VARIABLES ************/
-
- HAB hab;
- HMQ hmq;
- HHEAP hheap;
- HWND hwndFrame;
- HWND hwndClient;
- USHORT cyTitles;
- USHORT cxBorder;
- HCONVLIST hConvListMain;
- HSZ hszSysTopic;
- HSZ hszSysItemTopics;
- HSZ hszSysItemSysItems;
- ULONG gTimeout = 1000L;
- PFNWP lpfnSysEFWndProc;
-
- void cdecl main(argc, argv)
- int argc;
- char **argv;
- {
- USHORT err;
- QMSG qmsg;
-
- argc; argv;
-
- hab = WinInitialize(0);
- hmq = WinCreateMsgQueue(hab, 0);
- hheap = WinCreateHeap(0, 0, 0, 0, 0, HM_MOVEABLE);
-
- if (!WinRegisterClass(hab, "DDESpyr Class", ClientWndProc, CS_SIZEREDRAW,
- goto abort;
-
- cyTitles = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYTITLEBAR);
- cxBorder = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
-
- hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE, NULL,
- (PSZ)"DDESpyr Class",
- (PSZ)"", WS_VISIBLE, (HMODULE)NULL, IDR_MAIN,
- &hwndClient);
-
- WinSetWindowText(hwndFrame, "DDE Spy");
- if (err = DdeInitialize((PFNCALLBACK)dataxfer, 0L, 0L)) {
- DdePostError(err);
- goto abort;
- }
-
- hszSysTopic = DdeGetHsz((PSZ)SZDDESYS_TOPIC, 0, 0);
- hszSysItemTopics = DdeGetHsz((PSZ)SZDDESYS_ITEM_TOPICS, 0, 0);
- hszSysItemSysItems = DdeGetHsz((PSZ)SZDDESYS_ITEM_SYSITEMS, 0, 0);
-
- Refresh();
-
- while (WinGetMsg(hab, &qmsg, 0, 0, 0)) {
- WinDispatchMsg(hab, &qmsg);
- }
-
- DdeUninitialize();
- abort:
- if (hwndFrame)
- WinDestroyWindow(hwndFrame);
- if (hheap) {
- WinDestroyHeap(hheap);
- }
- WinTerminate(hab);
- DosExit(TRUE, 0);
- }
-
-
- MRESULT EXPENTRY ClientWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1, mp2;
- {
- USHORT i;
-
- switch (msg) {
- case WM_CREATE:
- /*
- * initialize globals
- */
- hwndClient = hwnd;
- for (i = IW_APPSLBOX; i <= IW_ITEMSLBOX; i++) {
- gswp[i].hwnd = WinCreateWindow(hwndClient, WC_LISTBOX, "",
- WS_VISIBLE | LS_NOADJUSTPOS, 0, 0, 0, 0, hwndClient,
- HWND_TOP, i, NULL, NULL);
- }
- for (i = IW_APPSTITLE; i <= IW_DATATITLE; i++) {
- gswp[i].hwnd = WinCreateWindow(hwndClient, WC_STATIC,
- apszTitles[i - IW_APPSTITLE],
- WS_VISIBLE | SS_TEXT | DT_CENTER | DT_BOTTOM,
- 0, 0, 0, 0, hwndClient,
- HWND_TOP, i, NULL, NULL);
- }
- gswp[IW_DATATEXT].hwnd = WinCreateWindow(hwndClient, WC_STATIC, "",
- WS_VISIBLE | SS_TEXT | DT_WORDBREAK,
- 0, 0, 0, 0, hwndClient,
- HWND_TOP, i, NULL, NULL);
-
- break;
-
- case WM_COMMAND:
- switch (LOUSHORT(mp1)) {
- case IDM_REFRESH:
- Refresh();
- break;
-
- case IDM_SETTIMEOUT:
- gTimeout = (USHORT)WinDlgBox(hwndFrame, NULL,
- (PFNWP)GetTimeoutDlgProc,
- (HMODULE)NULL, IDD_GETTIMEOUT, NULL);
- break;
-
- case IDM_EXEC:
- WinDlgBox(HWND_DESKTOP, hwnd, ExecDlgProc, NULL, IDD_EXEC, NULL);
- break;
- }
- break;
-
- case WM_CONTROL:
- switch (LOUSHORT(mp1)) {
- case IW_APPSLBOX:
- switch (HIUSHORT(mp1)) {
- case LN_SELECT:
- hwnd = gswp[IW_APPSLBOX].hwnd;
- SetLBEntries((HCONV)GetLBItemHandle(hwnd,
- GetLBSelectedItem(hwnd)),
- hszSysItemTopics, IW_TOPICSLBOX);
- SetLBEntries((HCONV)GetLBItemHandle(hwnd,
- GetLBSelectedItem(hwnd)),
- hszSysItemSysItems, IW_ITEMSLBOX);
- break;
- }
- break;
-
- case IW_TOPICSLBOX:
- break;
-
- case IW_ITEMSLBOX:
- break;
-
- default:
- goto DoDefAction;
- }
- break;
-
- case WM_SIZE:
- /*
- * resize children
- */
- ResizeChildren(SHORT1FROMMP(mp2), SHORT2FROMMP(mp2));
- break;
-
- case WM_ERASEBACKGROUND:
- return(TRUE);
- break;
-
- default:
- DoDefAction:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- }
- return(0L);
- }
-
-
-
- void ResizeChildren(cxNew, cyNew)
- USHORT cxNew, cyNew;
- {
- USHORT i;
-
- for (i = IW_FIRST; i <= IW_LAST; i++) {
- gswp[i].fs = SWP_SIZE | SWP_MOVE | SWP_SHOW;
- gswp[i].hwndInsertBehind = HWND_TOP;
- }
-
- for (i = IW_APPSTITLE; i <= IW_ITEMSTITLE; i++) {
- gswp[i].x =
- gswp[i - IW_APPSTITLE + IW_APPSLBOX].x = i == IW_APPSTITLE ? -cxBorde
- gswp[i - 1].x + gswp[i - 1].cx - cxBorder;
-
- gswp[i].y = cyNew - cyTitles;
- gswp[i - IW_APPSTITLE + IW_APPSLBOX].y = cyNew / 2;
-
- gswp[i].cx =
- gswp[i - IW_APPSTITLE + IW_APPSLBOX].cx = cxNew / 3;
-
- gswp[i].cy = cyTitles;
- gswp[i - IW_APPSTITLE + IW_APPSLBOX].cy = (cyNew / 2) - cyTitles;
- }
-
- gswp[IW_ITEMSLBOX].cx = cxNew - gswp[IW_ITEMSLBOX].x + cxBorder;
-
- gswp[IW_DATATITLE].cy = cyTitles;
- gswp[IW_DATATITLE].y =
- gswp[IW_DATATEXT].cy = cyNew / 2 - cyTitles;
-
- gswp[IW_DATATITLE].cx =
- gswp[IW_DATATEXT].cx = cxNew;
-
- WinSetMultWindowPos(hab, gswp, IW_DATATEXT - IW_APPSTITLE + 1);
- }
-
-
- void Refresh()
- {
- HCONV hConv;
- register NPSZ npszAppName;
- CONVINFO ci;
- USHORT cb;
-
- WinLockWindowUpdate(HWND_DESKTOP, gswp[IW_APPSLBOX].hwnd);
- WinSendMsg(gswp[IW_APPSLBOX].hwnd, LM_DELETEALL, 0L, 0L);
- WinSendMsg(gswp[IW_TOPICSLBOX].hwnd, LM_DELETEALL, 0L, 0L);
- WinSendMsg(gswp[IW_ITEMSLBOX].hwnd, LM_DELETEALL, 0L, 0L);
-
- hConvListMain = DdeBeginEnumServers(0L, hszSysTopic, hConvListMain, NULL,
- if (hConvListMain) {
- hConv = 0;
- while (hConv = DdeGetNextServer(hConvListMain, hConv)) {
- DdeQueryConvInfo(hConv, &ci, QID_SYNC);
- if (ci.hszAppPartner != 0) {
- cb = DdeGetHszString(ci.hszAppPartner, NULL, 0L) + 1;
- npszAppName = WinAllocMem(hheap, cb);
- DdeGetHszString(ci.hszAppPartner, (PSZ)npszAppName, (ULONG)cb
- InsertLBItem(gswp[IW_APPSLBOX].hwnd, (PSZ)npszAppName,
- (ULONG)hConv);
- WinFreeMem(hheap, npszAppName, cb);
- } else {
- InsertLBItem(gswp[IW_APPSLBOX].hwnd, SZINDETERMINATE,
- (ULONG)hConv);
- }
- }
- }
- WinLockWindowUpdate(HWND_DESKTOP, NULL);
- }
-
-
- SHORT InsertLBItem(hwndLB, psz, ulHandle)
- HWND hwndLB;
- PSZ psz;
- ULONG ulHandle;
- {
- SHORT ili;
-
- ili = (SHORT)WinSendMsg(hwndLB, LM_INSERTITEM, (MPARAM)LIT_SORTASCENDING,
- (MPARAM)psz);
- WinSendMsg(hwndLB, LM_SETITEMHANDLE, MPFROMSHORT(ili), (MPARAM)ulHandle);
- return(ili);
- }
-
-
- void SetLBEntries(hConv, hszItem, iwlb)
- HCONV hConv;
- HSZ hszItem;
- USHORT iwlb;
- {
- NPSZ npsz, npszT1, npszT2;
- BOOL fDone = 0;
- ULONG cb;
- HDMGDATA hDmgData;
-
- hDmgData = DdeClientXfer(0L, 0L, hConv, hszItem, DDEFMT_TEXT,
- XTYP_REQUEST, gTimeout, NULL);
-
- if (hDmgData == 0) {
- DdePostError(DdeGetLastError());
- return;
- }
-
- cb = DdeGetData(hDmgData, NULL, 0L, 0L);
- /*
- * BUG - may later want to handle the case for cb > 0xFFFF
- */
- npsz = WinAllocMem(hheap, (USHORT)cb);
- if (npsz == NULL) {
- DdePostError(DMGERR_MEMORY_ERROR);
- return;
- }
- if (DdeGetData(hDmgData, (PBYTE)npsz, cb, 0L) == 0) {
- DdePostError(DdeGetLastError());
- goto Exit;
- }
- npszT1 = npszT2 = npsz;
- WinLockWindowUpdate(HWND_DESKTOP, gswp[iwlb].hwnd);
- WinSendMsg(gswp[iwlb].hwnd, LM_DELETEALL, 0L, 0L);
- while (!fDone) {
- while (*npszT2 != '\t' && *npszT2 != '\0')
- npszT2++;
- if (*npszT2 == '\t') {
- *npszT2 = '\0';
- npszT2++;
- } else
- fDone = TRUE;
- InsertLBItem(gswp[iwlb].hwnd, (PSZ)npszT1,
- (ULONG)DdeGetHsz(npszT1, 0, 0));
- npszT1 = npszT2;
- }
- WinLockWindowUpdate(HWND_DESKTOP, NULL);
-
- Exit:
- WinFreeMem(hheap, (NPBYTE)npsz, (USHORT)cb);
- return;
- }
-
-
-
- HDMGDATA EXPENTRY dataxfer(hConv, hszTopic, hszItem, usFmt, usType,
- hDmgData)
- HCONV hConv;
- HSZ hszTopic;
- HSZ hszItem;
- USHORT usFmt;
- USHORT usType;
- HDMGDATA hDmgData;
- {
- hConv; hszTopic; hszItem; usFmt; usType; hDmgData;
-
- switch (usType) {
- case XTYP_XFERCOMPLETE:
- if (hwndExec) {
- if (DdeCheckQueue(hConv, &hDmgData, (ULONG)hDmgData, 0L)) {
- PSZ psz;
- if (psz = (PSZ)DdeAccessData(hDmgData)) {
- WinSetDlgItemText(hwndExec, IDEF_DATA, psz);
- /*
- * Free this data here.
- */
- DdeFreeData(hDmgData);
- }
- }
- }
- break;
- }
- return(0);
- }
-
-
- MRESULT EXPENTRY GetTimeoutDlgProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- USHORT usValue;
-
- switch (msg) {
- case WM_INITDLG:
- /*
- * set up our entryfield to be enhanced.
- */
- WinSetDlgItemShort(hwnd, IDC_EF, (USHORT)gTimeout, FALSE);
- lpfnSysEFWndProc = WinSubclassWindow(WinWindowFromID(hwnd, IDC_EF),
- EnhancedEFWndProc);
- break;
-
- case ENHAN_ENTER:
- /*
- * when the user hits the enter key, it will be passed from the
- * entryfield to here and we will use it as a signal to exit.
- */
- WinQueryDlgItemShort(hwnd, IDC_EF, &usValue, FALSE);
- WinDismissDlg(hwnd, usValue);
- break;
-
- default:
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0);
- }
-
- MRESULT EXPENTRY EnhancedEFWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch (msg) {
- case WM_CHAR:
- if (LOUSHORT(mp1) & KC_SCANCODE &&
- LOUSHORT(mp1) & KC_KEYUP &&
- /*---HACK ALERT!---*/
- LOBYTE(LOUSHORT(mp2)) == 0x0d) {
- NotifyOwner(hwnd, ENHAN_ENTER,
- (MPARAM)WinQueryWindowUShort(hwnd, QWS_ID), 0L);
- }
- break;
- }
- return(lpfnSysEFWndProc(hwnd, msg, mp1, mp2));
- }
-
-
-
- MRESULT EXPENTRY ExecDlgProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- static UCHAR szT[255];
- static HCONV hConv = NULL;
- register USHORT i;
- USHORT cb;
- register USHORT xtyp;
- HDMGDATA hDmgData;
- HSZ hszApp, hszItem, hszTopic;
- BOOL fAssync;
- ULONG xid;
-
- switch (msg) {
- case WM_INITDLG:
- hwndExec = hwnd;
- WinSendDlgItemMsg(hwnd, IDEF_DATA, EM_SETTEXTLIMIT, (MPARAM)MAX_QSTRI
- WinSendDlgItemMsg(hwnd, IDCB_QDATA, EM_SETTEXTLIMIT, (MPARAM)MAX_QSTR
- if ((i = GetLBSelectedItem(gswp[IW_APPSLBOX].hwnd)) != LIT_NONE) {
- GetLBItemText(gswp[IW_APPSLBOX].hwnd, i, 255, szT);
- WinSetDlgItemText(hwnd, IDEF_APP, szT);
- }
- if ((i = GetLBSelectedItem(gswp[IW_TOPICSLBOX].hwnd)) != LIT_NONE) {
- GetLBItemText(gswp[IW_TOPICSLBOX].hwnd, i, 255, szT);
- WinSetDlgItemText(hwnd, IDEF_TOPIC, szT);
- }
- if ((i = GetLBSelectedItem(gswp[IW_ITEMSLBOX].hwnd)) != LIT_NONE) {
- GetLBItemText(gswp[IW_ITEMSLBOX].hwnd, i, 255, szT);
- WinSetDlgItemText(hwnd, IDEF_ITEM, szT);
- }
- WinSendDlgItemMsg(hwnd, IDRB_REQUEST, BM_CLICK, 0L, 0L);
- break;
-
- case WM_CONTROL:
- case WM_COMMAND:
- switch (LOUSHORT(mp1)) {
- case MBID_CANCEL:
- if (hConv != NULL)
- DdeDisconnect(hConv);
- hConv = NULL;
- WinDismissDlg(hwnd, 0);
- break;
-
- case IDC_QFLUSH:
- DdeCheckQueue(hConv, NULL, QID_NEWEST, CQ_FLUSH);
- WinSetDlgItemText(hwnd, IDCB_QDATA, "");
- UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);
- break;
-
- case IDC_QUPDATE:
- UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);
- WinSendDlgItemMsg(hwnd, IDCB_QDATA, CBM_SHOWLIST, (MPARAM)TRUE, 0
- break;
-
- case IDC_DOIT:
- i = (USHORT)WinSendDlgItemMsg(hwnd, IDRB_ADVSTART,
- BM_QUERYCHECKINDEX, 0L, 0L) + IDRB_ADVSTART;
- WinQueryDlgItemText(hwnd, IDEF_APP, 255, szT);
- hszApp = DdeGetHsz(szT, 0, 0);
- WinQueryDlgItemText(hwnd, IDEF_TOPIC, 255, szT);
- hszTopic = DdeGetHsz(szT, 0, 0);
- WinQueryDlgItemText(hwnd, IDEF_ITEM, 255, szT);
- hszItem = DdeGetHsz(szT, 0, 0);
- if (i != IDRB_REQUEST) {
- WinQueryDlgItemText(hwnd, IDEF_DATA, 255, szT);
- cb = WinQueryDlgItemTextLength(hwnd, IDEF_DATA);
- }
- if (hConv == NULL && !(hConv = DdeConnect(hszApp, hszTopic, NULL,
- DdePostError(DdeGetLastError());
- if (LOUSHORT(mp1) == MBID_OK)
- WinDismissDlg(hwnd, 0);
- return(0);
- }
- switch (i) {
- case IDRB_REQUEST:
- xtyp = XTYP_REQUEST;
- goto XferOut;
- break;
- case IDRB_ADVSTART:
- xtyp = XTYP_ADVSTART;
- goto XferOut;
- break;
- case IDRB_ADVSTOP:
- xtyp = XTYP_ADVSTOP;
- goto XferOut;
- break;
- case IDRB_POKE:
- xtyp = XTYP_POKE;
- goto XferOut;
- break;
- case IDRB_EXECUTE:
- xtyp = XTYP_EXEC;
- XferOut:
- fAssync = (BOOL)WinSendDlgItemMsg(hwnd, IDCBX_ASSYNC,
- BM_QUERYCHECK, 0L, 0L);
- if (!(hDmgData = DdeClientXfer((PBYTE)szT, (ULONG)cb + 1,
- hConv, hszItem, DDEFMT_TEXT, xtyp,
- fAssync ? TIMEOUT_ASYNC : gTimeout, &xid)))
- DdePostError(DdeGetLastError());
-
- if (fAssync) {
- UpdateQueue(WinWindowFromID(hwnd, IDCB_QDATA), hConv);
- } else {
- if (i == IDRB_REQUEST) {
- DdeGetData(hDmgData, szT, 255L, 0L);
- DdeFreeData(hDmgData);
- WinSetWindowText(gswp[IW_DATATEXT].hwnd, szT);
- WinSetDlgItemText(hwnd, IDEF_DATA, szT);
- }
- }
-
- }
- break;
- }
- break;
-
- case WM_DESTROY:
- hwndExec = NULL;
- default:
- return(WinDefDlgProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0);
- }
-
-
-
- void UpdateQueue(hwndCB, hConv)
- HWND hwndCB;
- HCONV hConv;
- {
- SHORT lit;
- SHORT litSel = LIT_FIRST;
- CONVINFO ci;
- ULONG id, idSel;
- USHORT cItems;
- char szT[MAX_QSTRING];
-
- lit = (SHORT)WinSendMsg(hwndCB, LM_QUERYSELECTION,
- MPFROMSHORT(LIT_FIRST), 0L);
- idSel = (SHORT)WinSendMsg(hwndCB, LM_QUERYITEMHANDLE, MPFROMSHORT(lit), 0
- WinSendMsg(hwndCB, LM_DELETEALL, 0L, 0L);
- cItems = (USHORT)DdeCheckQueue(hConv, NULL, QID_NEWEST, CQ_COUNT);
- id = DdeCheckQueue(hConv, NULL, QID_NEWEST, 0L);
- while (cItems--) {
- DdeQueryConvInfo(hConv, &ci, id);
- ConvInfoToString(&ci, szT, MAX_QSTRING);
- lit = (SHORT)WinSendMsg(hwndCB, LM_INSERTITEM, MPFROMSHORT(LIT_END),
- WinSendMsg(hwndCB, LM_SETITEMHANDLE, MPFROMSHORT(lit), (MPARAM)id);
- if (id == idSel)
- litSel = lit;
- id = DdeCheckQueue(hConv, NULL, id, CQ_NEXT);
- }
- WinSendMsg(hwndCB, LM_SELECTITEM, MPFROMSHORT(litSel), (MPARAM)TRUE);
- }
-
-
-
- void ConvInfoToString(pci, psz, cbMax)
- PCONVINFO pci;
- PSZ psz;
- USHORT cbMax;
- {
- PSZ pszLast;
- char szT[100];
-
- pszLast = psz + cbMax - 1;
- *psz = '\0';
- psz = mylstrcat(psz, apszType[(pci->usType >> 4) && 0x1F], pszLast);
- psz = mylstrcat(psz, ": ", pszLast);
- psz = mylstrcat(psz, apszState[pci->usStatus & ST_CONNECTED ? 1 : 0], psz
- psz = mylstrcat(psz, " ", pszLast);
- psz = mylstrcat(psz, apszState[pci->usStatus & ST_ADVISE ? 3 : 2], pszLas
- psz = mylstrcat(psz, " ", pszLast);
- psz = mylstrcat(psz, apszStatus[pci->usConvst], pszLast);
- psz = mylstrcat(psz, " ", pszLast);
- if (pci->usFmt == DDEFMT_TEXT) {
- psz = mylstrcat(psz, "TEXT", pszLast);
- } else {
- DdeGetHszString(pci->hszItem, szT, 100L);
- psz = mylstrcat(psz, szT, pszLast);
- }
- psz = mylstrcat(psz, " ", pszLast);
- DdeGetHszString(pci->hszItem, szT, 100L);
- psz = mylstrcat(psz, szT, pszLast);
-
- if (pci->LastError) {
- psz = mylstrcat(psz, " ", pszLast);
- DdeGetErrorString(pci->LastError, pszLast - psz, psz);
- }
- pszLast = '\0';
- }
-
-
- /***************************** Public Function ****************************\
- * Concatonates psz1 and psz2 into psz1.
- * returns psz pointing to end of concatonated string.
- * pszLast marks point at which copying must stop. This makes this operation
- * safe for limited buffer sizes.
- *
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- PSZ mylstrcat(psz1, psz2, pszLast)
- PSZ psz1, psz2, pszLast;
- {
- psz1 += lstrlen(psz1);
- while (*psz2 != '\0' && psz1 < pszLast) {
- *psz1++ = *psz2++;
- }
- *psz1 = '\0';
- return(psz1);
- }
-
-
- /***************************** Private Function ****************************\
- *
- * returns string length not counting null terminator.
- *
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- int lstrlen(psz)
- PSZ psz;
- {
- int c = 0;
-
- while (*psz != 0) {
- psz++;
- c++;
- }
- return(c);
- }
-
-
-
- DEMO.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DEMO\DEMO.C
-
- /****************************** Module Header ******************************\
- * Module Name: demo.c - Demo application
- *
- * Created:
- *
- * Copyright (c) 1987 Microsoft Corporation
- *
- \***************************************************************************/
-
- #include "demo.h"
- #include <stdlib.h>
-
- /************* GLOBAL VARIABLES */
-
- char szDemoClass[] = "Demo";
-
- HAB hab;
- HMQ hmqDemo;
- HWND hwndDemo;
- HWND hwndDemoFrame;
- HCONV hconv = NULL;
- HSZ hszTitle, hszTopicChase, hszItemPos;
- USHORT fmtSWP;
- SWP SWPTarget = { 0 };
- PFNWP RealFrameProc;
- BOOL flee = FALSE;
- USHORT cServers = 0;
- USHORT cxScreen, cyScreen;
-
- #define TIMEOUT 100
- #define TIMERSPEED 1000
-
- /**************************************/
-
- VOID CommandMsg(USHORT cmd)
- {
- UNUSED cmd;
- }
-
- BOOL DemoInit()
- {
- hab = WinInitialize(0);
-
- hmqDemo = WinCreateMsgQueue(hab, 0);
-
- cxScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CXSCREEN);
- cyScreen = (USHORT)WinQuerySysValue(HWND_DESKTOP, SV_CYSCREEN);
- srand(2);
-
- if (!WinRegisterClass(hab, szDemoClass, (PFNWP)DemoWndProc,
- CS_SIZEREDRAW, 0))
- return(FALSE);
-
- /*
- * Initialize the ddeml
- */
- if (DdeInitialize((PFNCALLBACK)callback, 0L, 0L))
- return(FALSE);
-
- /*
- * Now create HSZs for each of our DDE strings.
- */
- fmtSWP = WinAddAtom(WinQuerySystemAtomTable(), "SWP FORMAT");
- hszTitle = DdeGetHsz("Demo", 0, 0);
- hszTopicChase = DdeGetHsz("Chaser", 0, 0);
- hszItemPos = DdeGetHsz("Position", 0, 0);
-
- /*
- * let others know we are here - available as a server and turn on
- * filtering so we don't get bothered with any initiates for any
- * other app names.
- */
- DdeAppNameServer(hszTitle, ANS_REGISTER | ANS_FILTERON);
-
- return(TRUE);
- }
-
- int cdecl main(int argc, char** argv)
- {
- ULONG fcf;
- QMSG qmsg;
-
- UNUSED argc;
- UNUSED argv;
-
- if (!DemoInit()) {
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- return(0);
- }
-
- fcf = FCF_STANDARD;
-
- hwndDemoFrame = WinCreateStdWindow(
- HWND_DESKTOP,
- WS_VISIBLE,
- &fcf,
- szDemoClass,
- "",
- WS_VISIBLE,
- NULL,
- IDR_DEMO,
- &hwndDemo);
-
- WinSetFocus(HWND_DESKTOP, hwndDemo);
-
- while (WinGetMsg(hab, (PQMSG)&qmsg, NULL, 0, 0)) {
- WinDispatchMsg(hab, (PQMSG)&qmsg);
- }
-
- WinDestroyWindow(hwndDemoFrame);
-
- WinDestroyMsgQueue(hmqDemo);
- WinTerminate(hab);
-
- return(0);
- }
-
- /********** Demo Window Procedure **************/
-
- MRESULT FAR PASCAL DemoWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- HPS hps;
- RECTL rclPaint;
- SWP swp;
- SHORT speed;
-
- switch (msg) {
- case WM_CREATE:
- /* Set up this global first thing in case we need it elsewhere */
- hwndDemo = hwnd;
- hwndDemoFrame = WinQueryWindow(hwnd, QW_PARENT, FALSE);
- RealFrameProc = WinSubclassWindow(hwndDemoFrame, DemoFrameWndProc);
- WinSetWindowPos(hwndDemoFrame, NULL, 0, 0, 0, 0, SWP_MINIMIZE | SWP_S
- /*
- * start the timer so we will keep looking for another app like ours
- * to chase.
- */
- WinStartTimer(hab, hwndDemo, 1, TIMERSPEED);
- return(MRFROMSHORT(FALSE));
- break;
-
- case WM_TIMER:
- /*
- * We use a timer to keep us moving.
- */
- if (!hconv) {
- HDMGDATA hData;
- PHSZHAPP phszhapp;
- /*
- * no active conversation, try to make one.
- */
- WinStopTimer(hab, hwndDemo, 1);
- /*
- * find out if any others like us are out there
- */
- hData = DdeAppNameServer(hszTitle, ANS_QUERYALLBUTME);
- if (!hData) {
- /*
- * wait till others arrive.
- */
- return(0);
- }
- /*
- * extract the first hApp from the hData so we can connect to it
- */
- phszhapp = (PHSZHAPP)DdeAccessData(hData);
- if (phszhapp->hsz == 0) {
- DdeFreeData(hData);
- return(0);
- }
- /*
- * perform directed connection to our target
- */
- hconv = DdeConnect(hszTitle, hszTopicChase, NULL, phszhapp->hApp)
- /*
- * free the hData now that we are done using it.
- */
- DdeFreeData(hData);
- WinStartTimer(hab, hwndDemo, 1, TIMERSPEED);
- if (!hconv) {
- /*
- * cant make one, try again later.
- */
- return(0);
- }
- /*
- * Get the target's position into SWPTarget.
- */
- if (hData = DdeClientXfer(NULL, 0L, hconv, hszItemPos, fmtSWP,
- XTYP_REQUEST, TIMEOUT, NULL)) {
- DdeCopyBlock(DdeAccessData(hData), (PBYTE)&SWPTarget,
- sizeof(SWP));
- DdeFreeData(hData);
- }
- /*
- * set up an advise loop so our moving target keeps us informed
- * of where he is.
- */
- DdeClientXfer(NULL, 0L, hconv, hszItemPos, fmtSWP,
- XTYP_ADVSTART, TIMEOUT, NULL);
- }
-
- if (WinIsWindow(hab, SWPTarget.hwnd)) {
- /*
- * target data must be valid, move toward it.
- */
- speed = 1;
- WinQueryWindowPos(hwndDemoFrame, &swp);
- if (swp.x > SWPTarget.x)
- swp.x -= speed;
- if (swp.x < SWPTarget.x)
- swp.x += speed;
- if (swp.y > SWPTarget.y)
- swp.y -= speed;
- if (swp.y < SWPTarget.y)
- swp.y += speed;
- swp.fs = SWP_MOVE | SWP_NOADJUST;
- WinSetMultWindowPos(hab, &swp, 1);
- if ((swp.x == SWPTarget.x) && (swp.y == SWPTarget.y) && (!flee))
- /*
- * he's cought stop chasing him and go find another.
- */
- WinAlarm(HWND_DESKTOP, WA_NOTE);
- DdeDisconnect(hconv);
- hconv = NULL;
- /*
- * move to a random position
- */
- WinSetWindowPos(hwndDemoFrame, HWND_TOP, rand() % cxScreen,
- rand() % cyScreen, 0, 0,
- SWP_MOVE | SWP_ZORDER | SWP_NOADJUST);
- }
- } else if (hconv) {
- /*
- * Target is invalid, disconnect and try a reconnect later.
- */
- DdeDisconnect(hconv);
- hconv = NULL;
- }
- break;
-
- case WM_PAINT:
- hps = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);
- DemoPaint(hwnd, hps, &rclPaint);
- WinEndPaint(hps);
- break;
-
- case WM_COMMAND:
- CommandMsg(LOUSHORT(mp1));
- break;
-
- default:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0L);
- }
-
-
-
- MRESULT FAR PASCAL DemoFrameWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM
- {
- switch (msg) {
- case WM_MOVE:
- DdePostAdvise(hszTopicChase, hszItemPos);
- /* fall through */
- default:
- return(RealFrameProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0L);
- }
-
-
- VOID DemoPaint(HWND hwnd, HPS hps, RECTL* prcl)
- {
- RECTL rcl;
-
- UNUSED prcl;
-
- /* get window interior rect */
- WinQueryWindowRect(hwnd, &rcl);
-
- /* print "Hello World" centered horizontally and vertically */
- WinDrawText(hps, -1, "Hello World", &rcl, SYSCLR_WINDOWTEXT,
- SYSCLR_WINDOW, DT_CENTER | DT_VCENTER | DT_ERASERECT);
-
- /* draw interior border */
- WinDrawBorder(hps, &rcl, 6, 6, SYSCLR_WINDOWTEXT, SYSCLR_WINDOW,
- DB_STANDARD);
- }
-
-
-
- HDMGDATA EXPENTRY callback(
- HCONV hConv,
- HSZ hszTopic,
- HSZ hszItem,
- USHORT usFmt,
- USHORT usType,
- HDMGDATA hDmgData)
- {
- SWP swp;
-
- UNUSED hConv;
-
- if (usType == XTYP_REGISTER && hszItem == hszTitle && !hconv) {
- /*
- * someone else came onboard, if we are looking for a target,
- * restart our clock.
- */
- WinStartTimer(hab, hwndDemo, 1, TIMERSPEED);
- }
-
- /*
- * we only care about stuff on our topic.
- */
- if (hszTopic != hszTopicChase)
- return(0);
-
- switch (usType) {
-
- case XTYP_ADVSTART:
- /*
- * Always allow advises on our item
- */
- return(hszItem == hszItemPos);
- break;
-
- case XTYP_ADVDATA:
- /*
- * Always accept advise data on our target's latest position.
- */
- if (hszItem == hszItemPos)
- DdeGetData(hDmgData, (PBYTE)&SWPTarget, sizeof(SWP), 0L);
- DdeFreeData(hDmgData);
- return(0);
- break;
-
- case XTYP_INIT:
- /*
- * always allow others to initiate with us on our topic.
- */
- return(hszItem == hszTitle && hszTopic == hszTopicChase);
- break;
-
- case XTYP_REQUEST:
- case XTYP_ADVREQ:
- /*
- * Respond to data requests as to our whereabouts item and format are
- * ok.
- */
- if (hszItem != hszItemPos || usFmt != fmtSWP)
- return(0);
- WinQueryWindowPos(hwndDemoFrame, &swp);
- return(DdePutData((PBYTE)&swp, sizeof(SWP), 0L, hszItemPos, fmtSWP, 0
- break;
-
- default:
- return(0);
- }
- }
-
-
-
-
-
- DIALOGS.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CLOCK\DIALOGS.C
-
- /*
- dialogs.c Dialog procedures for PM Clock Application
-
- Created by Microsoft Corporation, 1989
- */
- #define INCL_WINDIALOGS
- #define INCL_WINBUTTONS
- #define INCL_WINSYS
- #include <os2def.h>
- #include <pmwin.h>
- #include "dialogs.h"
-
- /* defined in paint.c */
- extern USHORT usMajorTickPref ;
- extern USHORT usMinorTickPref ;
- extern LONG clrBackground ;
- extern LONG clrFace ;
- extern LONG clrHourHand ;
- extern LONG clrMinuteHand ;
-
- /* defined in clock.c */
- extern HWND hwndFrame ;
-
- /*
- ClkAboutDlgProc() "About..." dialog
-
- Returns: MRESULT, 0 or return value from WinDefDlgProc
- */
- MRESULT EXPENTRY ClkAboutDlgProc ( HWND hwnd , USHORT usMsg ,
- MPARAM mp1 , MPARAM mp2 )
- {
- if ( usMsg == WM_COMMAND ) {
- WinDismissDlg ( hwnd , TRUE ) ;
- return 0L ;
- }
- else return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;
- }
-
-
- /*
- ClkTicksDlgProc() "Ticks..." dialog
-
- Returns: MRESULT, 0 or return value from WinDefDlgProc
- */
- MRESULT EXPENTRY ClkTicksDlgProc ( HWND hwnd , USHORT usMsg ,
- MPARAM mp1 , MPARAM mp2 )
- {
- static USHORT usMajorTickSel ;
- static USHORT usMinorTickSel ;
- USHORT usButtonID ;
-
- switch ( usMsg ) {
-
- case WM_INITDLG :
-
- /* show the current major tick preference */
- WinSendMsg ( WinWindowFromID ( hwnd ,
- CLKTM_MAJOR | usMajorTickPref ) ,
- BM_SETCHECK , MPFROM2SHORT ( TRUE , NULL ) , NULL )
-
- /* show the current minor tick preference */
- WinSendMsg ( WinWindowFromID ( hwnd ,
- CLKTM_MINOR | usMinorTickPref ) ,
- BM_SETCHECK , MPFROM2SHORT ( TRUE , NULL ) , NULL )
-
- /* load the selection values from the preferences */
- usMajorTickSel = usMajorTickPref ;
- usMinorTickSel = usMinorTickPref ;
-
- /* let the default dialog procedure handle anything else */
- break ;
-
- case WM_COMMAND :
-
- switch ( LOUSHORT ( mp1 ) ) {
-
- case DID_OK :
-
- /* store away selections as preferences */
- usMajorTickPref = usMajorTickSel ;
- usMinorTickPref = usMinorTickSel ;
-
- /* repaint with the new preferences */
- WinInvalidateRect ( hwndFrame , NULL, TRUE ) ;
-
- case DID_CANCEL :
- WinDismissDlg ( hwnd , TRUE ) ;
- }
-
- return NULL ;
-
- case WM_CONTROL :
-
- if ( SHORT2FROMMP ( mp1 ) == BN_CLICKED ) {
-
- usButtonID = SHORT1FROMMP ( mp1 ) ;
-
- switch ( usButtonID & 0xff00 ) {
-
- case CLKTM_MAJOR :
- usMajorTickSel = LOBYTE ( usButtonID ) ;
- break ;
-
- case CLKTM_MINOR :
- usMinorTickSel = LOBYTE ( usButtonID ) ;
- break ;
- }
- }
-
- /* fall through to the default control processing */
- }
-
- return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;
- }
-
-
- /*
- ClkColorsDlgProc() "Clock Color Preferences" Dialog
-
- Returns: MRESULT, 0 or return value from WinDefDlgProc
- */
- MRESULT EXPENTRY ClkColorsDlgProc ( HWND hwnd , USHORT usMsg ,
- MPARAM mp1 , MPARAM mp2 )
- {
- USHORT usButtonID ;
- static USHORT usCheckedButtonID ;
- HWND hwndButton ;
- RECTL rclButton , rclButtonInterior ;
- static LONG clrBackgroundNew ;
- static LONG clrFaceNew ;
- static LONG clrHourHandNew ;
- static LONG clrMinuteHandNew ;
- static LONG * pclrNew ;
-
- switch ( usMsg ) {
-
- case WM_INITDLG :
-
- /* load the new values from the current ones */
- clrBackgroundNew = clrBackground ;
- clrFaceNew = clrFace ;
- clrHourHandNew = clrHourHand ;
- clrMinuteHandNew = clrMinuteHand ;
-
- /* click the "Background" radio button */
- WinSendMsg ( WinWindowFromID ( hwnd , CLKCLR_BACKGROUND ) ,
- BM_CLICK , MPFROMSHORT ( TRUE ) , NULL ) ;
-
- /* let the default dialog procedure handle anything else */
- break ;
-
- case WM_COMMAND :
-
- switch ( LOUSHORT ( mp1 ) ) {
- case DID_OK :
-
- /* store the new values */
- clrBackground = clrBackgroundNew ;
- clrFace = clrFaceNew ;
- clrHourHand = clrHourHandNew ;
- clrMinuteHand = clrMinuteHandNew ;
-
- /* repaint with the new colors */
- WinInvalidateRect ( hwndFrame , NULL, TRUE ) ;
-
- case DID_CANCEL :
-
- WinDismissDlg ( hwnd , TRUE ) ;
- }
- return NULL ;
-
- case WM_CONTROL :
-
- usButtonID = SHORT1FROMMP ( mp1 ) ;
-
- /* selecting a new object */
- if ( usButtonID & CLKCLR_OBJECTS ) {
-
- switch ( usButtonID ) {
- case CLKCLR_BACKGROUND :
- pclrNew = & clrBackgroundNew ;
- break ;
- case CLKCLR_FACE :
- pclrNew = & clrFaceNew ;
- break ;
- case CLKCLR_HOURHAND :
- pclrNew = & clrHourHandNew ;
- break ;
- case CLKCLR_MINUTEHAND :
- pclrNew = & clrMinuteHandNew ;
- }
-
- /* click the button for the new object's current color */
- WinSendMsg (
- WinWindowFromID ( hwnd ,
- CLKCLR_BUTTONSHIFT + ( USHORT ) * pclrNew ) ,
- BM_CLICK , MPFROMSHORT ( TRUE ) , NULL ) ;
-
- break ;
- }
-
- switch ( SHORT2FROMMP ( mp1 ) ) {
-
- case BN_CLICKED :
-
- * pclrNew = ( LONG ) usButtonID - CLKCLR_BUTTONSHIFT ;
-
- /* turn off the check state of the previously checked
- * button and turn on the check state of the button
- * just clicked */
-
- WinSendMsg ( WinWindowFromID ( hwnd , usCheckedButtonID )
- BM_SETCHECK , MPFROM2SHORT ( FALSE , NULL )
- NULL ) ;
- WinSendMsg ( WinWindowFromID ( hwnd , usButtonID ) ,
- BM_SETCHECK , MPFROM2SHORT ( TRUE , NULL ) ,
- NULL ) ;
-
- usCheckedButtonID = usButtonID ;
-
- break ;
-
- case BN_PAINT :
-
- /* fill only the interior of the button, so we don't
- * conflict with the focus indicator */
-
- hwndButton = ( ( PUSERBUTTON ) mp2 ) -> hwnd ;
- WinQueryWindowRect ( hwndButton , & rclButton ) ;
- rclButton . xLeft ++ ;
- rclButton . yBottom ++ ;
- rclButton . xRight -- ;
- rclButton . yTop -- ;
- WinFillRect ( ( ( PUSERBUTTON ) mp2 ) -> hps ,
- & rclButton ,
- ( LONG ) usButtonID - CLKCLR_BUTTONSHIFT )
-
- /* hollow out those buttons which aren't checked */
- if ( ! WinSendMsg ( WinWindowFromID ( hwnd , usButtonID )
- BM_QUERYCHECK , NULL , NULL ) ) {
- rclButtonInterior . xLeft = rclButton . xLeft + 4 ;
- rclButtonInterior . yBottom = rclButton . yBottom + 4
- rclButtonInterior . xRight = rclButton . xRight - 4 ;
- rclButtonInterior . yTop = rclButton . yTop - 4 ;
- WinFillRect ( ( ( PUSERBUTTON ) mp2 ) -> hps ,
- & rclButtonInterior , SYSCLR_WINDOW ) ;
- }
-
- break ;
- }
-
- /* fall through to the default control processing */
- }
-
- return WinDefDlgProc ( hwnd , usMsg , mp1 , mp2 ) ;
- }
-
-
- DLGPROC.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\INIEDIT\DLGPROC.C
-
- /******************************* Module Header ******************************
- * Module Name: DlgProc.c
- *
- * Created by Microsoft Corporation, 1989
- *
- *
- * System Test Application
- *
- *
- \***************************************************************************/
-
-
- #define LINT_ARGS // Include needed parts of PM
- #define INCL_WININPUT // definitions
- #define INCL_WINSYS
- #define INCL_WINMESSAGEMGR
- #define INCL_WINBUTTONS
- #define INCL_WINPOINTERS
- #define INCL_WINHEAP
- #define INCL_WINSHELLDATA
- #define INCL_WINMENUS
- #define INCL_WINFRAMEMGR
- #define INCL_WINLISTBOXES
- #define INCL_WINENTRYFIELDS
- #define INCL_WINDIALOGS
- #define INCL_GPIBITMAPS
- #define INCL_GPIREGIONS
- #define INCL_GPILCIDS
- #define INCL_GPIPRIMITIVES
- #define INCL_DEV
-
- #include <string.h>
- #include <stdio.h>
-
- #include <os2.h>
-
- #include "IniEdit.h"
-
-
- /******************************* Constants *********************************/
-
- #define BUF_SIZE 132
-
-
- /******************************** Globals **********************************/
-
- static CHAR szSearch[BUF_SIZE] = { 0 }; // Current search string
- static USHORT usLastIndex = 0; // Last Searched Item
-
- /******************************* Externals *********************************/
-
- extern USHORT cAppNames; // see iniedit.c
- extern HWND hwndList;
- extern PGROUPSTRUCT pGroups;
- extern HAB habIniEdit;
- extern HWND FocusWindow;
-
-
- /****************************** Function Header ****************************\
- *
- * SearchWndProc
- *
- *
- * Handles the Search Dialog Box messages
- *
- \***************************************************************************/
-
- MRESULT _loadds EXPENTRY SearchWndProc(HWND hwndDialog, USHORT msg,
- MPARAM mp1, MPARAM mp2)
- {
- HWND hwndText; // Current Text Window
-
-
- switch (msg)
- {
-
- case WM_INITDLG:
- hwndText = WinWindowFromID( hwndDialog, IDDI_SEARCH_TEXT );
- WinSetWindowText(hwndText, szSearch);
- WinSendMsg( hwndText, EM_SETSEL,
- MPFROM2SHORT(0, strlen(szSearch)), (MPARAM)0 );
-
- break;
-
- case WM_COMMAND:
- switch( LOUSHORT( mp1 ) )
- {
-
- case IDDI_SEARCH_OK:
- hwndText = WinWindowFromID( hwndDialog, IDDI_SEARCH_TEXT
- WinQueryWindowText( hwndText, BUF_SIZE, szSearch );
- WinDismissDlg( hwndDialog, 0 );
-
- if( (usLastIndex = SHORT1FROMMR(WinSendMsg( hwndList, LM_
- MPFROM2SHORT( LSS_SUBSTRING, LIT_FIRST),
- MPFROMP( szSearch )) ) != LIT_NONE ))
- {
- WinSendMsg( hwndList, LM_SELECTITEM,
- MPFROM2SHORT( (usLastIndex), NULL),
- MPFROM2SHORT( TRUE, NULL ) );
- }
- else /* not found */
- {
- usLastIndex = LIT_FIRST;
- WinAlarm( HWND_DESKTOP, 0);
- }
- break;
-
- case IDDI_SEARCH_NEXT:
- FindNext();
- break;
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- return 0L;
-
- } /* SearchWndProc */
-
-
- /****************************** Function Header ****************************\
- *
- * FindNext
- *
- *
- * Finds the next instance of the current search string starting from the
- * Last searched position
- *
- \***************************************************************************/
-
- VOID FindNext()
- {
- if( (usLastIndex = SHORT1FROMMR(WinSendMsg( hwndList, LM_SEARCHSTRING,
- MPFROM2SHORT( LSS_SUBSTRING, usLastIndex),
- MPFROMP( szSearch )) ) != LIT_NONE ))
- {
- WinSendMsg( hwndList, LM_SELECTITEM,
- MPFROM2SHORT( (usLastIndex), NULL),
- MPFROM2SHORT( TRUE, NULL ) );
- }
- else /* alarm if not found */
- WinAlarm( HWND_DESKTOP, 0);
-
- } /* FindNext */
-
-
- /****************************** Function Header ****************************\
- *
- * AddKeyWndProc
- *
- *
- * Handles the AddKey Dialog Box messages
- * Will facilitate adding new keys for a given App Name
- *
- \***************************************************************************/
-
- MRESULT _loadds EXPENTRY AddKeyWndProc(HWND hwndDialog, USHORT msg,
- MPARAM mp1, MPARAM mp2)
- {
- HWND hwndTextApp; // Handle for App Text Window
- HWND hwndTextKey;
- HWND hwndTextValue;
- CHAR szApp[BUF_SIZE]; // String Contents
- CHAR szKey[BUF_SIZE];
- CHAR szValue[BUF_SIZE];
-
-
- switch (msg)
- {
- case WM_INITDLG:
- WinSendDlgItemMsg(hwndDialog, IDDI_ADD_KEY_TEXT_APP, EM_SETTEXTLI
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- WinSendDlgItemMsg(hwndDialog, IDDI_ADD_KEY_TEXT_KEY, EM_SETTEXTLI
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- WinSendDlgItemMsg(hwndDialog, IDDI_ADD_KEY_TEXT_VAL, EM_SETTEXTLI
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- break;
- case WM_COMMAND:
- switch( LOUSHORT( mp1 ) )
- {
-
- case IDDI_ADD_KEY_OK:
- hwndTextApp = WinWindowFromID( hwndDialog, IDDI_ADD_KEY_T
- WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );
-
- hwndTextKey = WinWindowFromID( hwndDialog, IDDI_ADD_KEY_T
- WinQueryWindowText( hwndTextKey, BUF_SIZE, szKey );
-
- hwndTextValue = WinWindowFromID( hwndDialog, IDDI_ADD_KEY
- WinQueryWindowText( hwndTextValue, BUF_SIZE, szValue );
-
- WinDismissDlg( hwndDialog, 0 );
-
- /* if the App is NULL forget it */
- if( *szApp == (CHAR)0 )
- {
- break;
- }
-
- /* if the Key is NULL forget it */
- if( *szKey == (CHAR)0 )
- {
- break;
- }
-
- /* if the Value is NULL forget it */
- if( *szValue == (CHAR)0 )
- {
- break;
- }
-
- if( !WinWriteProfileString( habIniEdit, szApp, szKey, szV
- ;
- break;
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- return 0L;
-
- } /* AddKeyWndProc */
-
-
- /****************************** Function Header ****************************\
- *
- * ChangeKeyWndProc
- *
- *
- * Handles the ChangeKey Dialog Box messages
- * Will facilitate changing a key's value given an app, key and new value
- *
- \***************************************************************************/
-
- MRESULT _loadds EXPENTRY ChangeKeyWndProc(HWND hwndDialog, USHORT msg,
- MPARAM mp1, MPARAM mp2)
- {
- HWND hwndTextApp; // Handle for App Text Window
- HWND hwndTextKey;
- HWND hwndTextVal;
- CHAR szApp[BUF_SIZE]; // String Contents
- CHAR szKey[BUF_SIZE];
- CHAR szVal[BUF_SIZE];
-
-
- switch (msg)
- {
- case WM_INITDLG:
- if( FocusWindow )
- {
-
- FocusWindow = WinWindowFromID( hwndDialog, IDDI_CHANGE_KEY_TE
- WinSetFocus( HWND_DESKTOP, FocusWindow);
- WinQueryWindowText( FocusWindow, BUF_SIZE, szVal );
-
- FocusWindow = (HWND)NULL;
-
- return((MRESULT) TRUE );
- } else {
- WinSendDlgItemMsg(hwndDialog, IDDI_CHANGE_KEY_TEXT_APP, EM_SE
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- WinSendDlgItemMsg(hwndDialog, IDDI_CHANGE_KEY_TEXT_KEY, EM_SE
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- WinSendDlgItemMsg(hwndDialog, IDDI_CHANGE_KEY_TEXT_VAL, EM_SE
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- }
- break;
-
- case WM_COMMAND:
- switch( LOUSHORT( mp1 ) )
- {
-
- case IDDI_CHANGE_KEY_OK:
- hwndTextApp = WinWindowFromID( hwndDialog, IDDI_CHANGE_KE
- WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );
-
- hwndTextKey = WinWindowFromID( hwndDialog, IDDI_CHANGE_KE
- WinQueryWindowText( hwndTextKey, BUF_SIZE, szKey );
-
- hwndTextVal = WinWindowFromID( hwndDialog, IDDI_CHANGE_KE
- WinQueryWindowText( hwndTextVal, BUF_SIZE, szVal );
-
-
- WinDismissDlg( hwndDialog, IDDI_CHANGE_KEY_OK );
-
- /* if the App is NULL forget it */
- if( *szApp == (CHAR)0 )
- {
- break;
- }
-
- /* if the Key is NULL forget it */
- if( *szKey == (CHAR)0 )
- {
- break;
- }
-
- /* if the Value is NULL forget it */
- if( *szVal == (CHAR)0 )
- {
- break;
- }
-
-
- if( !WinWriteProfileString( habIniEdit, szApp, szKey, szV
-
- break;
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- return 0L;
-
- } /* ChangeKeyWndProc */
-
-
- /****************************** Function Header ****************************\
- *
- * DelKeyWndProc
- *
- *
- * Handles the DelKey Dialog Box messages
- * Will facilitate deleting a key value given an app and the key
- *
- \***************************************************************************/
-
- MRESULT _loadds EXPENTRY DelKeyWndProc(HWND hwndDialog, USHORT msg,
- MPARAM mp1, MPARAM mp2)
- {
- HWND hwndTextApp; // Handle for App Text Window
- HWND hwndTextKey;
- CHAR szApp[BUF_SIZE]; // String Contents
- CHAR szKey[BUF_SIZE];
-
-
- switch (msg)
- {
- case WM_INITDLG:
- WinSendDlgItemMsg(hwndDialog, IDDI_DEL_KEY_TEXT_APP, EM_SETTEXTLI
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- WinSendDlgItemMsg(hwndDialog, IDDI_DEL_KEY_TEXT_KEY, EM_SETTEXTLI
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- break;
- case WM_COMMAND:
- switch( LOUSHORT( mp1 ) )
- {
-
- case IDDI_DEL_KEY_OK:
- hwndTextApp = WinWindowFromID( hwndDialog, IDDI_DEL_KEY_T
- WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );
-
- hwndTextKey = WinWindowFromID( hwndDialog, IDDI_DEL_KEY_T
- WinQueryWindowText( hwndTextKey, BUF_SIZE, szKey );
-
-
- WinDismissDlg( hwndDialog, 0 );
-
- /* if the App is NULL forget it */
- if( *szApp == (CHAR)0 )
- {
- break;
- }
-
- /* if the Key is NULL forget it */
- if( *szKey == (CHAR)0 )
- {
- break;
- }
-
-
- if( !WinWriteProfileString( habIniEdit, szApp, szKey, (PC
- ;
- break;
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- return 0L;
-
- } /* DelKeyProc */
-
-
- /****************************** Function Header ****************************\
- *
- * DelAppWndProc
- *
- *
- * Handles the DelApp Dialog Box messages
- * Will facilitate deleting all keys from a given app name
- *
- \***************************************************************************/
-
- MRESULT _loadds EXPENTRY DelAppWndProc(HWND hwndDialog, USHORT msg,
- MPARAM mp1, MPARAM mp2)
- {
- HWND hwndTextApp; // App Name Window
- CHAR szApp[BUF_SIZE]; // String Contents of Window
-
-
- switch (msg)
- {
- case WM_INITDLG:
- WinSendDlgItemMsg(hwndDialog, IDDI_DEL_APP_TEXT_APP, EM_SETTEXTLI
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- break;
-
- case WM_COMMAND:
- switch( LOUSHORT( mp1 ) )
- {
-
- case IDDI_DEL_APP_OK:
- hwndTextApp = WinWindowFromID( hwndDialog, IDDI_DEL_APP_T
- WinQueryWindowText( hwndTextApp, BUF_SIZE, szApp );
-
- WinDismissDlg( hwndDialog, 0 );
-
- /* if the App is NULL forget it */
- if( *szApp == (CHAR)0 )
- {
- break;
- }
-
- if( !WinWriteProfileString( habIniEdit, szApp, (PCHAR)NUL
- ;
-
- break;
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- default:
- return WinDefDlgProc(hwndDialog, msg, mp1, mp2);
- break;
- }
-
- return 0L;
-
- } /* DelAppWndProc */
-
-
- DLGSAMP.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DLGSAMP\DLGSAMP.C
-
- /*
- DLGSAMP -- Dialog Box Sample Application
- Created by Microsoft Corporation, 1989
- */
-
- #define INCL_WINBUTTONS
- #define INCL_WINDIALOGS
- #define INCL_WINERRORS
- #define INCL_WINFRAMEMGR
- #define INCL_WININPUT
- #define INCL_WINLISTBOXES
- #define INCL_WINMENUS
- #define INCL_WINMESSAGEMGR
- #define INCL_WINRECTANGLES
- #define INCL_WINSWITCHLIST
- #define INCL_WINSYS
- #define INCL_WINWINDOWMGR
- #define M_I86L
- #include <os2.h>
-
- #include <string.h>
- #include <stdlib.h>
-
- #include "dlgsamp.h"
- #include "dlgsamp1.h"
-
- /*
- Function Prototypes
- */
-
- VOID NEAR cdecl main(VOID);
-
- /* Local Routines */
- VOID cdecl CenterDlgBox(HWND);
- VOID cdecl CheckColor(HWND, SHORT, COLOR *);
- VOID cdecl EnableModality(HWND, BOOL);
- BOOL cdecl IsIntInRange(HWND, SHORT, SHORT, SHORT, SHORT, SHORT);
- VOID cdecl LoadDialog(HWND, HWND, SHORT, PFNWP, BOOL);
- VOID cdecl MainWndCommand(HWND, USHORT, BOOL *);
- VOID cdecl MainWndPaint(HWND);
- VOID cdecl SetModality(HWND, BOOL);
- VOID cdecl Trace(PSZ, PSZ);
-
- /* Window Procedures */
- MRESULT EXPENTRY fnwpMainWnd(HWND, USHORT, MPARAM, MPARAM);
- MRESULT EXPENTRY fnwpEntryFieldDlg(HWND, USHORT, MPARAM, MPARAM);
- MRESULT EXPENTRY fnwpAutoRadioButtonDlg(HWND, USHORT, MPARAM, MPARAM);
- MRESULT EXPENTRY fnwpCheckBoxDlg(HWND, USHORT, MPARAM, MPARAM);
- MRESULT EXPENTRY fnwpListBoxDlg(HWND, USHORT, MPARAM, MPARAM);
- MRESULT EXPENTRY fnwpAboutBoxDlg(HWND, USHORT, MPARAM, MPARAM);
-
- /*
- Global variables
- */
- COLOR colorClient = CLR_RED | CLR_BLUE; /* Color of client area */
-
- CHAR szEntryField1[10] = ""; /* Used to pass back info */
- CHAR szEntryField2[10] = ""; /* from entry fields */
- /* in EntryFieldDlg */
-
- BOOL bModality = TRUE; /* Does the user want modal*/
- /* or modeless dialogs? */
- COLOR colorSave;
- CHAR szSelection[LEN_LISTBOXENTRY] = ""; /* Used to pass back */
- /* list box item selected */
- /* in ListBoxDlg */
-
- HAB hab; /* Anchor block handle */
- HWND hwndClient; /* Client Window handle */
- HWND hwndFrame; /* Frame Window handle */
- HWND hwndModelessDlg; /* Modeless Dialog handle */
-
- /**************************************************************************
- *
- * FUNCTION: main
- *
- * Typical PM main function which initializes PM, creates a message queue,
- * registers a window class, creates a window, gets and dispatches
- * messages to its winproc until its time to quit, and then tidies up
- * before terminating.
- *
- **************************************************************************/
-
- VOID NEAR cdecl main( )
- {
- HMQ hmq; /* Message Queue handle */
- QMSG qmsg; /* Message */
- ULONG flCreate;
-
- hab = WinInitialize( 0 ); /* Initialize PM */
- hmq = WinCreateMsgQueue( hab, 0 );/* Create application msg queue */
-
- WinRegisterClass( /* Register Window Class */
- hab, /* Anchor block handle */
- "DlgSamp Class", /* Window Class name */
- fnwpMainWnd, /* Address of Window Procedure */
- (ULONG) NULL, /* No special class style */
- 0 /* No extra window words */
- );
-
- flCreate = FCF_STANDARD & ~FCF_ACCELTABLE;
-
- hwndFrame = WinCreateStdWindow(
- HWND_DESKTOP, /* Desktop Window is parent */
- WS_VISIBLE, /* Window styles */
- (PVOID)&flCreate, /* Window creation parameters */
- "DlgSamp Class", /* Window Class name */
- "", /* Window Text */
- 0L, /* Client style */
- (HMODULE) NULL, /* Module handle */
- ID_MAINWND, /* Window ID */
- (HWND FAR *)&hwndClient /* Client Window handle */
- );
-
-
- /* Message Loop */
- while( WinGetMsg( hab, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
- WinDispatchMsg( hab, (PQMSG)&qmsg );
-
- /* Cleanup code */
- WinDestroyWindow( hwndFrame );
- WinDestroyMsgQueue( hmq );
- WinTerminate( hab );
- }
-
- /***********************************************************************
- *
- * WinProc: fnwpMainWnd
- *
- * Controls the state of the menu, and loads various dialogs. The
- * dialogs will be modal or modeless depending on the setting of the
- * Modality menuitem.
- *
- ***********************************************************************/
-
- MRESULT EXPENTRY fnwpMainWnd( hwnd, message, mp1, mp2 )
- HWND hwnd;
- USHORT message;
- MPARAM mp1;
- MPARAM mp2;
- {
- USHORT Command; /* Command passed by WM_COMMAND */
- SHORT id; /* ID of item selected from the list box */
-
- switch(message)
- {
- case WM_PAINT:
- MainWndPaint( hwnd ); /* Invoke window painting routine */
- break;
- case WM_HELP:
- /*********************************************************************
- *
- * This will be received when either:-
- *
- * 1. The user hits the F1 key
- * 2. The user clicks on the action bar item F1=Help
- *
- *********************************************************************/
- WinMessageBox( HWND_DESKTOP,
- hwndFrame,
- (PSZ)"Dialog Sample Application: Help",
- (PSZ)"Try out the pulldown menus, or Alt+selection",
- ID_MB,
- MB_OK );
- break;
- case WM_COMMAND:
- Command = SHORT1FROMMP( mp1 );
- MainWndCommand( hwnd, Command, &bModality );
- break;
- case DLGSAMP_EFCOMPLETE:
- WinQueryWindowText( WinWindowFromID( hwndModelessDlg, EF_1 ),
- sizeof( szEntryField1 ), szEntryField1 );
- WinQueryWindowText( WinWindowFromID( hwndModelessDlg, EF_2 ),
- sizeof( szEntryField2 ), szEntryField2 );
- WinInvalidateRect( hwnd, NULL, FALSE );/* Request whole window repaint
- break;
- case DLGSAMP_LBCOMPLETE:
- id = SHORT1FROMMR( WinSendDlgItemMsg( hwndModelessDlg,
- LB_1,
- LM_QUERYSELECTION,
- 0L,
- 0L ) );
- if( id == LIT_NONE )
- strcpy( szSelection, "" );
- else
- WinSendDlgItemMsg( hwndModelessDlg,
- LB_1,
- LM_QUERYITEMTEXT,
- MPFROM2SHORT( id, sizeof( szSelection ) ),
- MPFROMP( szSelection ) );
- break;
- case DLGSAMP_RBCOMPLETE:
- case DLGSAMP_CBCOMPLETE:
- break;
- case DLGSAMP_DESTROYDLG:
- WinDestroyWindow( hwndModelessDlg );
- EnableModality( hwndFrame, TRUE );
- WinInvalidateRect( hwnd, NULL, FALSE );/* Request whole window repaint
- break;
- case WM_CLOSE:
- WinPostMsg( hwnd, WM_QUIT, 0L, 0L ); /* Cause termination */
- break;
- default:
- return WinDefWindowProc( hwnd, message, mp1, mp2 );
- }
- return FALSE;
- }
-
- /***********************************************************************
- *
- * DlgProc: fnwpEntryFieldDlg
- *
- * A dialog proc which captures and validates the contents of two
- * entry fields.
- *
- ***********************************************************************/
-
- MRESULT EXPENTRY fnwpEntryFieldDlg( hwndDlg, message, mp1, mp2 )
- HWND hwndDlg;
- USHORT message;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch (message)
- {
- case WM_INITDLG:
- CenterDlgBox( hwndDlg );
- break;
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) )
- {
- case DID_OK: /* Enter key or pushbutton pressed/ selected */
-
- /***************************************************************************
- *
- * Validate the contents of the two entry fields
- *
- ***************************************************************************/
-
- if( !IsIntInRange( hwndDlg, EF_1, 1, 100, ERR_EFINVALID, ID_MB ) )
- return FALSE;
- if( !IsIntInRange( hwndDlg, EF_2, 1, 100, ERR_EFINVALID, ID_MB ) )
- return FALSE;
-
- /***************************************************************************
- *
- * A modal dialog is destroyed before control is returned to the
- * invoking winproc, so it must pass the contents of its Entry Fields etc.
- * back to the invoking window before it returns.
- *
- * When a modeless dialog box returns it still continues to exist. It
- * could pass the contents of its Entry Fields etc. back to the
- * invoking window in several ways.
- *
- * Here a user message is posted to the invoking window to say that the
- * dialog has completed. The invoking window then has an opportunity
- * to extract the contents of the Entry Fields etc.
- *
- ***************************************************************************/
-
- if( bModality )
- {
- WinQueryWindowText( WinWindowFromID( hwndDlg, EF_1 ),
- sizeof( szEntryField1),
- szEntryField1 );
- WinQueryWindowText( WinWindowFromID( hwndDlg, EF_2 ),
- sizeof( szEntryField2),
- szEntryField2 );
- }
- else
- WinPostMsg( hwndClient, DLGSAMP_EFCOMPLETE, 0L, 0L );
-
- case DID_CANCEL:/* Escape key or CANCEL pushbutton pressed/selected *
- if( bModality )
- WinDismissDlg( hwndDlg,TRUE );
- else
- WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );
- return FALSE;
- default:
- break;
- }
- break;
-
- default: /* Pass all other messages to the default dialog proc */
- return WinDefDlgProc( hwndDlg, message, mp1, mp2 );
- }
- return FALSE;
- }
-
- /***********************************************************************
- *
- * DlgProc: fnwpAutoRadioButtonDlg
- *
- * A dialog procedure which uses auto radio buttons to change the
- * color of the Client Area window.
- *
- ***********************************************************************/
-
- MRESULT EXPENTRY fnwpAutoRadioButtonDlg( hwndDlg, message, mp1, mp2 )
- HWND hwndDlg;
- USHORT message;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch (message)
- {
- case WM_INITDLG:
- colorSave = colorClient;
- CenterDlgBox( hwndDlg );
- if ( colorClient == CLR_RED )
- WinPostMsg( WinWindowFromID( hwndDlg, RB_RED ),
- BM_SETCHECK,
- MPFROM2SHORT( TRUE, 0 ),
- 0L );
-
- if ( colorClient == CLR_GREEN )
- WinPostMsg( WinWindowFromID( hwndDlg, RB_GREEN ),
- BM_SETCHECK,
- MPFROM2SHORT( TRUE, 0 ),
- 0L );
-
- if ( colorClient == CLR_BLUE )
- WinPostMsg( WinWindowFromID( hwndDlg, RB_BLUE ),
- BM_SETCHECK,
- MPFROM2SHORT( TRUE, 0 ),
- 0L );
-
- break;
- case WM_CONTROL:
- if( SHORT2FROMMP( mp1 ) == BN_CLICKED )
- switch( SHORT1FROMMP( mp1 ) )
- {
- case RB_RED:
- colorClient = CLR_RED;
- break;
- case RB_GREEN:
- colorClient = CLR_GREEN;
- break;
- case RB_BLUE:
- colorClient = CLR_BLUE;
- break;
- default:
- return FALSE;
- }
- WinInvalidateRect( hwndClient, NULL, FALSE );
- break;
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) )
- {
- case DID_OK: /* Enter key or pushbutton pressed/ selected
- if( !bModality )
- WinPostMsg( hwndClient, DLGSAMP_RBCOMPLETE, 0L, 0L );
- break;
- case DID_CANCEL: /* Escape key or CANCEL pushbutton pressed/selected
- colorClient = colorSave;
- break;
- default:
- return WinDefDlgProc( hwndDlg, message, mp1, mp2 );
- }
- if( bModality )
- WinDismissDlg( hwndDlg, TRUE );
- else
- WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );
- break;
-
- default: /* Pass all other messages to the default dialog proc */
- return WinDefDlgProc( hwndDlg, message, mp1, mp2 );
- }
- return FALSE;
- }
-
-
- /***********************************************************************
- *
- * DlgProc: fnwpCheckBoxDlg
- *
- * A dialog procedure to which use checkboxes to change the color
- * of the Client Area Window.
- *
- ***********************************************************************/
-
- MRESULT EXPENTRY fnwpCheckBoxDlg( hwndDlg, message, mp1, mp2 )
- HWND hwndDlg;
- USHORT message;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch (message)
- {
- case WM_INITDLG:
- CenterDlgBox( hwndDlg );
- colorSave = colorClient;
- if( (colorClient & CLR_RED) == CLR_RED )
- WinPostMsg( WinWindowFromID( hwndDlg, CB_RED ),
- BM_SETCHECK,
- MPFROM2SHORT( TRUE,0 ),
- 0L );
- if( (colorClient & CLR_GREEN) == CLR_GREEN )
- WinPostMsg( WinWindowFromID( hwndDlg, CB_GREEN ),
- BM_SETCHECK,
- MPFROM2SHORT( TRUE,0 ),
- 0L );
- if( (colorClient & CLR_BLUE) == CLR_BLUE )
- WinPostMsg( WinWindowFromID( hwndDlg, CB_BLUE ),
- BM_SETCHECK,
- MPFROM2SHORT( TRUE,0 ),
- 0L );
- break;
- case WM_CONTROL: /* User has clicked on a checkbox */
- if( SHORT2FROMMP( mp1 ) == BN_CLICKED )
- CheckColor( hwndDlg, SHORT1FROMMP( mp1 ), &colorClient );
- WinInvalidateRect( hwndClient, NULL, FALSE );
- break;
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) )
- {
- case DID_OK: /* Enter key or pushbutton pressed/ selected */
- if( !bModality )
- WinPostMsg( hwndClient, DLGSAMP_CBCOMPLETE, 0L, 0L );
- break;
- case DID_CANCEL: /* Escape key or CANCEL pushbutton pressed/selected
- colorClient = colorSave;
- break;
- default:
- return WinDefDlgProc( hwndDlg, message, mp1, mp2 );
- }
- if( bModality )
- WinDismissDlg( hwndDlg, TRUE );
- else
- WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );
- return FALSE;
-
- default: /* Pass all other messages to the default dialog proc */
- return WinDefDlgProc( hwndDlg, message, mp1, mp2 );
- }
- return FALSE;
- }
-
- /***********************************************************************
- *
- * DlgProc: fnwpListBoxDlg
- *
- ***********************************************************************/
-
- MRESULT EXPENTRY fnwpListBoxDlg( hwndDlg, message, mp1, mp2 )
- HWND hwndDlg;
- USHORT message;
- MPARAM mp1;
- MPARAM mp2;
- {
- CHAR szBuffer[LEN_LISTBOXENTRY];
- SHORT i;
- SHORT id;
-
- switch (message)
- {
- case WM_INITDLG:
- CenterDlgBox( hwndDlg );
-
- /*************************************************************************
- *
- * Initialize the listbox with a set of strings loaded from a
- * resource file.
- *
- *************************************************************************/
-
- for ( i = 0; i < NUM_LISTBOXENTRIES; i++ )
- {
- WinLoadString( hab,
- (HMODULE) NULL,
- LBI_1 + i,
- LEN_LISTBOXENTRY,
- (PSZ)szBuffer
- );
- WinSendDlgItemMsg( hwndDlg,
- LB_1,
- LM_INSERTITEM,
- MPFROM2SHORT( LIT_END, 0 ),
- MPFROMP( szBuffer )
- );
- }
- break;
- case WM_COMMAND:
- switch( SHORT1FROMMP( mp1 ) )
- {
- case DID_OK: /* Enter key or pushbutton pressed/ selected */
- if( bModality )
- {
-
- /***********************************************************************
- *
- * Find out which item (if any) was selected and return the selected
- * item text.
- *
- ***********************************************************************/
-
- id = SHORT1FROMMR( WinSendDlgItemMsg( hwndDlg,
- LB_1,
- LM_QUERYSELECTION,
- 0L,
- 0L ) );
- if( id == LIT_NONE )
- strcpy( szSelection, "" );
- else
- WinSendDlgItemMsg( hwndDlg,
- LB_1,
- LM_QUERYITEMTEXT,
- MPFROM2SHORT( id, LEN_LISTBOXENTRY ),
- MPFROMP( szSelection ) );
- }
- else
- WinPostMsg( hwndClient, DLGSAMP_LBCOMPLETE, 0L, 0L );
- case DID_CANCEL: /* Escape key or CANCEL pushbutton pressed/selected
- if( bModality )
- WinDismissDlg( hwndDlg, TRUE );
- else
- WinPostMsg( hwndClient, DLGSAMP_DESTROYDLG, 0L, 0L );
- return FALSE;
- default:
- break;
- }
- break;
-
- default: /* Pass all other messages to the default dialog proc */
- return WinDefDlgProc( hwndDlg, message, mp1, mp2 );
- }
- return FALSE;
- }
-
- /*************************************************************************
- *
- * FUNCTION : CenterDlgBox
- *
- * Positions the dialog box in the center of the screen
- *
- *************************************************************************/
-
- VOID cdecl CenterDlgBox( hwnd )
- HWND hwnd;
- {
- SHORT ix, iy;
- SHORT iwidth, idepth;
- SWP swp;
-
- iwidth = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CXSCREEN );
- idepth = (SHORT)WinQuerySysValue( HWND_DESKTOP, SV_CYSCREEN );
- WinQueryWindowPos( hwnd, (PSWP)&swp );
- ix = ( iwidth - swp.cx ) / 2;
- iy = ( idepth - swp.cy ) / 2;
- WinSetWindowPos( hwnd, HWND_TOP, ix, iy, 0, 0, SWP_MOVE );
- }
-
- /***************************************************************************
- *
- * FUNCTION: CheckColor
- *
- * Toggle the Checked/UnChecked state of a checkbox and add/remove
- * the corresponding CLR color component of the Client Area Color.
- *
- ***************************************************************************/
-
- VOID cdecl CheckColor( hwndDlg, iDlgItem, colorClient )
- HWND hwndDlg;
- SHORT iDlgItem;
- COLOR *colorClient;
- {
- BOOL bChecked;
- COLOR color;
-
- switch( iDlgItem )
- {
- case CB_RED:
- color = CLR_RED;
- break;
- case CB_GREEN:
- color = CLR_GREEN;
- break;
- case CB_BLUE:
- color = CLR_BLUE;
- break;
- default:
- return;
- }
-
- bChecked = SHORT1FROMMR( WinSendMsg( WinWindowFromID( hwndDlg , iDlgItem ),
- BM_QUERYCHECK,
- 0L,
- 0L ) );
- WinPostMsg( WinWindowFromID( hwndDlg, iDlgItem ),
- BM_SETCHECK,
- MPFROM2SHORT( !bChecked, 0 ),
- 0L );
- if( bChecked ) /* If color previously checked */
- *colorClient -= color; /* subtract it ... else */
- else
- *colorClient += color; /* ... add it. */
- }
-
- /**************************************************************************
- *
- * FUNCTION: EnableModality
- *
- * Enable or disable the Modality menuitems depending on the value
- * of modal. This is done to prevent the user from altering the
- * modality setting while a modeless dialog is active.
- *
- **************************************************************************/
-
- VOID cdecl EnableModality( hwnd, bModal )
- HWND hwnd;
- BOOL bModal;
- {
- if( bModal )
- {
- WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),
- MM_SETITEMATTR,
- MPFROM2SHORT( MI_MODAL, TRUE ),
- MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED ) );
- WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),
- MM_SETITEMATTR,
- MPFROM2SHORT( MI_MODELESS, TRUE ),
- MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED ) );
- }
- else
- {
- WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),
- MM_SETITEMATTR,
- MPFROM2SHORT( MI_MODAL, TRUE ),
- MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED ) );
- WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),
- MM_SETITEMATTR,
- MPFROM2SHORT( MI_MODELESS, TRUE ),
- MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED ) );
- }
- }
-
- /***************************************************************************
- *
- * FUNCTION: IsIntInRange.
- *
- * Checks whether the value of a dialog item is in an integer in
- * a given range.
- *
- ***************************************************************************/
-
- BOOL cdecl IsIntInRange( hwndDlg, idEntryField,
- iLoRange, iHiRange,
- idErrMsg, idMessageBox )
- HWND hwndDlg;
- SHORT idEntryField;
- SHORT iLoRange;
- SHORT iHiRange;
- SHORT idErrMsg;
- SHORT idMessageBox;
- {
- SHORT ivalue;
- CHAR szErrMsg[80];
-
- /****************************************************************************
- *
- * Validate an entry field.
- *
- * If validation fails leave the dialog visible, issue an error message
- * using a messagebox, and when the user dismisses the messagebox,
- * set the input focus to the entry field containing the error. Leave
- * the contents of the entry field unchanged, and return FALSE.
- *
- * If validation is successful return the value in ivalue and return
- * TRUE.
- *
- ****************************************************************************/
-
- if( !WinQueryDlgItemShort( hwndDlg, idEntryField, &ivalue, TRUE ) ||
- ( ivalue < iLoRange ) ||
- ( ivalue > iHiRange ) )
- {
- WinLoadString( hab, (HMODULE) NULL, idErrMsg, sizeof( szErrMsg ), szErrMs
- WinMessageBox( HWND_DESKTOP,
- hwndFrame,
- (PSZ)szErrMsg,
- NULL,
- idMessageBox,
- MB_OK );
- WinSetFocus( HWND_DESKTOP, WinWindowFromID( hwndDlg, idEntryField ) );
- return FALSE;
- }
- else
- return TRUE;
- }
-
- /***********************************************************************
- *
- * FUNCTION: LoadDialog
- *
- * Use the appropriate functions to put up a modal or modeless
- * dialog box depending on the setting of the bModality parameter.
- *
- ***********************************************************************/
-
- VOID cdecl LoadDialog( hwndParent, hwndOwner, idDlg, fnwpDlgProc, bModality )
- HWND hwndParent;
- HWND hwndOwner;
- SHORT idDlg;
- PFNWP fnwpDlgProc;
- BOOL bModality;
- {
- EnableModality( hwndOwner, FALSE ); /* Disable the Modality menu item */
-
- if( bModality )
- {
- WinDlgBox( hwndParent, /* Parent */
- hwndOwner, /* Owner */
- fnwpDlgProc, /* Address of dialog proc */
- (HMODULE) NULL, /* Module handle */
- idDlg, /* Id of dialog in resource */
- NULL ); /* Initialisation data */
- EnableModality( hwndOwner, TRUE ); /* Enable the Modality menu item */
- }
- else
- {
- /*******************************************************************
- *
- * Check to see if a modeless dialog is already running: if
- * so destroy it before for loading the requested dialog. Save
- * the handle of the new dialog in a global variable so that in
- * can be accessed by the WinProc that issued LoadDialog.
- *
- *******************************************************************/
-
- if( WinIsWindow( hab, hwndModelessDlg ) )
- WinDestroyWindow( hwndModelessDlg );
- hwndModelessDlg = WinLoadDlg( hwndParent,
- hwndOwner,
- fnwpDlgProc,
- (HMODULE) NULL,
- idDlg,
- NULL );
- }
- }
-
- /*************************************************************************
- *
- * FUNCTION: MainWndCommand
- *
- * Take the appropriate action when a WM_COMMAND message is received by
- * MainWndProc. Issues calls which load dialogs in the prevailing state
- * of modality.
- *
- *************************************************************************/
-
- VOID cdecl MainWndCommand( hwnd, Command, bModality )
- HWND hwnd;
- USHORT Command;
- BOOL *bModality;
- {
- USHORT idDlg;
- PFNWP pfnDlgProc;
-
- switch( Command )
- {
- case MI_MODAL:
- case MI_MODELESS:
- *bModality = ( Command == MI_MODAL ) ? TRUE
- : FALSE;
- SetModality( WinQueryWindow( hwnd, QW_PARENT, FALSE ), *bModality );
- WinInvalidateRect( hwnd, NULL, FALSE );
- return;
- case MI_ENTRYFIELDEXAMPLE:
- idDlg = DLG_ENTRYFIELDEXAMPLE;
- pfnDlgProc = (PFNWP)fnwpEntryFieldDlg;
- break;
- case MI_AUTORADIOBUTTONEXAMPLE:
- idDlg = DLG_AUTORADIOBUTTONEXAMPLE;
- pfnDlgProc = (PFNWP)fnwpAutoRadioButtonDlg;
- break;
- case MI_CHECKBOXEXAMPLE:
- idDlg = DLG_CHECKBOXEXAMPLE;
- pfnDlgProc = (PFNWP)fnwpCheckBoxDlg;
- break;
- case MI_LISTBOXEXAMPLE:
- idDlg = DLG_LISTBOXEXAMPLE;
- pfnDlgProc = (PFNWP)fnwpListBoxDlg;
- break;
- case MI_ABOUTBOX:
- WinDlgBox(HWND_DESKTOP, hwnd, fnwpAboutBoxDlg, (HMODULE) NULL, DLG_ABOU
- return;
- default:
- return;
- }
- LoadDialog( HWND_DESKTOP,
- hwndFrame,
- idDlg,
- pfnDlgProc,
- *bModality );
- if( *bModality )
- WinInvalidateRect( hwnd, NULL, FALSE ); /* Request whole window repaint
- }
-
- /************************************************************************
- *
- * FUNCTION: MainWndPaint
- *
- * An unsophisticated window painting routine which simply repaints the
- * entire window when a WM_PAINT message is received. In a real
- * application more sophisticated techniques could be used to determine
- * the minimum region needing repainting, and to paint only that
- * region
- *
- ************************************************************************/
-
- VOID cdecl MainWndPaint( hwnd )
- HWND hwnd;
- {
- POINTL pointl;
- HPS hps; /* Presentation space handle */
- RECTL rcl; /* Window rectangle */
- CHAR string[50];
-
- hps = WinBeginPaint( hwnd, (HPS)NULL, (PRECTL)&rcl );
- /*
- Color in the background
- */
- switch ((int) colorClient) {
- case 0: /* (r,g,b) = (0,0,0) */
- WinFillRect( hps, (PRECTL)&rcl, CLR_BLACK );
- break;
- case 7: /* (r,g,b) = (1,1,1) */
- WinFillRect( hps, (PRECTL)&rcl, CLR_WHITE );
- break;
- default:
- WinFillRect( hps, (PRECTL)&rcl, colorClient );
- break;
- }
- /*
- Set the text character colors
- */
- GpiSetColor( hps, (colorClient == 0L) ? CLR_WHITE
- : CLR_BLACK );
- pointl.x = 10L; pointl.y = 70L;
- strcpy( string, "Dialog modality = " );
- strcat( string, (bModality) ? "Modal"
- : "Modeless" );
- GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );
- pointl.y = 50L;
- strcpy( string, "Entry Field 1 = " );
- strcat( string, szEntryField1 );
- GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );
- pointl.y = 30L;
- strcpy( string, "Entry Field 2 = " );
- strcat( string, szEntryField2 );
- GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );
- pointl.y = 10L;
- strcpy( string, "List Box Selection = " );
- strcat( string, szSelection );
- GpiCharStringAt( hps, &pointl, (LONG)strlen( string ), (PSZ)string );
- WinEndPaint( hps );
- }
-
- /**************************************************************************
- *
- * FUNCTION: SetModality
- *
- * Check or uncheck Modal and Modeless menu items as appropriate.
- *
- **************************************************************************/
-
- VOID cdecl SetModality( hwnd, bModal )
- HWND hwnd;
- BOOL bModal;
- {
- WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),
- MM_SETITEMATTR,
- MPFROM2SHORT( MI_MODAL, TRUE ),
- MPFROM2SHORT( MIA_CHECKED, (bModal) ? ( MIA_CHECKED)
- : (~MIA_CHECKED) ) );
-
- WinPostMsg( WinWindowFromID( hwnd, FID_MENU ),
- MM_SETITEMATTR,
- MPFROM2SHORT( MI_MODELESS, TRUE ),
- MPFROM2SHORT( MIA_CHECKED, (bModal) ? (~MIA_CHECKED)
- : ( MIA_CHECKED) ) );
-
- }
-
- MRESULT EXPENTRY fnwpAboutBoxDlg(hDlg, msg, mp1, mp2)
- /*
- About... dialog procedure
- */
- HWND hDlg;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hDlg, TRUE); break;
- default: break;
- }
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
-
- DMGDB.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGDB.C
-
- /****************************** Module Header ******************************\
- * Module Name: DMGDB.C
- *
- * DDE manager data handling routines
- *
- * Created: 12/14/88 Sanford Staab
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
- #include "ddemlp.h"
-
- /***************************** Private Function ****************************\
- * PAPPINFO GetCurrentAppInfo()
- *
- * DESCRIPTION:
- * This routine uses the pid of the current thread to locate the information
- * pertaining to that thread. If not found, 0 is returned.
- *
- * This call fails if the DLL is in a callback state to prevent recursion.
- * if fChkCallback is set.
- *
- * History: 1/1/89 Created sanfords
- \***************************************************************************/
- PAPPINFO GetCurrentAppInfo(fChkCallback)
- BOOL fChkCallback;
- {
- PAPPINFO pai;
-
- SemEnter();
- if (pAppInfoList == NULL || !CheckSel(SELECTOROF(pAppInfoList))) {
- SemLeave();
- return(0);
- }
- pai = pAppInfoList;
- while (pai) {
- if (pai->pid == FSRSemDmg.pid && pai->tid == FSRSemDmg.tid) {
- if (fChkCallback && pai->cInCallback > MAX_RECURSE) {
- pai->LastError = DMGERR_REENTRANCY;
- break;
- } else {
- SemLeave();
- return(pai);
- }
- }
- pai = pai->next;
- }
- SemLeave();
- return(0);
- }
-
-
- /***************************** Private Function ****************************\
- * void UnlinkAppInfo(pai)
- * PAPPINFO pai;
- *
- * DESCRIPTION:
- * unlinks an pai safely. Does nothing if not linked.
- *
- * History: 1/1/89 Created sanfords
- \***************************************************************************/
- void UnlinkAppInfo(pai)
- PAPPINFO pai;
- {
- PAPPINFO paiT;
-
- AssertF(pai != NULL, "UnlinkAppInfo - NULL input");
- SemEnter();
- if (pai == pAppInfoList) {
- pAppInfoList = pai->next;
- SemLeave();
- return;
- }
- paiT = pAppInfoList;
- while (paiT && paiT->next != pai)
- paiT = paiT->next;
- if (paiT)
- paiT->next = pai->next;
- SemLeave();
- return;
- }
-
-
-
-
-
- /***************************** Private Functions ***************************\
- * General List management functions.
- *
- * History:
- * Created 12/15/88 sanfords
- \***************************************************************************/
- PLST CreateLst(hheap, cbItem)
- HHEAP hheap;
- USHORT cbItem;
- {
- PLST pLst;
-
- SemEnter();
- if (!(pLst = (PLST)FarAllocMem(hheap, sizeof(LST)))) {
- SemLeave();
- return(NULL);
- }
- pLst->hheap = hheap;
- pLst->cbItem = cbItem;
- pLst->pItemFirst = (PLITEM)NULL;
- SemLeave();
- return(pLst);
- }
-
-
-
- void FlushLst(pLst)
- PLST pLst;
- {
- if (pLst == NULL)
- return;
- SemEnter();
- while (pLst->pItemFirst)
- RemoveLstItem(pLst, pLst->pItemFirst);
- SemLeave();
- }
-
-
-
- void DestroyLst(pLst)
- PLST pLst;
- {
- if (pLst == NULL)
- return;
- SemEnter();
- while (pLst->pItemFirst)
- RemoveLstItem(pLst, pLst->pItemFirst);
- FarFreeMem(pLst->hheap, pLst, sizeof(LST));
- SemLeave();
- }
-
-
-
- PLITEM FindLstItem(pLst, npfnCmp, piSearch)
- PLST pLst;
- NPFNCMP npfnCmp;
- PLITEM piSearch;
- {
- PLITEM pi;
-
- if (pLst == NULL)
- return(NULL);
- SemEnter();
- pi = pLst->pItemFirst;
- while (pi) {
- if ((*npfnCmp)
- ((PBYTE)pi + sizeof(LITEM), (PBYTE)piSearch + sizeof(LITEM)))
- SemLeave();
- return(pi);
- }
- pi = pi->next;
- }
- SemLeave();
- }
-
-
-
- /*
- * Comparison functions for FindLstItem() and FindPileItem()
- */
-
- BOOL CmpULONG(pb1, pb2)
- PBYTE pb1;
- PBYTE pb2;
- {
- return(*(PULONG)pb1 == *(PULONG)pb2);
- }
-
- BOOL CmppHsz(pb1, pb2)
- PBYTE pb1;
- PBYTE pb2;
- {
- return(CmpHsz(*(PHSZ)pb1, *(PHSZ)pb2) ? FALSE : TRUE);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * This routine creates a new list item for pLst and links it in according
- * to the ILST_ constant in afCmd. Returns a pointer to the new item
- * or NULL on failure.
- *
- * Note: This MUST be in the semaphore for use since the new list item
- * is filled with garbage on return yet is linked in.
- *
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- PLITEM NewLstItem(pLst, afCmd)
- PLST pLst;
- USHORT afCmd;
- {
- PLITEM pi, piT;
-
- if (pLst == NULL)
- return(NULL);
- SemCheckIn();
-
- pi = (PLITEM)FarAllocMem(pLst->hheap, pLst->cbItem + sizeof(LITEM));
- if (pi == NULL) {
- AssertF(FALSE, "NewLstItem - memory failure");
- return(NULL);
- }
-
- if (afCmd & ILST_NOLINK)
- return(pi);
-
- if (((piT = pLst->pItemFirst) == NULL) || (afCmd & ILST_FIRST)) {
- pi->next = piT;
- pLst->pItemFirst = pi;
- } else { /* ILST_LAST assumed */
- while (piT->next != NULL)
- piT = piT->next;
- piT->next = pi;
- pi->next = NULL;
- }
- return(pi);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This routine unlinks and frees pi from pLst. If pi cannot be located
- * within pLst, it is freed anyway.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- BOOL RemoveLstItem(pLst, pi)
- PLST pLst;
- PLITEM pi;
- {
- PLITEM piT;
-
- if (pLst == NULL || pi == NULL)
- return(FALSE);
-
- SemCheckIn();
-
- if ((piT = pLst->pItemFirst) != NULL) {
- if (pi == piT) {
- pLst->pItemFirst = pi->next;
- } else {
- while (piT->next != pi && piT->next != NULL)
- piT = piT->next;
- if (piT->next != NULL)
- piT->next = pi->next; /* unlink */
- }
- } else {
- AssertF(pi == NULL, "Improper list item removal");
- }
- FarFreeMem(pLst->hheap, pi, pLst->cbItem + sizeof(LITEM));
- return(TRUE);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This routine uses ILST_ constants to insert a list item into the apropriate
- * spot of the pLst given. Only ILST_FIRST or ILST_LAST are allowed.
- *
- * History:
- * Created 9/11/89 Sanfords
- \***************************************************************************/
- BOOL InsertLstItem(pLst, pi, afCmd)
- PLST pLst;
- PLITEM pi;
- USHORT afCmd;
- {
- PLITEM piT;
-
- if (pLst == NULL)
- return(FALSE);
-
- SemEnter();
-
- if (pLst->pItemFirst == NULL || afCmd & ILST_FIRST) {
- pi->next = pLst->pItemFirst;
- pLst->pItemFirst = pi;
- } else { /* ILST_LAST assumed */
- piT = pLst->pItemFirst;
- while (piT->next)
- piT = piT->next;
- piT->next = pi;
- pi->next = NULL;
- }
-
- SemLeave();
- return(TRUE);
- }
-
-
-
-
- /*
- * ------------- Specific list routines -------------
- */
-
- /*
- * This function is HIGHLY dependent on the ADVLI structure.
- * This will match an exact hsz/fmt pair with a 0 format being wild.
- */
- BOOL CmpAdv(pb1, pb2)
- PBYTE pb1;
- PBYTE pb2;
- {
- USHORT usFmt;
-
- if (*(PHSZ)pb1 == *(PHSZ)pb2) {
- if ((usFmt = *(PUSHORT)(pb2 + 4)) == 0)
- return(TRUE);
- if (usFmt == *(PUSHORT)(pb1 + 4))
- return(TRUE);
- }
- return(FALSE);
- }
-
-
-
- BOOL fSearchHwndList(pLst, hwnd)
- PLST pLst;
- HWND hwnd;
- {
- HWNDLI hwndi;
-
- hwndi.hwnd = hwnd;
- return((BOOL)FindLstItem(pLst, CmpHwnd, (PLITEM)&hwndi));
- }
-
-
-
- void AddHwndList(hwnd, pLst)
- HWND hwnd;
- PLST pLst;
- {
- HWNDLI hwndli;
- PHWNDLI pli;
-
- AssertF(pLst != NULL, "AddHwndList - NULL pLst");
- AssertF(pLst->cbItem == sizeof(HWNDLI), "AddHwndList - Bad item size");
- SemEnter();
- hwndli.hwnd = hwnd;
- if ((hwnd == NULL) || FindLstItem(pLst, CmpHwnd, (PLITEM)&hwndli)) {
- SemLeave();
- return;
- }
- pli = (PHWNDLI)NewLstItem(pLst, ILST_FIRST);
- pli->hwnd = hwnd;
- SemLeave();
- }
-
-
-
- /*
- * Insert the given data into the list if one does not already exist
- * under the given hwnd.
- */
- void AddAckHwndList(hwnd, hszApp, hszTopic, pLst)
- HWND hwnd;
- HSZ hszApp;
- HSZ hszTopic;
- PLST pLst;
- {
- HWNDLI hwndli;
- PACKHWNDLI pli;
-
- AssertF(pLst != NULL, "AddAckHwndList - NULL pLst");
- AssertF(pLst->cbItem == sizeof(ACKHWNDLI), "AddAckHwndList - Bad item siz
- SemEnter();
- hwndli.hwnd = hwnd;
- if ((hwnd == NULL) || FindLstItem(pLst, CmpHwnd, (PLITEM)&hwndli)) {
- SemLeave();
- return;
- }
- pli = (PACKHWNDLI)NewLstItem(pLst, ILST_FIRST);
- pli->hwnd = hwnd;
- pli->hszApp = hszApp;
- pli->hszTopic = hszTopic;
- SemLeave();
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * hwnd-hsz list functions
- *
- * History: 1/20/89 Created sanfords
- \***************************************************************************/
- void AddHwndHszList(hsz, hwnd, pLst)
- HSZ hsz;
- HWND hwnd;
- PLST pLst;
- {
- PHWNDHSZLI phhi;
-
- AssertF(pLst->cbItem == sizeof(HWNDHSZLI), "AddHwndHszList - Bad item siz
- SemEnter();
- if ((hsz == NULL) || (BOOL)HwndFromHsz(hsz, pLst)) {
- SemLeave();
- return;
- }
- phhi = (PHWNDHSZLI)NewLstItem(pLst, ILST_FIRST);
- phhi->hwnd = hwnd;
- phhi->hsz = hsz;
- IncHszCount(hsz);
- SemLeave();
- }
-
-
- void DestroyHwndHszList(pLst)
- PLST pLst;
- {
- AssertF(pLst->cbItem == sizeof(HWNDHSZLI), "DestroyHwndHszList - Bad item
- SemEnter();
- while(pLst->pItemFirst) {
- FreeHsz(((PHWNDHSZLI)pLst->pItemFirst)->hsz);
- RemoveLstItem(pLst, pLst->pItemFirst);
- }
- FarFreeMem(pLst->hheap, pLst, sizeof(LST));
- SemLeave();
- }
-
-
-
- HWND HwndFromHsz(hsz, pLst)
- HSZ hsz;
- PLST pLst;
- {
- HWNDHSZLI hhli;
- PHWNDHSZLI phhli;
-
- hhli.hsz = hsz;
- if (!(phhli = (PHWNDHSZLI)FindLstItem(pLst, CmppHsz, (PLITEM)&hhli)))
- return(NULL);
- return(phhli->hwnd);
- }
-
-
-
- /***************************** Private Function ****************************\
- * DESCRIPTION:
- * Advise list helper functions.
- *
- * History: 1/20/89 Created sanfords
- \***************************************************************************/
- BOOL AddAdvList(pLst, hszItem, fsStatus, usFmt)
- PLST pLst;
- HSZ hszItem;
- USHORT fsStatus;
- USHORT usFmt;
- {
- PADVLI pali;
-
- AssertF(pLst->cbItem == sizeof(ADVLI), "AddAdvList - bad item size");
- if (hszItem == NULL)
- return(TRUE);
- SemEnter();
- if (!(pali = FindAdvList(pLst, hszItem, usFmt))) {
- IncHszCount(hszItem);
- pali = (PADVLI)NewLstItem(pLst, ILST_FIRST);
- }
- AssertF((BOOL)pali, "AddAdvList - NewLstItem() failed")
- if (pali != NULL) {
- pali->hszItem = hszItem;
- pali->usFmt = usFmt;
- pali->fsStatus = fsStatus;
- }
- SemLeave();
- return((BOOL)pali);
- }
-
-
-
- /*
- * This will delete the matching Advise loop entry. If usFmt is 0, all
- * entries with the same hszItem are deleted. Returns fNotEmptyAfterDelete.
- */
- BOOL DeleteAdvList(pLst, hszItem, usFmt)
- PLST pLst;
- HSZ hszItem;
- USHORT usFmt;
- {
- PADVLI pali;
-
- if (hszItem == NULL)
- return((BOOL)pLst->pItemFirst);
- SemEnter();
- while (pali = (PADVLI)FindAdvList(pLst, hszItem, usFmt)) {
- FreeHsz((pali)->hszItem);
- RemoveLstItem(pLst, (PLITEM)pali);
- }
- SemLeave();
- return((BOOL)pLst->pItemFirst);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This routine searches the advise list for and entry in hszItem. It returns
- * pAdvli only if the item is found.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- PADVLI FindAdvList(pLst, hszItem, usFmt)
- PLST pLst;
- HSZ hszItem;
- USHORT usFmt;
- {
- ADVLI advli;
-
- advli.hszItem = hszItem;
- advli.usFmt = usFmt;
- return((PADVLI)FindLstItem(pLst, CmpAdv, (PLITEM)&advli));
- }
-
-
- /***************************** Private Function ****************************\
- * This routine searches for the next entry for hszItem. It returns
- * pAdvli only if the item is found.
- *
- * History:
- * Created 11/15/89 Sanfords
- \***************************************************************************/
- PADVLI FindNextAdv(padvli, hszItem)
- PADVLI padvli;
- HSZ hszItem;
- {
-
- SemEnter();
- while ((padvli = (PADVLI)padvli->next) != NULL) {
- if (padvli->hszItem == hszItem) {
- SemLeave();
- return(padvli);
- }
- }
- SemLeave();
- return(NULL);
- }
-
-
-
- /***************************** Pile Functions *******************************
- *
- * A pile is a list where each item is an array of subitems. This allows
- * a more memory efficient method of handling unordered lists.
- *
- \****************************************************************************
-
- PPILE CreatePile(hheap, cbItem, cItemsPerBlock)
- HHEAP hheap;
- USHORT cbItem;
- USHORT cItemsPerBlock;
- {
- PPILE ppile;
-
- if (!(ppile = (PPILE)FarAllocMem(hheap, sizeof(PILE)))) {
- SemLeave();
- return(NULL);
- }
- ppile->pBlockFirst = (PLITEM)NULL;
- ppile->hheap = hheap;
- ppile->cbBlock = cbItem * cItemsPerBlock + sizeof(PILEB);
- ppile->cSubItemsMax = cItemsPerBlock;
- ppile->cbSubItem = cbItem;
- return(ppile);
- }
-
-
- PPILE DestroyPile(pPile)
- PPILE pPile;
- {
- if (pPile == NULL)
- return(NULL);
- SemEnter();
- while (pPile->pBlockFirst)
- RemoveLstItem((PLST)pPile, (PLITEM)pPile->pBlockFirst);
- FarFreeMem(pPile->hheap, pPile, sizeof(PILE));
- SemLeave();
- return(NULL);
- }
-
- void FlushPile(pPile)
- PPILE pPile;
- {
- if (pPile == NULL)
- return;
- SemEnter();
- while (pPile->pBlockFirst)
- RemoveLstItem((PLST)pPile, (PLITEM)pPile->pBlockFirst);
- SemLeave();
- }
-
-
- USHORT QPileItemCount(pPile)
- PPILE pPile;
- {
- register USHORT c;
- PPILEB pBlock;
-
- if (pPile == NULL)
- return(0);
-
- SemEnter();
- pBlock = pPile->pBlockFirst;
- c = 0;
- while (pBlock) {
- c += pBlock->cItems;
- pBlock = pBlock->next;
- }
- SemLeave();
- return(c);
- }
-
-
- BOOL CopyPileItems(pPile, pDst)
- PPILE pPile;
- PBYTE pDst;
- {
- PPILEB pBlock;
-
- AssertF(pDst != NULL, "CopyPileItems - NULL destination");
- if (pPile == NULL)
- return(FALSE);
-
- SemEnter();
- pBlock = pPile->pBlockFirst;
- while (pBlock) {
- CopyBlock((PBYTE)pBlock + sizeof(PILEB), pDst,
- pBlock->cItems * pPile->cbSubItem);
- pDst += pBlock->cItems * pPile->cbSubItem;
- pBlock = pBlock->next;
- }
- SemLeave();
-
- return(TRUE);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * Locate and return the pointer to the pile subitem who's key fields match
- * pbSearch using npfnCmp to compare the fields. If pbSearch == NULL, or
- * npfnCmp == NULL, the first subitem is returned.
- *
- * afCmd may be:
- * FPI_DELETE - delete the located item
- * FPI_COUNT - count number of items that match
- * In this case, the returned pointer is not valid.
- *
- * pppb points to where to store a pointer to the block which contained
- * the located item.
- *
- * if pppb == NULL, it is ignored.
- *
- * NULL is returned if pbSearch was not found or if the list was empty.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- PBYTE FindPileItem(pPile, npfnCmp, pbSearch, afCmd)
- PPILE pPile;
- NPFNCMP npfnCmp;
- PBYTE pbSearch;
- USHORT afCmd;
- {
- PBYTE pb;
- PPILEB ppbT;
- register int i;
- register int c;
-
- if (pPile == NULL)
- return(NULL);
- c = 0;
- SemEnter();
- ppbT = pPile->pBlockFirst;
- while (ppbT) {
- /*
- * for each block...
- */
- for (pb = (PBYTE)ppbT + sizeof(PILEB), i = 0;
- i < ppbT->cItems; pb += pPile->cbSubItem, i++) {
- /*
- * and each item within that block..
- */
- if (pbSearch == NULL || npfnCmp == NULL ||
- (*npfnCmp)(pb, pbSearch)) {
- /*
- * If it matches or we don't care...
- */
- if (afCmd & FPI_DELETE) {
- /*
- * remove entire block if this was the last subitem in it
- */
- if (--ppbT->cItems == 0) {
- RemoveLstItem((PLST)pPile, (PLITEM)ppbT);
- } else {
- /*
- * copy last subitem in the block over the removed it
- */
- CopyBlock((PBYTE)ppbT + sizeof(PILEB) +
- pPile->cbSubItem * ppbT->cItems,
- pb, pPile->cbSubItem);
- }
- }
- if (afCmd & FPI_COUNT) {
- c++;
- } else {
- SemLeave();
- return(pb);
- }
- if (afCmd & FPI_DELETE) {
- pb = (PBYTE)ppbT + sizeof(PILEB);
- i = 0;
- }
- }
- }
- ppbT = (PPILEB)ppbT->next;
- }
- SemLeave();
- return((PBYTE)(ULONG)c);
- }
-
-
- /***************************** Private Function ****************************\
- * Places a copy of the subitem pointed to by pb into the first available
- * spot in the pile pPile. If npfnCmp != NULL, the pile is first searched
- * for a pb match. If found, pb replaces the located data but FALSE is
- * returned to show that no real addition took place.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- BOOL AddPileItem(pPile, pb, npfnCmp)
- PPILE pPile;
- PBYTE pb;
- BOOL (*npfnCmp)(PBYTE pb, PBYTE pbSearch);
- {
- PBYTE pbDst;
- PPILEB ppb;
-
- if (pPile == NULL)
- return(FALSE);
- SemEnter();
- if (npfnCmp != NULL &&
- (pbDst = FindPileItem(pPile, npfnCmp, pb, 0)) != NULL) {
- CopyBlock(pb, pbDst, pPile->cbSubItem);
- SemLeave();
- return(FALSE);
- }
- ppb = pPile->pBlockFirst;
- /*
- * locate a block with room
- */
- while ((ppb != NULL) && ppb->cItems == pPile->cSubItemsMax) {
- ppb = (PPILEB)ppb->next;
- }
- /*
- * If all full or no blocks, make a new one, link it on the bottom.
- */
- if (ppb == NULL) {
- if ((ppb = (PPILEB)NewLstItem((PLST)pPile, ILST_LAST)) == NULL) {
- SemLeave();
- return(FALSE);
- }
- ppb->cItems = 0;
- }
- /*
- * add the subitem
- */
- CopyBlock(pb, (PBYTE)ppb + sizeof(PILEB) + pPile->cbSubItem * ppb->cItems
- pPile->cbSubItem);
-
- SemLeave();
- return(TRUE);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * Fills pb with a copy of the top item's data and removes it from the pile.
- * returns FALSE if the pile was empty.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- BOOL PopPileSubitem(pPile, pb)
- PPILE pPile;
- PBYTE pb;
- {
- PPILEB ppb;
- PBYTE pSrc;
-
-
- if ((pPile == NULL) || ((ppb = pPile->pBlockFirst) == NULL))
- return(FALSE);
-
- SemEnter();
- pSrc = (PBYTE)pPile->pBlockFirst + sizeof(PILEB);
- CopyBlock(pSrc, pb, pPile->cbSubItem);
- /*
- * remove entire block if this was the last subitem in it.
- */
- if (pPile->pBlockFirst->cItems == 1) {
- RemoveLstItem((PLST)pPile, (PLITEM)pPile->pBlockFirst);
- } else {
- /*
- * move last item in block to replace copied subitem and decrement
- * subitem count.
- */
- CopyBlock(pSrc + pPile->cbSubItem * --pPile->pBlockFirst->cItems,
- pSrc, pPile->cbSubItem);
- }
- SemLeave();
- return(TRUE);
- }
-
-
- /***************************** Semaphore Functions *************************\
- * SemEnter() and SemLeave() are macros.
- *
- * History: 1/1/89 Created sanfords
- \***************************************************************************/
- void SemInit()
- {
- PBYTE pSem;
- SHORT c;
-
- pSem = (PBYTE)&FSRSemDmg;
- c = 0;
- while (c++ < sizeof(DOSFSRSEM)) {
- *pSem++ = 0;
- }
- FSRSemDmg.cb = sizeof(DOSFSRSEM);
- }
-
- #ifdef DEBUG
- void SemCheckIn()
- {
- PIDINFO pi;
- BOOL fin;
-
- DosGetPID(&pi);
- fin = (FSRSemDmg.cUsage > 0) &&
- (FSRSemDmg.pid == pi.pid) &&
- ((FSRSemDmg.tid == pi.tid) || (FSRSemDmg.tid == -1));
- /*
- * !!! NOTE: during exitlists processing, semaphore TIDs are set to -1
- */
- AssertF(fin, "SemCheckIn - Out of Semaphore");
- if (!fin)
- SemEnter();
- }
-
- void SemCheckOut()
- {
- PIDINFO pi;
- BOOL fOut;
-
- DosGetPID(&pi);
- fOut = FSRSemDmg.cUsage == 0 || FSRSemDmg.pid != pi.pid ||
- FSRSemDmg.tid != pi.tid;
- AssertF(fOut, "SemCheckOut - In Semaphore");
- if (!fOut)
- while (FSRSemDmg.cUsage)
- SemLeave();
-
- }
- #endif
-
-
- void SemEnter()
- {
- DosFSRamSemRequest(&FSRSemDmg, SEM_INDEFINITE_WAIT);
- }
-
-
- void SemLeave()
- {
- DosFSRamSemClear(&FSRSemDmg);
- }
-
-
-
- void EXPENTRY ExlstAbort(usTermCode)
- USHORT usTermCode;
- {
- PAPPINFO pai;
- usTermCode;
-
- SemEnter(); /* get any other processes out of the semaphore */
- if (pai = GetCurrentAppInfo(FALSE)) {
- pai->cInCallback = 0; /* so Unregister call will work */
- DdeUninitialize();
- } else {
- SemLeave();
- DosExitList(EXLST_REMOVE, (PFNEXITLIST)ExlstAbort);
- }
- DosExitList(EXLST_EXIT, 0);
- }
-
- BOOL CopyHugeBlock(pSrc, pDst, cb)
- PBYTE pSrc;
- PBYTE pDst;
- ULONG cb;
- {
- ULONG cFirst;
- /*
- * |____________| |___________| |____________| |____________|
- * ^src ^
- *
- * |____________| |___________| |____________| |____________|
- * ^dst ^
- */
- cFirst = (ULONG)min((~(USHORT)pSrc), (~(USHORT)pDst)) + 1L;
- if (cb < cFirst) {
- CopyBlock(pSrc, pDst, (USHORT)cb);
- return(TRUE);
- }
-
- goto copyit;
-
- /*
- * Now at least one of the pointers is on a segment boundry.
- */
- while (cb) {
- cFirst = min(0x10000 - ((USHORT)pSrc | (USHORT)pDst), cb);
- copyit:
- if (HIUSHORT(cFirst)) {
- /*
- * special case where pSrc and pDst both are on segment
- * bounds. Copy half at a time.
- */
- /*
- * |___________| |____________| |____________|
- * ^src ^
- *
- * |___________| |____________| |____________|
- * ^dst ^
- */
- cFirst >>= 1;
- CopyBlock(pSrc, pDst, (USHORT)cFirst);
- pSrc += cFirst;
- pDst += cFirst;
- cb -= cFirst;
- }
- CopyBlock(pSrc, pDst, (USHORT)cFirst);
- pSrc = HugeOffset(pSrc, cFirst);
- pDst = HugeOffset(pDst, cFirst);
- cb -= cFirst;
- /*
- * |____________| |___________| |____________| |____________|
- * ^src ^
- *
- * |____________| |___________| |____________| |____________|
- * ^dst ^
- */
- }
- return(TRUE);
- }
-
-
-
-
- /***************************************************************************\
- * Kills windows but avoids invalid window rips in debugger.
- \***************************************************************************/
- BOOL DestroyWindow(hwnd)
- HWND hwnd;
- {
- if (WinIsWindow(DMGHAB, hwnd))
- return(WinDestroyWindow(hwnd));
- return(TRUE);
- }
-
-
- /***************************** Private Function ****************************\
- * Returns hConv of the window passed in is one of the ddeml windows.
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- HCONV IsDdeWindow(hwnd)
- HWND hwnd;
- {
- PAPPINFO pai;
-
- pai = pAppInfoList;
-
- while (pai && WinIsChild(hwnd, pai->hwndDmg))
- pai = pai->next;
-
- if (pai)
- return((HCONV)hwnd);
- else
- return(0L);
- }
-
-
- /***************************** Private Function ****************************\
- * This routine only frees a MYDDES segment if this process is not the owner.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- void FreeData(
- PMYDDES pmyddes,
- PAPPINFO pai)
- {
- TID tid;
- if (!CheckSel(SELECTOROF(pmyddes)) ||
- ( pmyddes->offszItemName == sizeof(MYDDES) &&
- pmyddes->magic == MYDDESMAGIC &&
- pmyddes->fs & HDATA_APPOWNED &&
- pmyddes->pai == pai) )
- return;
-
- SemEnter();
- FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&pmyddes, FPI_DELETE);
- tid = pai->tid;
- do {
- if (FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&pmyddes, FPI_COUN
- SemLeave();
- return;
- }
- pai = pai->nextThread;
- } while (pai && pai->tid != tid);
- SemLeave();
- DosFreeSeg(SELECTOROF(pmyddes));
- }
-
-
-
- #ifdef DEBUG
- int APIENTRY DebugOutput(PCH);
- void fAssert(f, pszComment, line, szfile)
- BOOL f;
- PSZ pszComment;
- USHORT line;
- PSZ szfile;
- {
- char szT[90];
- PSZ psz, pszLast;
-
- if (!f) {
- szT[0] = '\000';
- psz = szT;
- pszLast = &szT[89];
- psz = lstrcat(psz, "\n\rAssertion failure: ", pszLast);
- psz = lstrcat(psz, szfile, pszLast);
- psz = lstrcat(psz, ":", pszLast);
- psz = dtoa(psz, line, FALSE);
- psz = lstrcat(psz, " ", pszLast);
- psz = lstrcat(psz, pszComment, pszLast);
- psz = lstrcat(psz, "\n\r", pszLast);
- DebugOutput(szT);
- DebugBreak();
- }
- }
- #endif
-
-
-
- HDMGDATA PutData(pSrc, cb, cbOff, hszItem, usFmt, afCmd, pai)
- PBYTE pSrc;
- ULONG cb;
- ULONG cbOff;
- HSZ hszItem;
- USHORT usFmt;
- USHORT afCmd;
- PAPPINFO pai;
- {
- PMYDDES pmyddes;
-
- if ((pmyddes = (PMYDDES)AllocDDESel(0, usFmt, hszItem, cb + cbOff, pai))
- == NULL) {
- pai->LastError = DMGERR_MEMORY_ERROR;
- return(0L);
- }
- pmyddes->fs = afCmd;
-
- if (afCmd & HDATA_APPFREEABLE) {
- if (!AddPileItem(pai->pHDataPile, (PBYTE)&pmyddes, CmpULONG)) {
- DosFreeSeg(SELECTOROF(pmyddes));
- pai->LastError = DMGERR_MEMORY_ERROR;
- return(0L);
- }
- }
- if (pSrc)
- CopyHugeBlock(pSrc, HugeOffset(DDES_PABDATA(pmyddes), cbOff), cb);
- return(pmyddes);
- }
-
-
- /*
- * This routine adds all HSZ/HAPP pairs it finds for the given pai matching
- * hszApp to hDataAdd.
- * poffAdd is the offset into the hDataAdd to start inserting HSZ/HAPP
- * pairs. It then truncates the list with a 0 HSZ and returns the offset
- * to the terminator (ready to be called again to add more).
- *
- * returns 0L on error.
- */
- ULONG
- QueryAppNames(
- PAPPINFO pai,
- HDMGDATA hDataAdd,
- HSZ hszApp,
- ULONG offAdd)
- {
- USHORT chsz;
- PHSZ phsz, phszPile;
- PPILEB pBlock;
-
- AssertF(sizeof(HSZ) == sizeof(HAPP), "Type size conflict");
-
- SemEnter();
- if (chsz = (USHORT)FindPileItem(pai->pAppNamePile,
- hszApp ? CmpULONG : NULL, (PBYTE)&hszApp, FPI_COUNT)) {
- /*
- * allocate for additions.
- */
- if (!DdeAddData(hDataAdd, NULL,
- (chsz + 1L) * (sizeof(HSZ) + sizeof(HDMGDATA)), offAdd)) {
- offAdd = 0L;
- GetCurrentAppInfo(FALSE)->LastError = DMGERR_MEMORY_ERROR;
- goto Exit;
- }
-
- phsz = DDES_PABDATA((PDDESTRUCT)hDataAdd) + offAdd;
- if (hszApp) {
- *phsz++ = hszApp; /* only one per thread expected */
- *phsz++ = (HSZ)pai->hwndFrame;
- } else {
- pBlock = pai->pAppNamePile->pBlockFirst;
- while (pBlock) {
- phszPile = (PHSZ)(pBlock + 1);
- for (chsz = 0; chsz < pBlock->cItems; chsz++) {
- *(phsz++) = *(phszPile++);
- *(phsz++) = (HSZ)pai->hwndFrame;
- }
- pBlock = pBlock->next;
- }
- }
- *phsz = 0L;
- offAdd = phsz - DDES_PABDATA((PDDESTRUCT)hDataAdd);
- }
- Exit:
- SemLeave();
- return(offAdd);
- }
-
-
-
- DMGDDE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGDDE.C
-
- /****************************** Module Header ******************************\
- * Module Name: DMGDDE.C
- *
- * This module contains functions used for interfacing with DDE structures
- * and such.
- *
- * Created: 12/23/88 sanfords
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
- #include "ddemlp.h"
-
- /***************************** Private Function ****************************\
- * timeout()
- *
- * This routine creates a timer for hwndTimeout. It then runs a modal loop
- * which will exit once the WM_TIMER message is received by hwndTimeout.
- * hwndTimeout can be any window that doesn't use timers itself with TID_TIMEO
- * or TID_ABORT since its window proc doesn't need to do
- * anything for this to work. Only the client and server windows use these
- * so were cool.
- * Only one timeout window is allowed per thread. This is checked by the
- * pai passed in.
- *
- * Returns fSuccess, ie TRUE if TID_TIMEOUT was received before TID_ABORT.
- *
- * PUBDOC START
- * Synchronous client transaction modal loops:
- *
- * During Synchronous transactions, a client application will enter a modal
- * loop while waiting for the server to respond to the request. If an
- * application wishes to filter messages to the modal loop, it may do so
- * by setting a message filter tied to MSGF_DDE. Applications should
- * be aware however that the DDE modal loop processes private messages
- * in the WM_USER range, WM_DDE messages, and WM_TIMER messages with timer IDs
- * using the TID_ constants defined in ddeml.h.
- * These messages must not be filtered by an application!!!
- *
- * PUBDOC END
- *
- * History:
- * Created sanfords 12/19/88
- \***************************************************************************/
- BOOL timeout(pai, ulTimeout, hwndTimeout)
- PAPPINFO pai;
- ULONG ulTimeout;
- HWND hwndTimeout;
- {
- QMSG qmsg;
-
- SemEnter();
- if (pai->hwndTimer) {
- pai->LastError = DMGERR_REENTRANCY;
- AssertF(FALSE, "Recursive timeout call");
- SemLeave();
- return(FALSE);
- }
- pai->hwndTimer = hwndTimeout;
- SemLeave();
-
- WinStartTimer(DMGHAB, hwndTimeout, TID_TIMEOUT, (USHORT)ulTimeout);
-
- WinGetMsg(DMGHAB, &qmsg, (HWND)NULL, 0, 0);
-
- /*
- * stay in modal loop until a timeout happens.
- */
- while (qmsg.hwnd != hwndTimeout ||
- qmsg.msg != WM_TIMER ||
- (LOUSHORT(qmsg.mp1) != TID_TIMEOUT &&
- LOUSHORT(qmsg.mp1) != TID_ABORT)) {
-
- if (!WinCallMsgFilter(DMGHAB, &qmsg, MSGF_DDE))
- WinDispatchMsg(DMGHAB, &qmsg);
-
- WinGetMsg(DMGHAB, &qmsg, (HWND)NULL, 0, 0);
- }
-
- WinStopTimer(DMGHAB, hwndTimeout, TID_TIMEOUT);
- SemEnter();
- pai->hwndTimer = 0;
- SemLeave();
- /*
- * post a callback check incase we blocked callbacks due to being
- * in a timeout.
- */
- WinPostMsg(pai->hwndDmg, UM_CHECKCBQ, (MPARAM)pai, 0L);
- return(LOUSHORT(qmsg.mp1) == TID_TIMEOUT);
- }
-
-
- /***************************** Private Function ****************************\
- *
- * Based on pii, this sends an INITIATE message to either an exact
- * target window (hwndSend), a target frame window (hwndFrame) or to all
- * top level frames (both hwnds are NULL). It fills in pci info as apropriat
- * Note that pii->pCC must NOT be NULL and is assumed to be properly set.
- *
- * Returns FALSE if SendDDEInit failed.
- * On success pci->ci.xad.state is CONVST_CONNECTED.
- *
- * History:
- * created 12/21/88 sanfords
- \***************************************************************************/
- BOOL ClientInitiate(hwnd, pii, pci)
- HWND hwnd;
- PINITINFO pii;
- PCLIENTINFO pci;
- {
- BOOL fRet = TRUE;
-
- if (pii->pCC->cb < sizeof(CONVCONTEXT))
- return(FALSE);
-
- SemEnter();
- /*
- * we need to set this info BEFORE we do the synchronous initiate
- * so the INITIATEACK msg is done correctly.
- */
- pci->ci.xad.state = CONVST_INIT1;
- pci->ci.xad.LastError = DMGERR_NO_ERROR;
- pci->ci.hszServerApp = pii->hszAppName;
- pci->ci.hszTopic = pii->hszTopic;
- pci->ci.cc.cb = sizeof(CONVCONTEXT);
- CopyBlock((PBYTE)&pii->pCC->fsContext, (PBYTE)&pci->ci.cc.fsContext,
- sizeof(CONVCONTEXT) - sizeof(USHORT));
- pci->ci.hwndFrame = pii->hwndFrame;
- SemLeave();
-
- fRet = SendDDEInit(hwnd,
- WinIsWindow(DMGHAB, pii->hwndSend) ? pii->hwndSend : pii->hwndFra
- pci);
- SemEnter();
- /*
- * If we failed to initiate directly with the server, try the frame.
- */
- if (!fRet && WinIsWindow(DMGHAB, pii->hwndSend) &&
- WinIsWindow(DMGHAB, pii->hwndFrame)) {
- SemLeave();
- fRet = SendDDEInit(hwnd, pii->hwndFrame, pci);
- if (fRet) {
- /*
- * OK, client is locked in so he wont go away on a terminate
- * from a random window. If the new server is not the same
- * window as the origonal, send it a terminate so it can
- * go away nicely.
- */
- if (pii->hwndSend != pci->ci.hwndPartner)
- WinSendMsg(pii->hwndSend, WM_DDE_TERMINATE, 0L, 0L);
- }
- SemEnter();
-
- }
- if (!fRet)
- pci->ci.xad.state = CONVST_NULL;
- else {
- /*
- * successful initiate means we want to keep these around awhile.
- * removed at window closing time.
- */
- IncHszCount(pci->ci.hszServerApp);
- IncHszCount(pci->ci.hszTopic);
- }
- SemLeave();
- return(fRet);
- }
-
-
-
- /***************************** Private Function ****************************\
- * Allocates and sends a WM_DDE_INITIATE message to hwndTo. Any failures
- * cause FALSE to be returned. If hwndTo is NULL, performs equivalent of
- * WinDdeInitiate2().
- *
- * History:
- * created 12/22/88 sanfords
- * 2/2/89 sanfords added SEG_GETABLE during monitoring.
- \***************************************************************************/
- BOOL SendDDEInit(hwndFrom, hwndTo, pci)
- HWND hwndFrom;
- HWND hwndTo;
- PCLIENTINFO pci;
- {
- PID pidTo;
- TID tid;
- SEL sel;
- PDDEINIT pddeinit;
- HENUM henum;
- ULONG ul;
- USHORT cchApp, cchTopic;
- PSZ pszApp, pszTopic;
- BOOL fEnumerating; /* set if extra acks are ok */
-
- SemCheckOut();
-
- if (hwndTo == NULL) {
- /*
- * Call on self for all top level frame windows until we are connecte
- * (if enumerating, do em all anyway.)
- */
- fEnumerating = WinQueryWindow(hwndFrom, QW_PARENT, FALSE) !=
- pci->ci.pai->hwndDmg;
- if (henum = WinBeginEnumWindows(HWND_DESKTOP)) {
- while ((hwndTo = WinGetNextWindow(henum)) &&
- (fEnumerating || pci->ci.xad.state == CONVST_INIT1)) {
- if (hwndTo != pci->ci.pai->hwndFrame &&
- (ul = (ULONG)WinSendMsg(hwndTo, WM_QUERYFRAMEINFO, 0L
- (ul & FI_FRAME))
- SendDDEInit(hwndFrom, hwndTo, pci);
- }
- WinEndEnumWindows(henum);
- }
- return(TRUE);
- }
-
- if (WinQueryWindowProcess(hwndTo, &pidTo, &tid) == NULL)
- return(FALSE);
-
- SemEnter();
- pszApp = pszFromHsz(pci->ci.hszServerApp, &cchApp);
- pszTopic = pszFromHsz(pci->ci.hszTopic, &cchTopic);
- if (DosAllocSeg(sizeof(DDEINIT) + sizeof(CONVCONTEXT) + cchApp + cchTopic
- &sel, SEG_GIVEABLE) != 0) {
- SemLeave();
- return(FALSE);
- }
- pddeinit = MAKEP(sel, 0);
- pddeinit->cb = sizeof(DDEINIT);
- pddeinit->offConvContext = sizeof(DDEINIT);
- pddeinit->pszAppName = (PSZ)pddeinit + sizeof(DDEINIT) + sizeof(CONVCONTE
- pddeinit->pszTopic = pddeinit->pszAppName + cchApp;
- CopyBlock((PBYTE)&pci->ci.cc, (PBYTE)DDEI_PCONVCONTEXT(pddeinit), sizeof(
- CopyBlock((PBYTE)pszApp, (PBYTE)pddeinit->pszAppName, cchApp);
- CopyBlock((PBYTE)pszTopic, (PBYTE)pddeinit->pszTopic, cchTopic);
- FarFreeMem(hheapDmg, pszApp, cchApp);
- FarFreeMem(hheapDmg, pszTopic, cchTopic);
- SemLeave();
-
- if (DosGiveSeg(sel, pidTo, &sel) != 0) {
- DosFreeSeg(sel);
- return(FALSE);
- }
-
- WinSendMsg(hwndTo, WM_DDE_INITIATE, (MPARAM)hwndFrom, pddeinit);
- if (pidTo != pci->ci.pai->pid)
- DosFreeSeg(sel);
- return(TRUE);
- }
-
-
-
- /***************************** Private Function ****************************\
- *
- * Alocates and fills in a MYDDES. if pai == 0, the MYDDES is considered
- * unowned.
- *
- * History: created 1/4/89 sanfords
- * 10/18/89 sanfords Added hack so that if usFmt==DDEFMT_TEXT and hszItem==0L
- * the data and item strings are one.
- * (This allows for excel EXEC compatibility)
- * 2/2/89 sanfords Added GETABLE during monitoring.
- * 6/13/90 sanfords Altered to not expand hszItem at this point.
- \***************************************************************************/
- PDDESTRUCT AllocDDESel(fsStatus, usFmt, hszItem, cbData, pai)
- USHORT fsStatus;
- USHORT usFmt;
- HSZ hszItem;
- ULONG cbData;
- PAPPINFO pai;
- {
- PMYDDES pmyddes = NULL;
- ULONG cbTotal;
- ULONG cchItem;
- SEL sel;
-
- SemEnter();
- cchItem = DdeGetHszString(hszItem, NULL, 0L) + 1L;
-
- /*
- * This hack makes execs conform to EXCELs way.
- */
- if (!hszItem && usFmt == DDEFMT_TEXT)
- cchItem = 0L;
-
- cbTotal = sizeof(MYDDES) + cchItem + cbData + 1;
- if (cbTotal <= 0xFFFF) {
- if (DosAllocSeg((USHORT)cbTotal, &sel, SEG_GIVEABLE) != 0)
- goto allocDdeExit;
- } else {
- if (DosAllocHuge((USHORT)(cbTotal >> 16), (USHORT)cbTotal, &sel,
- 0, SEG_GIVEABLE) != 0)
- goto allocDdeExit;
- }
-
- pmyddes = MAKEP(sel, 0);
- pmyddes->cbData = cbData;
- pmyddes->fsStatus = fsStatus;
- pmyddes->usFormat = usFmt;
- pmyddes->offszItemName = sizeof(MYDDES);
- pmyddes->offabData = sizeof(MYDDES) + (USHORT)cchItem;
- pmyddes->ulRes1 = 0L;
- pmyddes->magic = MYDDESMAGIC;
- pmyddes->hszItem = hszItem;
- pmyddes->pai = pai;
- pmyddes->fs = 0;
- *DDES_PABDATA((PDDESTRUCT)pmyddes) = '\0'; /* in case data is never place
- *DDES_PSZITEMNAME((PDDESTRUCT)pmyddes) = '\0'; /* we expand this at post
-
- allocDdeExit:
- SemLeave();
- return((PDDESTRUCT)pmyddes);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * This routine returns the hwnd of a newly created and connected DDE
- * client or NULL if failure.
- *
- * History: created 1/6/89 sanfords
- \***************************************************************************/
- HCONV GetDDEClientWindow(hConvList, hwndFrame, hwndSend, hszApp, hszTopic, pC
- HCONVLIST hConvList;
- HWND hwndFrame;
- HWND hwndSend;
- HSZ hszApp;
- HSZ hszTopic;
- PCONVCONTEXT pCC;
- {
- HCONV hConv;
- INITINFO ii;
- CONVCONTEXT cc;
-
- SemCheckOut();
-
- hConv = WinCreateWindow(hConvList, SZCLIENTCLASS, "", 0L,
- 0, 0, 0, 0, (HWND)NULL, HWND_TOP, WID_CLIENT, 0L, 0L);
-
- if (hConv == NULL)
- return(NULL);
-
- ii.hszTopic = hszTopic;
- ii.hszAppName = hszApp;
- ii.hwndSend = hwndSend;
- ii.hwndFrame = hwndFrame;
- if (pCC == NULL) {
- pCC = &cc;
- cc.cb = sizeof(CONVCONTEXT);
- cc.fsContext = 0;
- /*##LATER - may want to use process codepage instead */
- cc.usCodepage = syscc.codepage;
- cc.idCountry = syscc.country;
- }
- if (pCC->usCodepage == 0)
- pCC->usCodepage = syscc.codepage;
- if (pCC->idCountry == 0)
- pCC->idCountry = syscc.country;
-
- ii.pCC = pCC;
- WinSendMsg(hConv, UMCL_INITIATE, (MPARAM)&ii, 0L);
-
- if (!((USHORT)WinSendMsg(hConv, UM_QUERY, (MPARAM)Q_STATUS, 0L) &
- ST_CONNECTED)) {
- WinDestroyWindow(hConv);
- return(NULL);
- }
- return(hConv);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This routine institutes a callback directly if psi->fEnableCB is set
- * and calls QReply to complete the transaction,
- * otherwise it places the data into the queue for processing.
- *
- * Since hDmgData may be freed by the app at any time once the callback is
- * issued, we cannot depend on it being there for QReply. Therefore we
- * save all the pertinant data in the queue along with it.
- *
- * Returns fSuccess.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- BOOL MakeCallback(pai, hConv, hszTopic, hszItem, usFmt, usType, hDmgData,
- msg, fsStatus, hConvClient)
- PAPPINFO pai;
- HCONV hConv;
- HSZ hszTopic;
- HSZ hszItem;
- USHORT usFmt;
- USHORT usType;
- HDMGDATA hDmgData;
- USHORT msg;
- USHORT fsStatus;
- HCONV hConvClient;
- {
- PCBLI pcbli;
-
- SemEnter();
-
- if (!(pcbli = (PCBLI)NewLstItem(pai->plstCB, ILST_LAST))) {
- pai->LastError = DMGERR_MEMORY_ERROR;
- SemLeave();
- return(FALSE);
- }
- pcbli->hConv = hConv;
- pcbli->hszTopic = hszTopic;
- pcbli->hszItem = hszItem;
- pcbli->usFmt = usFmt;
- pcbli->usType = usType;
- pcbli->hDmgData = hDmgData;
- pcbli->msg = msg;
- pcbli->fsStatus = fsStatus;
- pcbli->hConvPartner = hConvClient;
-
- if (pai->fEnableCB && !pai->hwndTimer) {
- SemLeave();
- WinPostMsg(pai->hwndDmg, UM_CHECKCBQ, (MPARAM)pai, 0L);
- } else
- SemLeave();
-
- return(TRUE);
- }
-
-
-
- /*************************************************************************\
- * Attempts to post a DDE message to hwndTo. Properly frees up pmyddes
- * if afCmd has MDPM_FREEHDATA set. We do not add pmyddes to the target
- * thread list since we assume that will be done at the receiving end
- * if necessary.
- *
- * Returns fSuccess.
- *
- * 6/12/90 sanfords Created
- * 6/13/90 sanfords Made it convert hszItem to a string at this point
- * only if hwndTo is not a local guy.
- \*************************************************************************/
- BOOL MyDdePostMsg(
- HWND hwndTo,
- HWND hwndFrom,
- USHORT msg,
- PMYDDES pmyddes,
- PAPPINFO paiFrom,
- USHORT afCmd)
- {
- PID pid;
- TID tid;
- SEL selR;
- BOOL fRet;
- PFNWP pfnwpTo;
-
- if (!WinQueryWindowProcess(hwndTo, &pid, &tid))
- return FALSE;
-
- pfnwpTo = (PFNWP)WinQueryWindowPtr(hwndTo, QWP_PFNWP);
- if (cMonitor || (pfnwpTo != ServerWndProc && pfnwpTo != ClientWndProc)) {
- /*
- * its not local - expand hszItem if necessary - always
- * expand if a monitor is installed.
- */
- if (CheckSel(SELECTOROF(pmyddes)) >= sizeof(MYDDES) &&
- pmyddes->magic == MYDDESMAGIC &&
- pmyddes->hszItem &&
- !(pmyddes->fs & HDATA_PSZITEMSET)) {
- pmyddes->fs |= HDATA_PSZITEMSET;
- QueryHszName(pmyddes->hszItem, DDES_PSZITEMNAME(pmyddes),
- pmyddes->offabData - pmyddes->offszItemName);
- }
- }
- /*
- * Don't try to share seg with ourselves.
- */
- if (paiFrom->pid != pid) {
- selR = SELECTOROF(pmyddes);
- if (DosGiveSeg(SELECTOROF(pmyddes), pid, &selR))
- return FALSE;
- if (afCmd & MDPM_FREEHDATA)
- FreeData(pmyddes, paiFrom);
- } else {
- /*
- * just remove hData from our thread list
- */
- if (afCmd & MDPM_FREEHDATA && !(pmyddes->fs & HDATA_APPOWNED))
- FindPileItem(paiFrom->pHDataPile, CmpULONG, (PBYTE)&pmyddes,
- FPI_DELETE);
- }
- fRet = (BOOL)WinPostMsg(hwndTo, msg, (MPARAM)hwndFrom, (MPARAM)pmyddes);
- if (!fRet) {
- /*
- * make sure this is freed if it is supposed to be - this covers
- * the case where the target is of the same process and only
- * these two threads are registered.
- */
-
- tid = paiFrom->tid;
- do {
- if (FindPileItem(paiFrom->pHDataPile, CmpULONG, (PBYTE)&pmyddes,
- FPI_COUNT))
- return(FALSE); /* there is another thread that has this */
- paiFrom = paiFrom->nextThread;
- } while (paiFrom->tid != tid);
- DosFreeSeg(SELECTOROF(pmyddes));
- }
- return(fRet);
- }
-
-
- DMGHSZ.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGHSZ.C
-
- /****************************** Module Header ******************************\
- * Module Name: DMGLATOM.C
- *
- * This module contains functions used for HSZ control.
- *
- * Created: 8/2/88 sanfords
- * Added case preservation/insensitive 1/22/90 Sanfords
- * 6/12/90 sanfords Fixed HSZ local string allocation size errors.
- * Added latom validation checks
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
- #include "ddemlp.h"
-
-
- /*
- * since the top 12 bits of any latom is always 0 (unless we have > 16
- * atom tables!) we can encode any ulong into only 5 bytes.
- */
- #define ENCODEBYTES 5
- #define MAX_LATOMSTRSIZE 255 - ENCODEBYTES - 2
- char szT[MAX_LATOMSTRSIZE + 1 + ENCODEBYTES]; /* used for HSZ expansion */
-
- extern BOOL APIENTRY WinSetAtomTableOwner( HATOMTBL, PID );
-
-
- /*********************** LATOM management functions *************************
- * An HSZ is a long atom which holds an encoded reference to two other long
- * atoms. One long atom is for the actual string, the other is for its
- * uppercase version. Two HSZs are ranked by their uppercase latoms.
- * This makes HSZs case insensitive, case preserving. An latom
- * is an atom with an atom table index tacked onto the HIUSHORT part of
- * of the latom. Strings too long for the atom manager are split up and
- * each piece is prepended with a coded string that represents the
- * LATOM of the rest of the string. LATOM strings thus may be of any length.
- * (up to 64K in this version)
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
-
- /***************************** Private Function ****************************\
- * Allocates space in the DDE manager heap for a string queried from the DDE
- * manager latomtable. The case sensitive string is returned.
- *
- * This function should be serialized. Memory allocation or latom table failu
- * results in a 0 return value.
- *
- * 0 latoms result in a NULL terminated empty string.
- *
- * Note that *pcch is set to the length of the string INCLUDING the null
- * terminator. This way a wild string has a cch=1.
- *
- * History:
- * created 12/22/88 sanfords
- * 11/10/89 sanfords modified to return '\0' on invalid atom.
- \***************************************************************************/
- PSZ pszFromHsz(hsz, pcch)
- HSZ hsz;
- USHORT FAR *pcch;
- {
- PSZ psz;
- LATOM latom;
- char sz[ENCODEBYTES + 1];
- register USHORT cch;
-
- SemCheckIn();
-
- if (hsz == 0)
- cch = 1;
- else {
- QuerylatomName((LATOM)hsz, sz, ENCODEBYTES + 1);
- latom = Decode(sz); /* take origonal case version */
- cch = QuerylatomLength(latom) + 1;
- }
-
- psz = (PSZ)FarAllocMem(hheapDmg, cch);
- if (psz == 0) {
- *pcch = '\000';
- return(0);
- }
-
- if (hsz == 0) {
- *pcch = 1;
- *psz = '\0';
- } else {
- *pcch = cch;
- if (QuerylatomName(latom, psz, cch) == 0) {
- AssertF(FALSE, "pszFromHsz - bad latom");
- *psz = '\0'; /* invalid case - never expected */
- }
- }
- return(psz);
- }
-
-
- /***************************** Private Function ****************************\
- * HSZ GetHsz(psz, cc, cp, fAdd)
- * PSZ psz;
- * USHORT cc;
- * USHORT cp;
- * BOOL fAdd;
- *
- * The goal of this routine is to convert a psz to an hsz. This uses the
- * atom manager for its dirty work. This call has the side effect of
- * incrementing the use count for the hsz returned and its associated latoms
- * if fAdd is set.
- *
- * if fAdd is FALSE, NULL is returned if the hsz doesn't exist.
- *
- * History:
- * created 12/23/88 sanfords
- \***************************************************************************/
- HSZ GetHsz(psz, cc, cp, fAdd)
- PSZ psz;
- USHORT cc;
- USHORT cp;
- BOOL fAdd;
- {
- LATOM latom1, latom2;
- USHORT cb;
- PSZ pszT;
- BOOL fNew = FALSE;
- HSZ hsz;
-
- /*
- * NULL or 0 length pszs are considered wild HSZs.
- */
- if (psz == NULL || *psz == '\0')
- return(0L);
-
- SemEnter();
-
- if (!(latom1 = FindAddlatom(psz, fAdd))) {
- AssertF(!fAdd, "GetHsz - Atom Add failed");
- SemLeave();
- return(0L);
- }
-
- cb = lstrlen(psz) + 1;
-
- if (!(pszT = FarAllocMem(hheapDmg, max(cb, ENCODEBYTES * 2 + 1)))) {
- SemLeave();
- return(0L);
- }
-
- CopyBlock((PBYTE)psz, (PBYTE)pszT, cb);
- WinUpper(DMGHAB, cp ? cp : syscc.codepage, cc ? cc : syscc.country, pszT)
- latom2 = FindAddlatom(pszT, fAdd);
-
- if (!latom2) {
- AssertF(!fAdd, "GetHsz - Atom Add(2) failed");
- hsz = 0;
- } else {
- *Encode(latom2, Encode(latom1, pszT)) = '\000';
- hsz = (HSZ)FindAddlatom(pszT, fAdd);
- }
- FarFreeMem(hheapDmg, pszT, max(cb, ENCODEBYTES * 2 + 1));
- SemLeave();
- return(hsz);
- }
-
-
-
- /*
- * Note that all three associated latoms are freed.
- */
- BOOL FreeHsz(hsz)
- HSZ hsz;
- {
- char sz[ENCODEBYTES * 2 + 1];
-
- SemEnter();
- if (hsz && QuerylatomName((LATOM)hsz, sz, ENCODEBYTES * 2 + 1)) {
- Freelatom(Decode((PBYTE)sz));
- Freelatom(Decode((PBYTE)&sz[ENCODEBYTES]));
- Freelatom((LATOM)hsz);
- }
- SemLeave();
- return(TRUE);
- }
-
-
-
- /*
- * Note that all three associated latoms are incremented.
- */
- BOOL IncHszCount(hsz)
- HSZ hsz;
- {
- char sz[ENCODEBYTES * 2 + 1];
- register BOOL fRet;
-
- if (hsz == 0)
- return(TRUE);
-
- SemEnter();
-
- QuerylatomName((LATOM)hsz, sz, ENCODEBYTES * 2 + 1);
- fRet = InclatomCount(Decode((PBYTE)sz)) &&
- InclatomCount(Decode((PBYTE)&sz[ENCODEBYTES])) &&
- InclatomCount((LATOM)hsz);
- SemLeave();
- return(fRet);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This routine adds an atom table and returns its handle. Returns fSuccess.
- *
- * Effects cAtbls, aAtbls, iAtblCurrent;
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- BOOL AddAtomTable(fInit)
- BOOL fInit;
- {
- PHATOMTBL pat;
-
- SemEnter();
-
- if (!(pat = (PHATOMTBL)FarAllocMem(hheapDmg,
- sizeof(HATOMTBL) * (cAtbls + 1)))) {
- SemLeave();
- return(FALSE);
- }
-
- if (!fInit) {
- CopyBlock((PBYTE)aAtbls, (PBYTE)pat, sizeof(HATOMTBL) * cAtbls);
- FarFreeMem(hheapDmg, aAtbls, sizeof(HATOMTBL) * cAtbls);
- }
-
- aAtbls = pat;
-
- if (!(aAtbls[cAtbls] = WinCreateAtomTable(0, 0)))
- return(FALSE);
- /*
- * Share our atom tables with all processes...
- */
- if (!WinSetAtomTableOwner(aAtbls[cAtbls], NULL)) {
- AssertF(FALSE, "AddAtomTable - WinSetAtomTable failed");
- return(FALSE);
- }
- iAtblCurrent = cAtbls++;
- SemLeave();
- return(TRUE);
- }
-
-
-
- USHORT QueryHszLength(hsz)
- HSZ hsz;
- {
- char sz[ENCODEBYTES + 1];
- USHORT us;
-
- if (!hsz)
- return(0);
- SemEnter();
- QuerylatomName((LATOM)hsz, sz, ENCODEBYTES + 1);
- us = QuerylatomLength(Decode(sz));
- SemLeave();
- return(us);
- }
-
-
-
- USHORT QueryHszName(hsz, psz, cchMax)
- HSZ hsz;
- PSZ psz;
- USHORT cchMax;
- {
- char sz[ENCODEBYTES + 1];
- register USHORT usRet;
-
- if (hsz == 0) {
- if (psz)
- *psz = '\000';
- return(1);
- } else {
- usRet = 0;
- SemEnter();
- if (QuerylatomName((LATOM)hsz, sz, ENCODEBYTES + 1))
- usRet = QuerylatomName(Decode(sz), psz, cchMax);
- SemLeave();
- return(usRet);
- }
- }
-
-
-
- /*
- * returns 0 if ==, -1 if hsz1 < hsz2, 1 if hsz1 > hsz2, 2 on error
- */
- SHORT CmpHsz(hsz1, hsz2)
- HSZ hsz1, hsz2;
- {
- char sz[ENCODEBYTES * 2 + 1];
- LATOM latom;
- SHORT usRet;
-
- if (hsz1 == hsz2)
- return(0);
- if (!hsz1)
- return(-1);
- if (!hsz2)
- return(1);
-
- usRet = 2;
- SemEnter();
- if (QuerylatomName((LATOM)hsz1, sz, ENCODEBYTES * 2 + 1)) {
- latom = Decode(&sz[ENCODEBYTES]); /* use UPPERCASE form for compari
- if (QuerylatomName((LATOM)hsz2, sz, ENCODEBYTES * 2 + 1)) {
- latom = latom - Decode(&sz[ENCODEBYTES]);
- usRet = latom == 0 ? 0 : (latom > 0 ? 1 : -1);
- }
- }
- SemLeave();
- return(usRet);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * Returns the length of the latom given without NULL terminator.
- * Wild LATOMs have a length of 0.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- USHORT QuerylatomLength(latom)
- LATOM latom;
- {
- USHORT cb;
- USHORT cbT = 0;
- BYTE ab[ENCODEBYTES + 1];
-
- AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");
- if (latom == 0)
- return(0);
- SemCheckIn();
- while (TRUE) {
- if (!(cb = WinQueryAtomLength(aAtbls[HIUSHORT(latom)],
- LOUSHORT(latom)))) {
- AssertF(cbT == 0, "QuerylatomLength - failed on continued latom")
- return(0);
- }
-
- cbT += cb;
-
- if (cb <= MAX_LATOMSTRSIZE) {
- return(cbT);
- }
-
- /*
- * it MUST be a huge latom.
- */
- if (!(WinQueryAtomName(aAtbls[HIUSHORT(latom)], LOUSHORT(latom),
- (PSZ)ab, ENCODEBYTES + 1))) {
- AssertF(FALSE, "QuerylatomLength - Length but no name");
- return(0);
- }
-
- latom = Decode(ab);
- cbT -= ENCODEBYTES;
- }
- }
-
-
-
- USHORT QuerylatomName(latom, psz, cchMax)
- LATOM latom;
- PSZ psz;
- USHORT cchMax;
- {
- USHORT cb;
- extern char szT[];
-
- if (HIUSHORT(latom) >= cAtbls) {
- AssertF(FALSE, "Invalid latom");
- psz[0] = '\0';
- return(0);
- }
-
- AssertF(latom != 0, "QuerylatomName - 0 latom");
- SemCheckIn();
- cb = WinQueryAtomLength(aAtbls[HIUSHORT(latom)], LOUSHORT(latom));
- if (cb > MAX_LATOMSTRSIZE) {
- if (!WinQueryAtomName(aAtbls[HIUSHORT(latom)], LOUSHORT(latom), szT,
- MAX_LATOMSTRSIZE + ENCODEBYTES + 1)) {
- AssertF(FALSE, "QuerylatomName - length but no name");
- return(0);
- }
- CopyBlock(szT + ENCODEBYTES, psz, min(MAX_LATOMSTRSIZE, cchMax));
- latom = Decode((PBYTE)szT);
- cb = MAX_LATOMSTRSIZE + QuerylatomName(latom, psz + MAX_LATOMSTRSIZE,
- cchMax > MAX_LATOMSTRSIZE ? cchMax - MAX_LATOMSTRSIZE : 0);
-
- } else {
- WinQueryAtomName(aAtbls[HIUSHORT(latom)], LOUSHORT(latom), psz, cchMa
- }
- psz[cchMax - 1] = '\0'; /* add NULL terminator */
- return(min(cb, cchMax - 1));
- }
-
-
-
- /***************************** Private Function ****************************\
- * This uses globals szT, aAtbls, cAtbls, and iAtblCurrent to add or
- * find the latom for psz depending on fAdd.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- LATOM FindAddlatom(psz, fAdd)
- PSZ psz;
- BOOL fAdd;
- {
- LATOM latom;
-
- AssertF(psz != NULL, "FindAddlatom - NULL psz");
- AssertF(*psz != '\0', "FindAddlatom - NULL psz string");
- SemCheckIn();
- if (lstrlen(psz) > MAX_LATOMSTRSIZE) {
- latom = FindAddlatom(psz + MAX_LATOMSTRSIZE, fAdd);
- CopyBlock((PBYTE)psz, Encode((ULONG)latom, szT),
- (ULONG)MAX_LATOMSTRSIZE - ENCODEBYTES + 1);
- szT[MAX_LATOMSTRSIZE + ENCODEBYTES] = '\0';
- latom = FindAddlatomHelper(szT, fAdd);
- return(latom);
- } else {
- return(FindAddlatomHelper(psz, fAdd));
- }
- }
-
-
-
-
- LATOM FindAddlatomHelper(psz, fAdd)
- PSZ psz;
- BOOL fAdd;
- {
- int i;
- ATOM atom;
- ATOM (APIENTRY *lpfn)(HATOMTBL, PSZ);
-
- SemCheckIn();
- if (fAdd) {
- AssertF(++cAtoms, "Possible atom count overflow");
- lpfn = WinAddAtom;
- } else
- lpfn = WinFindAtom;
-
- if (!(atom = (*lpfn)(aAtbls[i = iAtblCurrent], psz))) {
- /*
- * Must be full/not found, try all the existing tables
- */
- for (i = 0; i < cAtbls; i++) {
- if (i != iAtblCurrent) {
- if (atom = (*lpfn)(aAtbls[i], psz)) {
- if (fAdd)
- iAtblCurrent = i;
- break;
- }
- }
- }
-
- if (!atom) {
- if (fAdd) {
- /*
- * they're all full, make another table.
- */
- if (!AddAtomTable(FALSE)) {
- return(0L);
- }
- if (!(atom = (*lpfn)(aAtbls[iAtblCurrent], psz))) {
- return(0L);
- }
- } else {
- return(0L);
- }
- }
- }
- return((LATOM)MAKEP(i, atom));
- }
-
-
-
-
-
- BOOL InclatomCount(latom)
- LATOM latom;
- {
- AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");
- AssertF(latom != 0, "InclatomCount - 0 latom");
- SemCheckIn();
- AssertF(++cAtoms, "Possible atom count overflow");
- return(WinAddAtom(aAtbls[HIUSHORT(latom)], MAKEP(0XFFFF, LOUSHORT(latom))
- }
-
-
-
- BOOL Freelatom(latom)
- LATOM latom;
- {
- AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");
- AssertF(latom != 0, "Freelatom - 0 latom");
- AssertF(WinQueryAtomUsage(aAtbls[HIUSHORT(latom)], LOUSHORT(latom)),
- "Freelatom - Freeing Non-existing atom");
- SemCheckIn();
-
- if (WinDeleteAtom(aAtbls[HIUSHORT(latom)], LOUSHORT(latom))) {
- AssertF(FALSE, "Freelatom - WinDeleteAtom failed");
- return(FALSE);
- }
- AssertF(--cAtoms >= 0, "Freelatom - negative atom count");
- return(TRUE);
- }
-
-
-
-
- #ifdef DEBUG
- BASEVAL '0' /* more readable for debugging */
- #else
- BASEVAL 1 /* less likely to conflict with a string */
- #endif
-
- /***************************** Private Function ****************************\
- * Converts an latom into a ENCODEBYTES character string apropriate for
- * atomization. (NULL terminator must be added)
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- PBYTE Encode(latom, pb)
- ULONG latom;
- PBYTE pb;
- {
- int i;
-
-
- AssertF(HIUSHORT(latom) < cAtbls, "Invalid latom");
- for (i = 0; i < ENCODEBYTES; i++) {
- *pb++ = ((BYTE)latom & 0x0F) + BASEVAL;
- latom >>= 4;
- }
- return(pb);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This takes a pointer to a buffer of 8 bytes which is a coded LATOM and
- * returns the LATOM.
- *
- * History:
- * Created 9/12/89 Sanfords
- \***************************************************************************/
- LATOM Decode(pb)
- PBYTE pb;
- {
- ULONG ul = 0;
- int i;
-
- for (i = ENCODEBYTES - 1; i >= 0; i--) {
- ul <<= 4;
- ul += (ULONG)(pb[i] - BASEVAL);
- }
- return((LATOM)ul);
- }
-
-
- /*
- * This routine extracts the hszItem out of an existing hData handle.
- * local conversations can use the hsz directly out of the handle while
- * non-dll conversations will have to generate the hsz from the string.
- */
- HSZ GetHszItem(
- PMYDDES pmyddes,
- PCONVCONTEXT pCC,
- BOOL fAdd)
- {
- if (CheckSel(SELECTOROF(pmyddes)) >= sizeof(MYDDES) &&
- pmyddes->magic == MYDDESMAGIC) {
- if (fAdd)
- IncHszCount(pmyddes->hszItem);
- return(pmyddes->hszItem);
- } else {
- return(GetHsz(DDES_PSZITEMNAME(pmyddes), pCC->idCountry,
- pCC->usCodepage, fAdd));
- }
- }
-
-
- DMGMON.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGMON.C
-
- /****************************** Module Header ******************************\
- * Module Name: DMGMON.C
- *
- * This module contains functions used for DDE monitor control.
- *
- * Created: 8/2/88 sanfords
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
- #include "ddemlp.h"
- #define MSGF_DDEPOSTMSG 3
-
- #define freeMonStr(psz) MyFreeMem(hheapDmg, (NPBYTE)(USHORT)psz, MAX_MONITORS
-
-
- BOOL EXPENTRY DdeSendHookProc(hab, psmh, fInterTask)
- HAB hab;
- PSMHSTRUCT psmh;
- BOOL fInterTask;
- {
- PSZ psz;
- PSZ pszSave;
- PSZ pszLast;
-
- UNUSED hab;
- UNUSED fInterTask;
-
- if (psmh->msg == WM_DDE_INITIATE || psmh->msg == WM_DDE_INITIATEACK) {
- if (allocMonStr(&pszSave, &pszLast)) {
- psz = timestamp(pszSave, pszLast);
- psz = lstrcat(psz, " ", pszLast);
- psz = ltoa((ULONG)psmh->mp1, psz, pszLast);
- psz = lstrcat(psz, " -> ", pszLast);
- psz = ltoa((ULONG)psmh->hwnd, psz, pszLast);
- psz = lstrcat(psz, "\n\r", pszLast);
- psz = ddeMsgToPsz(psmh->msg, psz, pszLast);
- psz = pddesToPsz(psmh->msg, (PDDESTRUCT)psmh->mp2, psz, pszLast);
- psz = lstrcat(psz, ")\n\r", pszLast);
- MonitorBroadcast(pszSave);
- freeMonStr(pszSave);
- }
- }
- return(FALSE);
- }
-
-
-
-
- BOOL EXPENTRY DdePostHookProc(hab, pqmsg, fs)
- HAB hab;
- PQMSG pqmsg;
- USHORT fs;
- {
- PSZ psz;
- PSZ pszSave;
- PSZ pszLast;
-
- UNUSED hab;
-
- if (fs && pqmsg->msg >= WM_DDE_FIRST && pqmsg->msg <= WM_DDE_LAST) {
- pszLast = psz + MAX_MONITORSTR;
- if (allocMonStr(&pszSave, &pszLast)) {
- psz = timestamp(pszSave, pszLast);
- psz = lstrcat(psz, " ", pszLast);
- psz = ltoa((ULONG)pqmsg->mp1, psz, pszLast);
- psz = lstrcat(psz, " -> ", pszLast);
- psz = ltoa((ULONG)pqmsg->hwnd, psz, pszLast);
- psz = lstrcat(psz, "\n\r", pszLast);
- psz = ddeMsgToPsz(pqmsg->msg, psz, pszLast);
- psz = pddesToPsz(pqmsg->msg, (PDDESTRUCT)pqmsg->mp2, psz, pszLast
- psz = lstrcat(psz, ")\n\r", pszLast);
- MonitorBroadcast(pszSave);
- freeMonStr(pszSave);
- }
- }
- return(FALSE);
- }
-
- /*
- * This guy sends a UM_MONITOR to all the monitor windows (up to MAX_MONITOR)
- * The cheap restriction is due to needing to not be in the semaphore
- * while the monitor is in control yet needing to keep access to pai in
- * the semaphore.
- */
- void MonitorBroadcast(psz)
- PSZ psz;
- {
- HWND hwnd[MAX_MONITORS];
- PAPPINFO pai;
- register USHORT i = 0;
-
- SemCheckOut();
- SemEnter();
- pai = pAppInfoList;
- while (pai && i < cMonitor && i < MAX_MONITORS) {
- if (pai->hwndMonitor) {
- hwnd[i] = pai->hwndMonitor;
- i++;
- }
- pai = pai->next;
- }
- SemLeave();
-
- for (i = 0; i < cMonitor; i++)
- WinSendMsg(hwnd[i], UM_MONITOR, (MPARAM)psz, 0L);
- }
-
-
- /*
- * We need to allocate the string buffer so that recursive calls will work.
- * We also need to do this because the DLL DS is shared between all potential
- * monitor processes.
- *
- * This also initializes the psz for us with a null terminator and checks
- * cMonitor for us. If this fails, no monitor action is done.
- *
- * ppsz will contain a pointer to the begining of the allocated buffer.
- * ppszLast will contain a pointer to the end of the allocated buffer.
- */
- BOOL allocMonStr(ppsz, ppszLast)
- PSZ far *ppsz;
- PSZ far *ppszLast;
- {
- SemEnter();
- if (cMonitor == 0 ||
- ((*ppsz = FarAllocMem(hheapDmg, MAX_MONITORSTR + 1)) == NULL)) {
- SemLeave();
- return(FALSE);
- }
- *ppszLast = *ppsz + MAX_MONITORSTR;
- **ppsz = '\0';
- SemLeave();
- return(TRUE);
- }
-
-
-
- MRESULT EXPENTRY MonitorWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- register MPARAM mp1;
- MPARAM mp2;
- {
- PAPPINFO pai;
- HDMGDATA hDmgData;
-
- pai = GetCurrentAppInfo(FALSE);
-
- switch (msg) {
- case WM_CREATE:
- mp1 = (PSZ)"\n\rMonitor Created\n\r\n\r";
- goto MonOut;
- break;
-
- case WM_DESTROY:
- mp1 = (PSZ)"\n\r\n\rMonitor Destroyed\n\r";
- /* fall through */
-
- case UM_MONITOR:
- /*
- * mp1 = psz to print
- */
- MonOut:
- hDmgData = DdePutData((PSZ)mp1, (ULONG)(lstrlen(mp1) + 1),
- 0L, (HSZ)0L, DDEFMT_TEXT, 0);
- pai->cInCallback++;
- DoCallback(pai, 0, 0, 0, DDEFMT_TEXT, XTYP_MONITOR, hDmgData);
- if (pai->cInCallback > 0) /* test incase exitlist processing messed
- pai->cInCallback--;
- break;
-
- default:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
-
- return(0);
- }
-
-
-
-
- DMGQ.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGQ.C
-
- /****************************** Module Header ******************************\
- * Module Name: DMGQ.C
- *
- * DDE Manager queue control functions.
- *
- * Created: 9/1/89 Sanford Staab
- *
- * This is a general queue manager - yes another one!
- * Queues are each allocated within their own segment and have a
- * QST structure associated with that heap. Each queue item
- * is allocated within the heap segment. The offset of the items
- * address combined with an instance count is used as the item ID.
- * This is both unique and allows for instant location of an item.
- * New items are added to the head of the queue which is a doubly linked
- * list. The next links point to more recent entries, the prev pointers
- * to older entries. The next of the head is the tail. The prev of the
- * tail is the head. All pointers are far.
- * Queue Data may be of any structure type that begins identical to
- * a QUEUEITEM structure. Functions that require an cbItem perameter
- * should be given the size of the specialized queue item structure.
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
-
- #include "ddemlp.h"
-
-
- /***************************** Private Function ****************************\
- *
- * Creates a Queue for items of cbItem.
- * Returns NULL on error.
- *
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- PQST CreateQ(cbItem)
- USHORT cbItem;
- {
- QST cq;
- PQST pQ;
-
- cq.cItems = 0;
- cq.instLast = 0;
- cq.cbItem = cbItem;
- cq.pqiHead = NULL;
- if (!(cq.hheap = MyCreateHeap(0, sizeof(QST) + cbItem << 3,
- cbItem << 3, cbItem, cbItem, HEAPFLAGS)))
- return(NULL);
- if (!(pQ = (PQST)FarAllocMem(cq.hheap, sizeof(QST)))) {
- MyDestroyHeap(cq.hheap);
- return(0);
- }
- *pQ = cq;
- return(pQ);
- }
-
-
-
- /***************************** Private Function ****************************\
- *
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- BOOL DestroyQ(pQ)
- PQST pQ;
- {
- if (pQ)
- MyDestroyHeap(pQ->hheap);
- return(TRUE);
- }
-
-
-
- /***************************** Private Function ****************************\
- *
- * returns a long pointer to the queue item data created. The new item
- * is added to the head of the queue. The queue's cbItem specified at
- * creation is used for allocation.
- *
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- PQUEUEITEM Addqi(pQ)
- PQST pQ;
- {
- PQUEUEITEM pqi;
-
- if ((pqi = (PQUEUEITEM)FarAllocMem(pQ->hheap, pQ->cbItem)) == NULL) {
- if (pQ->cItems == 0)
- return(0);
- /*
- * remove the oldest item to make room for the new.
- */
- pqi = pQ->pqiHead->next;
- SemEnter();
- pqi->prev->next = pqi->next;
- pqi->next->prev = pqi->prev;
- SemLeave();
- }
-
- SemEnter();
- if (pQ->cItems == 0) {
- pQ->pqiHead = pqi->prev = pqi->next = pqi;
- } else {
- pqi->prev = pQ->pqiHead;
- pqi->next = pQ->pqiHead->next;
- pQ->pqiHead->next->prev = pqi;
- pQ->pqiHead->next = pqi;
- pQ->pqiHead = pqi;
- }
- SemLeave();
- pQ->cItems++;
- pqi->inst = ++pQ->instLast;
- return(pqi);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- *
- * The id given is an external LONG id, not an item instance number.
- * If id is QID_NEWEST, the head item is deleted.
- * If id is QID_OLDEST, the tail item is deleted.
- *
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- void Deleteqi(pQ, id)
- PQST pQ;
- ULONG id;
- {
- PQUEUEITEM pqi;
-
- SemEnter();
- pqi = Findqi(pQ, id);
- if (pqi == NULL) {
- SemLeave();
- return;
- }
- pqi->prev->next = pqi->next;
- pqi->next->prev = pqi->prev;
- if (pqi == pQ->pqiHead)
- pQ->pqiHead = pqi->prev;
- if (!(--pQ->cItems))
- pQ->pqiHead = NULL;
- FarFreeMem(pQ->hheap, pqi, pQ->cbItem);
- SemLeave();
- }
-
-
-
-
-
-
- /***************************** Private Function ****************************\
- *
- * The id given is an external LONG id, not an item instance number.
- *
- * if id == QID_NEWEST, returns the head queue data item.
- * if id == QID_OLDEST, returns the tail queue data item.
- * if the id is not found or the queue is empty, NULL is returned.
- * if found, pqi is returned.
- *
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- PQUEUEITEM Findqi(pQ, id)
- PQST pQ;
- ULONG id;
- {
- PQUEUEITEM pqi;
-
- SemCheckIn();
- if (pQ == NULL || pQ->pqiHead == NULL)
- return(NULL);
-
- if (id == QID_OLDEST)
- return(pQ->pqiHead->next);
-
- if (id == QID_NEWEST)
- return(pQ->pqiHead);
-
- if (id) {
- pqi = PFROMID(pQ, id);
- if (pqi->inst == HIUSHORT(id)) {
- return(pqi);
- }
- return(NULL);
- }
- }
-
-
- DMGSTR.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGSTR.C
-
- /****************************** Module Header ******************************\
- * Module Name: DMGSTR.C
- *
- * DDE manager string handling routines
- *
- * Created: 1/31/88 Sanford Staab
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
- #include "ddemlp.h"
- #include "ctype.h"
-
-
-
- /***************************** Private Function ****************************\
- *
- * returns string length not counting null terminator.
- *
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- int lstrlen(psz)
- PSZ psz;
- {
- int c = 0;
-
- while (*psz != 0) {
- psz++;
- c++;
- }
- return(c);
- }
-
- /***************************** Public Function ****************************\
- * Concatonates psz1 and psz2 into psz1.
- * returns psz pointing to end of concatonated string.
- * pszLast marks point at which copying must stop. This makes this operation
- * safe for limited buffer sizes.
- *
- * History: 1/1/89 created sanfords
- \***************************************************************************/
- PSZ lstrcat(psz1, psz2, pszLast)
- PSZ psz1, psz2, pszLast;
- {
- psz1 += lstrlen(psz1);
- while (*psz2 != '\0' && psz1 < pszLast) {
- *psz1++ = *psz2++;
- }
- *psz1 = '\0';
- return(psz1);
- }
-
- /***************************** Private Function ****************************\
- * DESCRIPTION: ASCII dependent converter of DDE structure data to a string.
- * returns psz pointing to end of copy.
- * During monitoring we allocate segments as gettable so we can monitor them.
- *
- * History: Created 1/31/89 sanfords
- \***************************************************************************/
- PSZ pddesToPsz(msg, pddes, psz, pszLast)
- USHORT msg;
- PDDESTRUCT pddes;
- PSZ psz;
- PSZ pszLast;
- {
- USHORT cb;
- PBYTE pData;
- #define pDdeInit ((PDDEINIT)pddes)
-
- *psz = '\0';
- switch (msg) {
- case WM_DDE_REQUEST:
- case WM_DDE_ACK:
- case WM_DDE_DATA:
- case WM_DDE_ADVISE:
- case WM_DDE_UNADVISE:
- case WM_DDE_POKE:
- case WM_DDE_EXECUTE:
- psz = lstrcat(psz, "S:", pszLast);
- psz = Status(pddes->fsStatus, psz, pszLast);
- psz = lstrcat(psz, " F:", pszLast);
- psz = Format(pddes->usFormat, psz, pszLast);
- psz = lstrcat(psz, " I:", pszLast);
- psz = lstrcat(psz, DDES_PSZITEMNAME(pddes), pszLast);
- if (pddes->cbData)
- psz = lstrcat(psz, "\n\r Data:", pszLast);
- pData = DDES_PABDATA(pddes);
-
- for (cb = 0; (ULONG)cb < pddes->cbData && psz < pszLast; cb++, pData+
- /*
- * new line every 64 chars
- */
- if ((cb & 0x3F) == 0) {
- *psz = '\0';
- psz = lstrcat(psz, "\n\r ", pszLast);
- }
- if (*pData > 0x20)
- *psz = *pData;
- else
- *psz = '.';
-
- *psz++ = *psz & 0x7f;
- }
- CopyBlock("\n\r", pszLast - 3, 3L);
- break;
-
- case WM_DDE_INITIATEACK:
- case WM_DDE_INITIATE:
- if (CheckSel(SELECTOROF(pDdeInit))) {
- psz = lstrcat(psz, "A:", pszLast);
- psz = lstrcat(psz, pDdeInit->pszAppName, pszLast);
- psz = lstrcat(psz, " T:", pszLast);
- psz = lstrcat(psz, pDdeInit->pszTopic, pszLast);
- }
- break;
-
- case WM_DDE_TERMINATE:
- break;
- }
- *psz = '\0';
- return(psz);
-
- #undef pDdeInit
-
- }
-
-
- PSZ Status(fs, psz, pszLast)
- USHORT fs;
- PSZ psz;
- PSZ pszLast;
- {
- if (fs & DDE_FACK) {
- psz = lstrcat(psz, "ACK ", pszLast);
- }
- if (fs & DDE_FBUSY) {
- psz = lstrcat(psz, "BUSY ", pszLast);
- }
- if (fs & DDE_FNODATA) {
- psz = lstrcat(psz, "NODATA ", pszLast);
- }
- if (fs & DDE_FACKREQ) {
- psz = lstrcat(psz, "ACKREQ ", pszLast);
- }
- if (fs & DDE_FRESPONSE) {
- psz = lstrcat(psz, "RESPONSE ", pszLast);
- }
- if (fs & DDE_NOTPROCESSED) {
- psz = lstrcat(psz, "NOTPROCESSED ", pszLast);
- }
- if (fs & DDE_FAPPSTATUS) {
- psz = lstrcat(psz, "APPSTAT=", pszLast);
- psz = itoa(fs & DDE_FAPPSTATUS, psz, pszLast);
- *psz++ = ' ';
- *psz++ = '\0';
- }
- if (fs & DDE_FRESERVED) {
- psz = lstrcat(psz, "RESERVED=", pszLast);
- psz = itoa(fs & DDE_FRESERVED, psz, pszLast);
- }
- return(psz);
- }
-
-
- PSZ Format(fmt, psz, pszLast)
- USHORT fmt;
- PSZ psz;
- PSZ pszLast;
- {
- if (fmt > 0xbfff) {
- *psz++ = '"';
- psz += WinQueryAtomName(WinQuerySystemAtomTable(), fmt, psz, pszLast
- *psz++ = '"';
- *psz = '\0';
- } else if (fmt == DDEFMT_TEXT) {
- psz = lstrcat(psz, "TEXT", pszLast);
- } else {
- psz = itoa(fmt, psz, pszLast);
- }
- return(psz);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * DESCRIPTION: puts an apropriate string for a DDE message into psz. pszLast
- * specifies the last spot to copy. Returns a psz pointing to the end of
- * the copyed data.
- *
- * History: Created 1/31/89 sanfords
- \***************************************************************************/
- PSZ ddeMsgToPsz(msg, psz, pszLast)
- USHORT msg;
- PSZ psz;
- PSZ pszLast;
- {
- psz = lstrcat(psz, " ", pszLast);
- if (msg < WM_DDE_FIRST || msg > WM_DDE_LAST) {
- psz = itoa(msg, psz, pszLast);
- } else {
- WinLoadString(DMGHAB, hmodDmg, msg, pszLast - psz + 1, psz);
- psz += lstrlen(psz);
- }
- return(lstrcat(psz, "(", pszLast));
- }
-
- /***************************** Private Function ****************************\
- * DESCRIPTION:
- * fills psz with a hex string "0xdddd" and returns psz pointing to the 0
- * terminator at the end. copying will never go beyond pszLast.
- *
- * History: Created 1/31/89 sanfords
- \***************************************************************************/
- PSZ itoa(us, psz, pszLast)
- USHORT us;
- PSZ psz;
- PSZ pszLast;
- {
- if (psz > pszLast - 7)
- return(psz);
- *psz++ = '0';
- *psz++ = 'x';
- return(stoa(psz, us));
- }
-
- /***************************** Private Function ****************************\
- * DESCRIPTION:
- * fills psz with a hex string "0xdddddddd" and returns psz pointing to the
- * terminator at the end. copying will never go beyond pszLast.
- *
- * History: Created 1/31/89 sanfords
- \***************************************************************************/
- PSZ ltoa(ul, psz, pszLast)
- ULONG ul;
- PSZ psz;
- PSZ pszLast;
- {
- if (psz > pszLast - 11)
- return(psz);
- *psz++ = '0';
- *psz++ = 'x';
- psz = stoa(psz, HIUSHORT(ul));
- return(stoa(psz, LOUSHORT(ul)));
- }
-
-
- /***************************** Private Function ****************************\
- * DESCRIPTION:
- * fills psz with a hex string "dddd" and returns psz pointing to the 0
- * terminator at the end.
- *
- * History: Created 1/31/89 sanfords
- \***************************************************************************/
- PSZ stoa(psz, us)
- PSZ psz;
- USHORT us;
- {
- static char dtoa[] = "0123456789abcdef";
-
- *psz++ = dtoa[(us & 0xf000) >> 12];
- *psz++ = dtoa[(us & 0xf00) >> 8];
- *psz++ = dtoa[(us & 0xf0) >> 4];
- *psz++ = dtoa[us & 0xf];
- *psz = '\0';
- return(psz);
- }
-
-
- /*
- * Decimal to ascii
- */
- PSZ dtoa(psz, us, fRecurse)
- PSZ psz;
- USHORT us;
- BOOL fRecurse;
- {
- if (us > 9) {
- psz = dtoa(psz, us / 10, TRUE);
- *psz++ = (UCHAR)(us % 10) + '0';
- } else if (us > 0)
- *psz++ = (UCHAR)us + '0';
- else if (!fRecurse)
- *psz++ = '0';
- *psz = '\000';
- return(psz);
- }
-
-
- /***************************** Private Function ****************************\
- * DESCRIPTION:
- * fills psz with a hex time stamp and returns psz pointing to the 0
- * terminator at the end.
- *
- * History: Created 5/9/89 sanfords
- \***************************************************************************/
- PSZ timestamp(psz, pszLast)
- PSZ psz;
- PSZ pszLast;
- {
- DATETIME dt;
- static USHORT prevTime = 0;
- USHORT Time;
-
- DosGetDateTime(&dt);
- Time = MAKESHORT(dt.hundredths, dt.seconds);
- psz = lstrcat(psz, "----------- dTime=", pszLast);
- psz = itoa(Time - prevTime, psz, pszLast);
- psz = lstrcat(psz, " ", pszLast);
- prevTime = Time;
- return(psz + lstrlen(psz));
- }
-
-
- DMGSTRT.ASM
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGSTRT.ASM
-
- ; DDE manager library initialization routine
-
- .286p
-
- ?WIN=1 ; Use Windows prolog/epilog
- ?PLM=1 ; Use PLM calling convention
- DOS5=1
- .xlist
- include cmacros.inc
- .list
-
- sBegin DATA
-
- assumes DS,DATA
-
- externW hmodDmg
- externW usHugeShift
-
- sEnd DATA
-
- sBegin CODE
- assumes cs,CODE
- assumes ds,DATA
-
- externNP SemInit
-
- ;
- ; Registers set up by DosLoadModule...
- ;
- ; SI = heap size
- ; DI = module ID
- ; DS = library's automatic data segment
- ;
- cProc LoadProc,<FAR,PUBLIC>
- cBegin LoadProc
- ; int 3
- mov hmodDmg, di
- call SemInit
- cEnd LoadProc
-
- ;
- ; FillBlock(PBYTE pDst, USHORT cb, BYTE b)
- ;
- cProc FillBlock,<PUBLIC, NEAR>,<DI, DS>
- ParmD pDst
- ParmW cb
- ParmW b
- cBegin
- les di,pDst
- mov cx,cb
- mov ax,b
- cld
- rep stosb
- cEnd
-
- ;
- ; CopyBlock(pbSrc, pbDst, cb)
- ;
- LabelNP <PUBLIC, CopyBlock>
- mov bx,sp
- push si
- push di
- mov dx,ds ; preserve DS
-
- mov cx,ss:[bx+2]
- jcxz copydone ; all done if crc == 0
- les di,ss:[bx+2+2]
- lds si,ss:[bx+2+2+4]
- cmp si,di
- jae copyok
- mov ax,cx
- dec ax
- add si,ax
- add di,ax
- std
- rep movsb
- cld
- jmp short copydone
- copyok:
- cld
- rep movsb
- copydone:
-
- mov ds,dx
- pop di
- pop si
- ret 10
-
-
- cProc HugeOffset,<NEAR, PUBLIC>
- parmD pSrc
- parmD cb
- cBegin
- mov dx, SEG_cb
- mov ax, OFF_pSrc
- add ax, OFF_cb
- adc dx, 0
- mov cx, usHugeShift
- shl dx, cl
- add dx, SEG_pSrc
- cEnd
-
-
- LabelFP <PUBLIC, DdeDebugBreak>
- int 3
- retf 0
-
- ;
- ; Returns segment size or 0 on error.
- ;
- LabelNP <PUBLIC, CheckSel>
- ; parmW Selector ; selector to validate
- cBegin nogen
- mov bx,sp ; BX = selector to validate
- mov bx,ss:[bx].2
- lar ax,bx ; See if valid selector
- jnz invalid_selector
-
- lsl ax,bx
- or ax,ax ; zero sized?
- jnz valid_selector ; nope, ok.
-
- invalid_selector:
- xor ax,ax ; Return zero just to be nice
-
- valid_selector:
- ret 2
-
- cEnd nogen
-
- sEnd CODE
- end LoadProc
-
-
- DMGWNDP.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\DDEML\DMGWNDP.C
-
- /****************************** Module Header ******************************\
- *
- * Module Name: DMGWNDP.C
- *
- * This module contains all the window procs for the DDE manager.
- *
- * Created: 12/23/88 sanfords
- *
- * Copyright (c) 1988, 1989 Microsoft Corporation
- \***************************************************************************/
-
- #include "ddemlp.h"
-
-
- ULONG defid = QID_SYNC;
- XFERINFO defXferInfo = {
- &defid,
- 1L,
- XTYP_INIT,
- DDEFMT_TEXT,
- 0L,
- 0L,
- 0L,
- NULL
- };
-
- void InitAck(HWND hwnd, PCLIENTINFO pci, HWND hwndServer, PDDEINIT pddei);
- MRESULT ClientXferReq(PXFERINFO pXferInfo, PCLIENTINFO pci, HWND hwnd);
- USHORT SendClientReq(PXADATA pXad, HWND hwndServer, HWND hwnd, PAPPINFO pai);
- void DoClientDDEmsg(PCLIENTINFO pci, HWND hwnd, USHORT msg, HWND hwndFrom,
- PDDESTRUCT pddes);
- BOOL fExpectedMsg(PXADATA pXad, PDDESTRUCT pddes, USHORT msg, PCLIENTINFO pci
- BOOL AdvanceXaction(HWND hwnd, PCLIENTINFO pci, PXADATA pXad,
- PDDESTRUCT pddes, USHORT msg, PUSHORT pErr);
- MRESULT ClientXferRespond(PCLIENTINFO pci, PXADATA pXad, PUSHORT pErr);
- void FrameInitConv(HWND hwndClient, PDDEINIT pddei);
-
- /*
- * ----------------CLIENT SECTION------------------
- *
- * Each client conversation has associated with it a window and a queue.
- * A conversation has one synchronous transaction and may have many
- * asynchronous transactions. A transaction is differientiated by its
- * state and other pertinant data. A transaction may be synchronous,
- * asynchronous, (initiated by DdeClientXfer()), or it may be external,
- * (initiated by an advise loop.)
- *
- * A transaction is active if it is in the middle of tranfer, otherwise
- * it is shutdown. A shutdown transaction is either successful or
- * failed. When an asynchronous transaction shuts down, the client
- * is notified via the callback function. (XTYP_XFERCOMPLETE)
- *
- * The synchronous transaction, when active, is in a timeout loop which
- * can shut-down the transaction at the end of a predefined time period.
- * Shutdown synchronous transactions imediately transfer their information
- * to the client application by returning to DdeClientXfer().
- *
- * asynchronous transactions remain in the client queue until removed
- * by the client application via DdeCheckQueue().
- *
- * external transactions take place when the client is in an advise
- * data loop. These transactions pass through the callback function to
- * the client to be accepted.(XTYP_ADVDATA)
- */
-
-
- /***************************** Private Function ****************************\
- * MRESULT EXPENTRY ClientWndProc(hwnd, msg, mp1, mp2);
- *
- * This window controls a single DDE conversation from the CLIENT side.
- * If closed, it will automaticly abort any conversationn in progress.
- * It maintains an internal list of any extra WM_DDEINITIATEACK messages
- * it receives so that it can be queried later about this information.
- * Any extra WM_DDEINITIATEACK messages comming in will be immediately
- * terminated.
- * It also maintains an internal list of all items which currently are
- * in active ADVISE loops.
- *
- * History:
- * Created 12/16/88 Sanfords
- \***************************************************************************/
- MRESULT EXPENTRY ClientWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- register PCLIENTINFO pci;
- PAPPINFO pai;
- MRESULT mrData;
- PDDESTRUCT pddes;
-
- pci = (PCLIENTINFO)WinQueryWindowULong(hwnd, QWL_USER);
-
- switch (msg) {
- case WM_CREATE:
- /*
- * allocate and initialize the client window info.
- */
- pai = GetCurrentAppInfo(FALSE);
- SemEnter();
- pci = (PCLIENTINFO)FarAllocMem(pai->hheapApp, sizeof(CLIENTINFO));
- SemLeave();
- if (pci == NULL) {
- pai->LastError = DMGERR_MEMORY_ERROR;
- return(1); /* aboart creation - low memory */
- }
- WinSetWindowULong(hwnd, QWL_USER, (ULONG)pci);
- pci->ci.pai = pai;
- pci->ci.xad.state = CONVST_NULL;
- pci->ci.xad.pXferInfo = &defXferInfo;
- pci->ci.fs = 0;
- pci->ci.hwndPartner = NULL;
- pci->ci.hszServerApp = NULL;
- pci->ci.hszTopic = NULL;
- pci->pQ = NULL; /* don't create until we need one */
- if (!(pci->ci.pAdviseList = CreateLst(pai->hheapApp, sizeof(ADVLI))))
- FarFreeMem(pai->hheapApp, (PBYTE)pci, sizeof(CLIENTINFO));
- pai->LastError = DMGERR_MEMORY_ERROR;
- return(1); /* aboart creation - low memory */
- }
- break;
-
- case UMCL_INITIATE:
- if (pci->ci.xad.state == CONVST_NULL) {
- return(ClientInitiate(hwnd, (PINITINFO)mp1, pci));
- }
- break;
-
- case WM_DDE_INITIATEACK:
- InitAck(hwnd, pci, mp1, mp2);
- DosFreeSeg(SELECTOROF(mp2));
- return(1);
- break;
-
- case WM_DESTROY:
- SemCheckOut();
- if (pci->ci.fs & ST_CONNECTED) {
- /*
- * stop any advises in progress
- */
- if (pci->ci.fs & ST_ADVISE) {
- pddes = AllocDDESel(0, 0, 0, 0L, NULL);
- MyDdePostMsg(pci->ci.hwndPartner, hwnd, WM_DDE_UNADVISE,
- (PMYDDES)pddes, pci->ci.pai, MDPM_FREEHDATA);
- }
- WinSendMsg(hwnd, UMCL_TERMINATE, 0L, 0L);
- /*
- * decrement the use counts on hszs we are done with.
- */
- FreeHsz(pci->ci.hszServerApp);
- FreeHsz(pci->ci.hszTopic);
- }
-
- DestroyLst(pci->ci.pAdviseList);
-
- SemEnter();
- DestroyQ(pci->pQ);
- FarFreeMem(pci->ci.pai->hheapApp, (PBYTE)pci, sizeof(CLIENTINFO));
- SemLeave();
- break;
-
- case UMCL_TERMINATE:
- /*
- * terminates any conversation in progress
- */
- if (pci->ci.fs & ST_CONNECTED) {
- pci->ci.fs = pci->ci.fs & ~ST_CONNECTED;
- pci->ci.xad.state = CONVST_TERMINATED;
- if (WinIsWindow(DMGHAB, pci->ci.hwndPartner))
- WinDdePostMsg(pci->ci.hwndPartner, hwnd, WM_DDE_TERMINATE, 0L
- }
- break;
-
- case UMCL_XFER:
- if (!(pci->ci.fs & ST_CONNECTED)) {
- pci->ci.pai->LastError = DMGERR_NO_CONV_ESTABLISHED;
- return(0);
- }
- return(ClientXferReq((PXFERINFO)mp1, pci, hwnd));
- break;
-
- case WM_DDE_DATA:
- case WM_DDE_ACK:
- DoClientDDEmsg(pci, hwnd, msg, (HWND)mp1, (PDDESTRUCT)mp2);
- break;
-
- case WM_DDE_TERMINATE:
- SemCheckOut();
- /*
- * only respond if this is for us.
- */
- if ((HWND)mp1 != pci->ci.hwndPartner) {
- DosFreeSeg(SELECTOROF(mp2));
- break;
- }
- WinSendMsg(hwnd, UMCL_TERMINATE, 0L, 0L);
- DosFreeSeg(SELECTOROF(mp2));
- break;
-
- case UM_QUERY:
- /*
- * LOUSHORT(mp1) = info index.
- * mp2 = pData. If pData==0, return data else copy into pData.
- */
- switch (LOUSHORT(mp1)) {
- case Q_STATUS:
- mrData = (MRESULT)pci->ci.fs;
- break;
-
- case Q_CLIENT:
- mrData = TRUE;
- break;
-
- case Q_APPINFO:
- mrData = pci->ci.pai;
- break;
-
- case Q_APPNAME:
- mrData = *(PHSZ)PTOPPILEITEM(pci->ci.pai->pAppNamePile);
- break;
-
- case Q_ALL:
- mrData = (MRESULT)(CLIENTINFO FAR *)pci;
- break;
- }
- if (mp2 == 0)
- return(mrData);
- else
- *(MRESULT FAR *)mp2 = mrData;
- return(1);
- break;
-
- default:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0);
- }
-
-
-
- /*
- * Client response to a WM_DDE_INITIATEACK message when expected.
- */
- void InitAck(hwnd, pci, hwndServer, pddei)
- HWND hwnd;
- PCLIENTINFO pci;
- HWND hwndServer;
- PDDEINIT pddei;
- {
- SemCheckOut();
-
- if (pci->ci.fs & ST_CONNECTED) {
- /*
- * extra server - spawn another client window. (we assume we
- * will only get extras if enumerating.)
- */
- AssertF(WinQueryWindow(hwnd, QW_PARENT, FALSE) != pci->ci.pai->hwndDm
- "Improper client spawn")
- if (hwndServer != pci->ci.hwndPartner) {
- WinSendMsg(hwndServer, WM_DDE_TERMINATE, hwnd, 0L);
- GetDDEClientWindow(WinQueryWindow(hwnd, QW_PARENT, FALSE),
- hwndServer, hwndServer, pci->ci.hszServerApp,
- pci->ci.hszTopic, &pci->ci.cc);
- }
- return;
- }
-
- if (pci->ci.xad.state != CONVST_INIT1)
- return;
-
- /*
- * first one back... lock in!
- */
- pci->ci.hwndPartner = hwndServer;
- pci->ci.xad.state = CONVST_CONNECTED;
- pci->ci.fs |= ST_CONNECTED;
- if (WinQueryWindowPtr(hwndServer, QWP_PFNWP) == ServerWndProc)
- pci->ci.fs |= ST_INTRADLL;
-
- /*
- * If the connection was made using a wild app name, we want to
- * hack in an apropriate name so QueryConvInfo can give the app
- * something useful to refer to this guy as.
- *
- * - the protocol is little help here.
- */
- if (pci->ci.hszServerApp == 0) {
- if (WinQueryWindowPtr(hwndServer, QWP_PFNWP) == ServerWndProc) {
- /*
- * one of ours! simple.
- */
- pci->ci.hszServerApp = (PAPPINFO)WinSendMsg(pci->ci.hwndPartner,
- UM_QUERY, (MPARAM)Q_APPNAME, 0L);
- } else {
- /*
- * Try the psz in pddei. Maybe the server set it properly
- * before returning it.
- */
- if (!(pci->ci.hszServerApp =
- GetHsz(PSZAPP(pddei), pci->ci.cc.idCountry,
- pci->ci.cc.usCodepage, TRUE))) {
-
- PSZ pszT;
- USHORT cb;
-
- /*
- * WORST CASE:
- * Until a better way is found, we set the hszServerApp to
- * the title of the frame window.
- */
- if (pszT = FarAllocMem(pci->ci.pai->hheapApp,
- cb = WinQueryWindowTextLength(pci->ci.hwndFrame) + 1)
- WinQueryWindowText(pci->ci.hwndFrame, cb, (PSZ)pszT);
- pci->ci.hszServerApp = GetHsz(pszT, pci->ci.cc.idCountry,
- pci->ci.cc.usCodepage, TRUE);
- FarFreeMem(pci->ci.pai->hheapApp, (PBYTE)pszT, cb);
- }
- }
- }
- }
- /*
- * Now what if the topic was wild?
- */
- if (pci->ci.hszTopic == 0) {
- if (WinQueryWindowPtr(hwndServer, QWP_PFNWP) == ServerWndProc) {
- /*
- * one of ours! simple.
- */
- pci->ci.hszTopic = (PAPPINFO)WinSendMsg(pci->ci.hwndPartner,
- UM_QUERY, (MPARAM)Q_TOPIC, 0L);
- } else {
- /*
- * Try the psz in pddei. Maybe the server set it properly
- * before returning it. If this doesn't work were out of
- * luck, keep it wild.
- */
- pci->ci.hszServerApp = GetHsz(PSZAPP(pddei), pci->ci.cc.idCountry
- pci->ci.cc.usCodepage, TRUE);
- }
- }
- }
-
-
-
- /***************************** Private Function ****************************\
- * Processes a client transfer request issued by one of the ClientXfer
- * functions. This may be synchronous or asynchronous.
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- MRESULT ClientXferReq(pXferInfo, pci, hwnd)
- PXFERINFO pXferInfo;
- PCLIENTINFO pci;
- HWND hwnd;
- {
- PCQDATA pcqd;
- MRESULT retVal;
-
- if (pXferInfo->ulTimeout == TIMEOUT_ASYNC) {
- /*
- * add a client queue item to track this transaction and return
- * the ID.
- */
- if (pci->pQ == NULL)
- pci->pQ = CreateQ(sizeof(CQDATA));
- if (pci->pQ == NULL) {
- pci->ci.pai->LastError = DMGERR_MEMORY_ERROR;
- return(0);
- }
- pcqd = (PCQDATA)Addqi(pci->pQ);
- if (pcqd == NULL) {
- pci->ci.pai->LastError = DMGERR_MEMORY_ERROR;
- return(0);
- }
- CopyBlock((PBYTE)pXferInfo, (PBYTE)&pcqd->XferInfo, sizeof(XFERINFO))
- pcqd->xad.state = CONVST_CONNECTED;
- pcqd->xad.pddes = 0;
- pcqd->xad.LastError = DMGERR_NO_ERROR;
- pcqd->xad.pXferInfo = &pcqd->XferInfo;
- /*
- * Get transaction started - if it fails, quit now.
- */
- if ((pcqd->xad.LastError = SendClientReq(&pcqd->xad,
- pci->ci.hwndPartner, hwnd, pci->ci.pai)) == DMGERR_SERVER_DIE
- pci->ci.fs = pci->ci.fs & ~ST_CONNECTED;
- Deleteqi(pci->pQ, MAKEID(pcqd));
- pci->ci.pai->LastError = DMGERR_SERVER_DIED;
- return(0);
- }
- return((MRESULT)MAKEID(pcqd));
- }
-
- /*
- * if not quiesent, yet synchronous, tell him were busy.
- * (this case could happen on a recursive call.)
- */
- if (pci->ci.xad.state != CONVST_CONNECTED) {
- pci->ci.pai->LastError = DMGERR_BUSY;
- return(0);
- }
- /*
- * Set this so messages comming in during the conversation know whats up
- */
- pci->ci.xad.pXferInfo = pXferInfo;
-
- if ((pci->ci.pai->LastError = SendClientReq(&pci->ci.xad,
- pci->ci.hwndPartner, hwnd, pci->ci.pai)) == DMGERR_SERVER_DIED) {
- pci->ci.fs = pci->ci.fs & ~ST_CONNECTED;
- }
-
- if (pci->ci.pai->LastError != DMGERR_NO_ERROR)
- return(0);
- /*
- * reset the LastError here so we know if we had problems while
- * in the modal loop.
- */
- pci->ci.pai->LastError = DMGERR_NO_ERROR;
- /*
- * timeout - modal loop.
- */
- if (!timeout(pci->ci.pai, pXferInfo->ulTimeout, hwnd)) {
- /*
- * reentrency or client has unregistered
- */
- return(0);
- }
- /*
- * check results - lasterror already set by timeout().
- * Synchronous conversation must be reset to quiesent by the time we
- * give up.
- */
- if (pci->ci.xad.state == CONVST_INCOMPLETE) {
- pci->ci.xad.state = CONVST_CONNECTED;
- return(0);
- }
-
- retVal = ClientXferRespond(pci, &pci->ci.xad, &pci->ci.pai->LastError);
- if (pci->ci.xad.state == CONVST_INCOMPLETE)
- pci->ci.xad.state = CONVST_CONNECTED;
-
- return(retVal);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * This routine sends the apropriate initiation messages for starting a
- * client request according to the transaction data given.
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- USHORT SendClientReq(pXad, hwndServer, hwnd, pai)
- PXADATA pXad;
- HWND hwndServer;
- HWND hwnd;
- PAPPINFO pai;
- {
- USHORT fsStatus = 0;
- USHORT msg;
- BOOL fCopy;
- PDDESTRUCT pddes;
-
- switch (pXad->pXferInfo->usType) {
- case XTYP_REQUEST:
- msg = WM_DDE_REQUEST;
- pXad->state = CONVST_REQSENT;
- fCopy = FALSE;
- break;
-
- case XTYP_POKE:
- msg = WM_DDE_POKE;
- pXad->state = CONVST_POKESENT;
- fCopy = TRUE;
- break;
-
- case XTYP_EXEC:
- msg = WM_DDE_EXECUTE;
- pXad->state = CONVST_EXECSENT;
- fCopy = TRUE;
- break;
-
- case XTYP_ADVSTART:
- case XTYP_ADVSTART | XTYPF_NODATA:
- case XTYP_ADVSTART | XTYPF_ACKREQ:
- case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:
- fsStatus = pXad->pXferInfo->usType & (DDE_FACKREQ | DDE_FNODATA);
- msg = WM_DDE_ADVISE;
- pXad->state = CONVST_ADVSENT;
- fCopy = FALSE;
- break;
-
- case XTYP_ADVSTOP:
- msg = WM_DDE_UNADVISE;
- pXad->state = CONVST_UNADVSENT;
- fCopy = FALSE;
- break;
-
- default:
- return(DMGERR_INVALIDPARAMETER);
- break;
- }
-
- /*
- * Send transfer
- */
- if ((pddes = AllocDDESel(fsStatus, pXad->pXferInfo->usFmt,
- pXad->pXferInfo->hszItem, fCopy ? pXad->pXferInfo->cb : 0, NULL))
- == 0) {
- pXad->state = CONVST_CONNECTED;
- return(DMGERR_MEMORY_ERROR);
- }
-
- if (fCopy)
- CopyHugeBlock((PBYTE)pXad->pXferInfo->pData, DDES_PABDATA(pddes),
- pXad->pXferInfo->cb);
-
- if (WinIsWindow(DMGHAB, hwndServer)) {
- if (!MyDdePostMsg(hwndServer, hwnd, msg, (PMYDDES)pddes, pai, MDPM_FR
- pXad->state = CONVST_CONNECTED;
- return(DMGERR_POSTMSG_FAILED);
- }
- } else {
- /*
- * We lost the server, we are TERMINATED arnold!
- */
- pXad->state = CONVST_TERMINATED;
- FreeData((PMYDDES)pddes, pai);
- return(DMGERR_SERVER_DIED);
- }
- return(DMGERR_NO_ERROR);
- }
-
-
-
-
-
- /***************************** Private Function ****************************\
- * This handles client window processing of WM_DDE_ACK and WM_DDE_DATA msgs.
- * On exit pddes is freed.
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- void DoClientDDEmsg(pci, hwnd, msg, hwndFrom, pddes)
- PCLIENTINFO pci;
- HWND hwnd;
- USHORT msg;
- HWND hwndFrom;
- PDDESTRUCT pddes;
- {
- PCQDATA pqd;
- int i;
- HSZ hszItem;
- PADVLI pAdviseItem;
-
- /*
- * make sure its for us.
- */
- if (hwndFrom != pci->ci.hwndPartner || !(pci->ci.fs & ST_CONNECTED)) {
- FreeData((PMYDDES)pddes, pci->ci.pai);
- return;
- }
- /*
- * Check if it fits the synchronous transaction data
- */
- if (fExpectedMsg(&pci->ci.xad, pddes, msg, pci)) {
- if (AdvanceXaction(hwnd, pci, &pci->ci.xad, pddes, msg,
- &pci->ci.pai->LastError))
- WinPostMsg(hwnd, WM_TIMER, (MPARAM)TID_TIMEOUT, 0L);
- return;
- }
-
- /*
- * See if it fits any asynchronous transaction data - if any exist
- */
- if (pci->pQ != NULL && pci->pQ->pqiHead != NULL) {
- SemEnter();
- pqd = (PCQDATA)pci->pQ->pqiHead;
- /*
- * cycle from oldest to newest.
- */
- for (i = pci->pQ->cItems; i; i--) {
- pqd = (PCQDATA)pqd->next;
- if (!fExpectedMsg(&pqd->xad, pddes, msg, pci))
- continue;
- if (AdvanceXaction(hwnd, pci, &pqd->xad, pddes, msg,
- &pqd->xad.LastError)) {
- ClientXferRespond(pci, &pqd->xad, &pqd->xad.LastError);
- SemLeave();
- MakeCallback(pci->ci.pai, hwnd, (HSZ)0L, (HSZ)0L, 0,
- XTYP_XFERCOMPLETE, (HDMGDATA)MAKEID(pqd),
- 0, 0, hwndFrom);
- return;
- }
- SemLeave();
- return;
- }
- SemLeave();
- }
- /*
- * It doesn't fit anything, check for an advise data message.
- */
- if (msg == WM_DDE_DATA) {
- hszItem = GetHszItem((PMYDDES)pddes, &pci->ci.cc, TRUE);
- if (pAdviseItem = (PADVLI)FindAdvList(pci->ci.pAdviseList, hszItem,
- pddes->usFormat)) {
- MakeCallback(pci->ci.pai, (HCONV)hwnd, pci->ci.hszTopic,
- hszItem, pddes->usFormat, XTYP_ADVDATA, pddes, msg,
- pddes->fsStatus, pci->ci.hwndPartner);
- } else {
- FreeHsz(hszItem);
- }
- return;
- }
- /*
- * throw it away
- */
- FreeData((PMYDDES)pddes, pci->ci.pai);
- return;
- }
-
-
-
- /***************************** Private Function ****************************\
- * This routine matches a conversation transaction with a DDE message. If
- * the state, usType, format, itemname dde structure data and the message
- * received all agree, TRUE is returned.
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- BOOL fExpectedMsg(pXad, pddes, msg, pci)
- PXADATA pXad;
- PDDESTRUCT pddes;
- USHORT msg;
- PCLIENTINFO pci;
- {
- HSZ hsz = 0;
- BOOL fRet = FALSE;
-
- if (!(pXad->state > CONVST_INIT1 &&
- pddes->usFormat == pXad->pXferInfo->usFmt &&
- (hsz = GetHszItem((PMYDDES)pddes, &pci->ci.cc, TRUE)) ==
- pXad->pXferInfo->hszItem)) {
- goto Exit;
- }
- switch (pXad->state) {
- case CONVST_REQSENT:
- if (msg == WM_DDE_DATA && !(pddes->fsStatus & DDE_FRESPONSE))
- /*
- * Not data in response to a request!
- */
- break;
- fRet = (msg == WM_DDE_ACK || msg == WM_DDE_DATA);
- break;
-
- case CONVST_POKESENT:
- case CONVST_EXECSENT:
- case CONVST_ADVSENT:
- case CONVST_UNADVSENT:
- fRet = (msg == WM_DDE_ACK);
- break;
- }
-
- Exit:
- FreeHsz(hsz);
- return(fRet);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This function assumes that msg is an apropriate message for the transaction
- * referenced by pXad. It acts on msg as apropriate. pddes is the DDESTRUCT
- * associated with msg.
- *
- * Returns fSuccess ie: transaction is ready to close up.
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- BOOL AdvanceXaction(hwnd, pci, pXad, pddes, msg, pErr)
- HWND hwnd;
- PCLIENTINFO pci;
- PXADATA pXad;
- PDDESTRUCT pddes;
- USHORT msg;
- PUSHORT pErr;
- {
- switch (msg) {
- case WM_DDE_ACK:
- switch (pXad->state) {
- case CONVST_ADVSENT:
- case CONVST_EXECSENT:
- case CONVST_POKESENT:
- case CONVST_REQSENT:
- case CONVST_UNADVSENT:
- if (pddes->fsStatus & DDE_FACK) {
- /*
- * handle successes
- */
- switch (pXad->state) {
- case CONVST_POKESENT:
- pXad->state = CONVST_POKEACKRCVD;
- break;
-
- case CONVST_EXECSENT:
- pXad->state = CONVST_EXECACKRCVD;
- break;
-
- case CONVST_ADVSENT:
- pXad->state = CONVST_ADVACKRCVD;
- break;
-
- case CONVST_UNADVSENT:
- pXad->state = CONVST_UNADVACKRCVD;
- break;
-
- case CONVST_REQSENT:
- /*
- * requests are not expected to send a +ACK. only
- * -ACK or data. We ignore a +ACK to a request.
- */
- FreeData((PMYDDES)pddes, pci->ci.pai);
- return(FALSE);
- }
- } else {
- /*
- * handle the expected ACK failures.
- */
- *pErr = DMGERR_NOTPROCESSED;
- if (pddes->fsStatus & DDE_FBUSY)
- *pErr = DMGERR_BUSY;
- pXad->state = CONVST_INCOMPLETE;
- }
- }
- FreeData((PMYDDES)pddes, pci->ci.pai);
- return(TRUE);
- break;
-
- case WM_DDE_DATA:
- switch (pXad->state) {
- case CONVST_REQSENT:
- /*
- * send an ack if requested - we dare not return the given
- * pddes because it may be a data item sent to several
- * clients and we would mess up the fsStatus word for
- * all processes involved.
- */
- if (pddes->fsStatus & DDE_FACKREQ) {
- MyDdePostMsg(pci->ci.hwndPartner, hwnd, WM_DDE_ACK,
- (PMYDDES)AllocDDESel(DDE_FACK, pddes->usFormat,
- pXad->pXferInfo->hszItem, 0L, NULL),
- pci->ci.pai, MDPM_FREEHDATA);
- }
- pXad->state = CONVST_DATARCVD;
- /*
- * We do NOT free the selector here yet because it will be
- * given to the client via pXad->pddes.
- */
- pXad->pddes = pddes;
- return(TRUE);
- break;
- }
- }
- return(FALSE);
- }
-
-
-
- /***************************** Private Function ****************************\
- * This function assumes that a client transfer request has been completed -
- * or should be completed by the time this is called.
- *
- * pci contains general client info
- * pXad contains the transaction info
- * pErr points to where to place the LastError code.
- *
- * Returns 0 on failure
- * Returns TRUE or a Data Selector on success.
- * On failure, the conversation is left in a CONVST_INCOMPLETE state.
- * On success, the conversation is left in a CONVST_CONNECTED state.
- *
- * History:
- * Created 9/1/89 Sanfords
- \***************************************************************************/
- MRESULT ClientXferRespond(pci, pXad, pErr)
- PCLIENTINFO pci;
- PXADATA pXad;
- PUSHORT pErr;
- {
- if (pXad->state == CONVST_INCOMPLETE)
- return(0);
-
- switch (pXad->pXferInfo->usType) {
- case XTYP_REQUEST:
- if (pXad->state != CONVST_DATARCVD) {
- if (*pErr == DMGERR_NO_ERROR)
- *pErr = DMGERR_DATAACKTIMEOUT;
- goto failexit;
- }
- pXad->state = CONVST_CONNECTED;
- return(pXad->pddes);
- break;
-
- case XTYP_POKE:
- if (pXad->state != CONVST_POKEACKRCVD) {
- if (*pErr == DMGERR_NO_ERROR)
- *pErr = DMGERR_POKEACKTIMEOUT;
- goto failexit;
- }
- pXad->state = CONVST_CONNECTED;
- return(TRUE);
- break;
-
- case XTYP_EXEC:
- if (pXad->state != CONVST_EXECACKRCVD) {
- if (*pErr == DMGERR_NO_ERROR)
- *pErr = DMGERR_EXECACKTIMEOUT;
- goto failexit;
- }
- pXad->state = CONVST_CONNECTED;
- return(TRUE);
- break;
-
- case XTYP_ADVSTART:
- case XTYP_ADVSTART | XTYPF_NODATA:
- case XTYP_ADVSTART | XTYPF_ACKREQ:
- case XTYP_ADVSTART | XTYPF_NODATA | XTYPF_ACKREQ:
- if (pXad->state != CONVST_ADVACKRCVD) {
- if (*pErr == DMGERR_NO_ERROR)
- *pErr = DMGERR_ADVACKTIMEOUT;
- goto failexit;
- }
- if (!AddAdvList(pci->ci.pAdviseList, pXad->pXferInfo->hszItem,
- pXad->pXferInfo->usType & (DDE_FACKREQ | DDE_FNODATA),
- pXad->pXferInfo->usFmt)) {
- pXad->state = CONVST_INCOMPLETE;
- pci->ci.pai->LastError = DMGERR_MEMORY_ERROR;
- return(FALSE);
- } else {
- pXad->state = CONVST_CONNECTED;
- pci->ci.fs |= ST_ADVISE;
- return(TRUE);
- }
- break;
-
- case XTYP_ADVSTOP:
- if (pXad->state != CONVST_UNADVACKRCVD) {
- if (*pErr == DMGERR_NO_ERROR)
- *pErr = DMGERR_UNADVACKTIMEOUT;
- goto failexit;
- }
- if (!DeleteAdvList(pci->ci.pAdviseList, pXad->pXferInfo->hszItem,
- pXad->pXferInfo->usFmt))
- pci->ci.fs &= ~ST_ADVISE;
- pXad->state = CONVST_CONNECTED;
- return(TRUE);
- break;
-
- }
-
- failexit:
- pXad->state = CONVST_INCOMPLETE;
- return(0);
- }
-
-
-
-
-
-
- /*
- * ----------------------------SERVER SECTION--------------------------------
- */
-
-
-
- /***************************** Public Function ****************************\
- * MRESULT EXPENTRY ServerWndProc(hwnd, msg, mp1, mp2)
- * HWND hwnd;
- * USHORT msg;
- * MPARAM mp1;
- * MPARAM mp2;
- *
- * DESCRIPTION:
- * This processes DDE conversations from the server end.
- * It stores internal information and acts much like a state machine.
- * If closed, it will automaticly abort any conversation in progress.
- * It also maintains an internal list of all items which currently are
- * in active ADVISE loops.
- * PUBDOC START
- * These server windows have the feature that a conversation can be
- * re-initiated with them by a client. The Client merely terminates
- * the conversation and then re-initiates by using a SendMsg to this
- * window. This allows a client to change the topic of the conversation
- * or to pass the conversation on to another client window without
- * loosing the server it initiated with. This is quite useful for
- * wild initiates.
- * PUBDOC END
- *
- * History:
- * 10/18/89 sanfords Added hack to make hszItem==0L when offszItem==offabData.
- * 1/4/89 sanfords created
- \***************************************************************************/
- MRESULT EXPENTRY ServerWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- #define PDDES ((PDDESTRUCT)mp2)
- register PSERVERINFO psi;
- MPARAM mrData;
- PADVLI pAdviseItem;
- PSZ pszApp, pszTopic;
- HSZ hsz;
- USHORT cchApp, cchTopic;
- USHORT usType;
- HDMGDATA hDmgData = 0L;
- BOOL fResult;
-
-
- psi = (PSERVERINFO)WinQueryWindowULong(hwnd, QWL_USER);
-
- switch (msg) {
- case WM_DDE_REQUEST:
- case WM_DDE_ACK:
- case WM_DDE_ADVISE:
- case WM_DDE_UNADVISE:
- case WM_DDE_POKE:
- case WM_DDE_EXECUTE:
- /*
- * only respond if this is for us.
- */
- if ((HWND)mp1 != psi->ci.hwndPartner || !(psi->ci.fs & ST_CONNECTED))
- FreeData((PMYDDES)mp2, psi->ci.pai);
- return(0);
- }
- }
-
- switch (msg) {
- case WM_CREATE: {
- PAPPINFO pai;
-
- /*
- * allocate and initialize the server window info.
- */
- pai = GetCurrentAppInfo(FALSE);
- SemEnter();
-
- if (!(psi = (PSERVERINFO)FarAllocMem(pai->hheapApp, sizeof(SERVER
- goto LowMem;
- FillBlock((PBYTE)&psi->ci, sizeof(COMMONINFO), 0);
- if (!(psi->ci.pAdviseList = CreateLst(pai->hheapApp, sizeof(ADVLI
- FarFreeMem(pai->hheapApp, (PBYTE)psi, sizeof(SERVERINFO));
- LowMem:
- pai->LastError = DMGERR_MEMORY_ERROR;
- SemLeave();
- return(1); /* abort creation - low memory */
- }
- SemLeave();
- psi->ci.pai = pai;
- psi->ci.xad.state = CONVST_NULL;
- WinSetWindowULong(hwnd, QWL_USER, (ULONG)psi);
- }
- break;
-
- case UMSR_INITIATE:
- /*
- * This was sent by the subclassed frame of the server app.
- * The frame has already queried the server for permission
- * to create this window.
- *
- * If mp2 is NULL, this is a hot server window waiting for
- * a WM_DDE_INITIATE.
- */
- #define pii ((PINITINFO)mp1)
- IncHszCount(psi->ci.hszServerApp = pii->hszAppName);
- IncHszCount(psi->ci.hszTopic = pii->hszTopic);
- psi->ci.hwndPartner = (HWND)mp2;
- psi->ci.hwndFrame = FindFrame(psi->ci.hwndPartner);
- psi->ci.cc.fsContext = pii->pCC->fsContext;
- psi->ci.cc.idCountry = pii->pCC->idCountry;
- psi->ci.cc.usCodepage = pii->pCC->usCodepage;
- psi->ci.fs |= ST_CONNECTED;
- psi->ci.xad.state = CONVST_CONNECTED;
-
- SemEnter();
- pszApp = pszFromHsz(psi->ci.hszServerApp, &cchApp);
- pszTopic = pszFromHsz(psi->ci.hszTopic, &cchTopic);
- SemLeave();
-
- if (mp2)
- WinDdeRespond((HWND)mp2, hwnd, pszApp, pszTopic);
-
- SemEnter();
- FarFreeMem(hheapDmg, (PBYTE)pszApp, cchApp);
- FarFreeMem(hheapDmg, (PBYTE)pszTopic, cchTopic);
- SemLeave();
-
- return(1);
- #undef pii
- break;
-
- case WM_DDE_INITIATE:
- /*
- * This will happen when a client tries to re-initiate a conversation
- * with this server. We allow about 10 seconds after termination
- * for another client to connect specifically with this window.
- * This allows a client to swap windows on its end of the conversatio
- */
-
- if (psi->ci.xad.state == CONVST_TERMINATED &&
- (psi->ci.hszServerApp == GetHsz(PSZAPP(mp2), psi->ci.cc.idCou
- psi->ci.cc.usCodepage, FALSE))) {
-
- WinStopTimer(DMGHAB, hwnd, TID_SELFDESTRUCT);
- hsz = psi->ci.hszTopic;
- psi->ci.hszTopic = GetHsz(PSZTOPIC(mp2), psi->ci.cc.idCountry,
- psi->ci.cc.usCodepage, TRUE);
- FreeHsz(hsz);
- psi->ci.hwndPartner = (HWND)mp1;
- psi->ci.hwndFrame = FindFrame(psi->ci.hwndPartner);
- psi->ci.fs |= ST_CONNECTED;
- psi->ci.xad.state = CONVST_CONNECTED;
- if (WinQueryWindowPtr(psi->ci.hwndPartner, QWP_PFNWP) == ClientWn
- psi->ci.fs |= ST_INTRADLL;
- WinDdeRespond((HWND)mp1, hwnd, PSZAPP(mp2), PSZTOPIC(mp2));
- fResult = TRUE;
- } else
- fResult = FALSE;
-
- FreeData((PMYDDES)mp2, psi->ci.pai);
- return(fResult);
- break;
-
- case WM_DDE_TERMINATE:
- /*
- * only respond if this is for us.
- */
- if ((HWND)mp1 != psi->ci.hwndPartner)
- break;
- /* fall through */
-
- case UMSR_TERMINATE:
- /*
- * terminates any conversation in progress
- * Note that we keep around all the other conversation data so
- * a later re-connection is possible.
- */
- if (psi->ci.fs & ST_CONNECTED) {
- psi->ci.fs &= ~ST_CONNECTED;
- psi->ci.xad.state = CONVST_TERMINATED;
- if (WinIsWindow(DMGHAB, psi->ci.hwndPartner))
- WinDdePostMsg(psi->ci.hwndPartner, hwnd, WM_DDE_TERMINATE, 0L
- }
- if (psi->ci.fs & ST_ADVISE) {
- FlushLst(psi->ci.pAdviseList);
- psi->ci.fs &= ~ST_ADVISE;
- }
- /*
- * Mr. Phelps, if this window isn't reconnected within 10 odd
- * seconds, it will self-destruct. This gives the client time
- * to reconnect with another client window. This often happens
- * with wild initiates.
- */
- WinStartTimer(DMGHAB, hwnd, TID_SELFDESTRUCT, 0xa000);
- break;
-
- case WM_TIMER:
- if (LOUSHORT(mp1) == TID_SELFDESTRUCT && !(psi->ci.fs & ST_CONNECTED)
- DestroyWindow(hwnd);
- break;
-
- case WM_DESTROY:
- SemCheckOut();
- /*
- * Send ourselves a terminate and free local data.
- */
- WinSendMsg(hwnd, UMSR_TERMINATE, 0L, 0L);
- MakeCallback(psi->ci.pai, hwnd, psi->ci.hszTopic, (HSZ)NULL, 0, XTYP_
- 0L, 0, 0, psi->ci.hwndPartner);
- SemEnter();
- DestroyLst(psi->ci.pAdviseList);
- FreeHsz(psi->ci.hszServerApp);
- FreeHsz(psi->ci.hszTopic);
- FarFreeMem(psi->ci.pai->hheapApp, (PBYTE)psi, sizeof(SERVERINFO));
- SemLeave();
- break;
-
- case WM_DDE_REQUEST:
- usType = XTYP_REQUEST;
- goto Callback;
-
- case WM_DDE_EXECUTE:
- usType = XTYP_EXEC;
- hDmgData = mp2;
- goto Callback;
-
- case WM_DDE_POKE:
- usType = XTYP_POKE;
- hDmgData = mp2;
- goto Callback;
-
- case WM_DDE_ADVISE:
- usType = XTYP_ADVSTART; /* set ST_ADVISE AFTER app oks advise loop */
- goto Callback;
-
- case WM_DDE_UNADVISE:
- /*
- * Terminate the advise now, but notify the server in callback so
- * messages don't get out of order.
- */
- if (!DeleteAdvList(psi->ci.pAdviseList,
- GetHszItem(mp2, &psi->ci.cc, FALSE),
- PDDES->usFormat))
- psi->ci.fs &= ~ST_ADVISE;
- usType = XTYP_ADVSTOP;
- goto Callback;
-
- case WM_DDE_ACK:
- /*
- * This is an ack in response to the FACKREQ bit being set.
- * See if this refers to one of the advise loops.
- */
- if ((pAdviseItem = FindAdvList(psi->ci.pAdviseList,
- GetHszItem(mp2, &psi->ci.cc, FALSE),
- PDDES->usFormat)) &&
- (pAdviseItem->fsStatus & DDE_FACKREQ)) {
- /*
- * Update advise loop status - no longer waiting for an ack.
- */
- pAdviseItem->fsStatus &= ~ADVST_WAITING;
- if (pAdviseItem->fsStatus & ADVST_CHANGED) {
- pAdviseItem->fsStatus |= ADVST_POSTED;
- /*
- * The client is out of date. Send the data
- * again (simulate a post advise call).
- * Don't bother the server with ACK info.
- */
- MakeCallback(psi->ci.pai, (HCONV)hwnd, psi->ci.hszTopic,
- pAdviseItem->hszItem,
- pAdviseItem->usFmt, XTYP_ADVREQ,
- 0L, UMSR_POSTADVISE,
- pAdviseItem->fsStatus & ~DDE_FRESERVED,
- psi->ci.hwndPartner);
- FreeData((PMYDDES)mp2, psi->ci.pai);
- return(0);
- }
- }
- usType = XTYP_ACK;
- hDmgData = PDDES->fsStatus;
-
- Callback:
- MakeCallback(psi->ci.pai, (HCONV)hwnd, psi->ci.hszTopic,
- #if 0
- /*
- * hack for EXCEL which makes its items and data equal for
- * execute acks which SHOULD use NULL as the item name.
- */
- (PDDES->offszItemName == PDDES->offabData) ?
- 0L :
- #endif
- GetHszItem((PMYDDES)mp2, &psi->ci.cc, TRUE),
- PDDES->usFormat, usType,
- hDmgData, msg, PDDES->fsStatus,
- psi->ci.hwndPartner);
- /*
- * now free the incomming selector IF it wasn't passed on to
- * MakeCallback as hDmgData.
- */
- if (hDmgData != mp2)
- FreeData((PMYDDES)mp2, psi->ci.pai);
- break;
-
- case UMSR_POSTADVISE:
- /*
- * This message came from DdePostAdvise()
- *
- * Advise loops are tricky because of the desireable FACKREQ feature
- * of DDE. The advise loop list holds information in its fsStatus
- * field to maintain the state of the advise loop.
- *
- * if the ADVST_POSTED bit is set, it means that the server already
- * has an ADVREQ message in its callback queue. This prevents
- * unnecessary ADVREQ messages from getting thrown into the callback
- * queue.
- *
- * if the ADVST_WAITING bit is set, the server is still waiting for
- * the client to give it the go-ahead for more data with an
- * ACK message on this item. (FACKREQ is set) Without a go-ahead,
- * the server will not send any more advise data to the client but
- * will instead set the ADVST_CHANGED bit which will cause another
- * WM_DDE_DATA message to be sent to the client as soon as the
- * go-ahead ACK is received. This keeps the client up to date
- * but never overloads it.
- */
-
- if (!(psi->ci.fs & ST_ADVISE) ||
- !(pAdviseItem = FindAdvList(psi->ci.pAdviseList, (HSZ)mp1, 0)
- break;
-
- do {
- /*
- * for each format for this item that has an advise loop:
- */
- if (pAdviseItem->fsStatus & ADVST_POSTED)
- continue;
-
- if ((pAdviseItem->fsStatus & DDE_FACKREQ) &&
- (pAdviseItem->fsStatus & ADVST_WAITING)) {
- /*
- * if the client has not yet finished with the last data
- * we gave him, just update the advise loop status
- * instead of sending data now.
- */
- pAdviseItem->fsStatus |= ADVST_CHANGED;
- continue;
- }
- if (pAdviseItem->fsStatus & DDE_FNODATA) {
- /*
- * In the nodata case, we don't bother the server. Just
- * pass the client an apropriate DATA message.
- */
- MyDdePostMsg(psi->ci.hwndPartner, hwnd, WM_DDE_DATA,
- (PMYDDES)AllocDDESel(pAdviseItem->fsStatus & ~(DDE_FN
- pAdviseItem->usFmt, (HSZ)mp1, 0L, 0),
- psi->ci.pai, MDPM_FREEHDATA);
- continue;
- }
- /*
- * Otherwise, lets get the data from the server.
- */
- pAdviseItem->fsStatus |= ADVST_POSTED;
- MakeCallback(psi->ci.pai, (HCONV)hwnd, psi->ci.hszTopic,
- (HSZ)mp1, pAdviseItem->usFmt, XTYP_ADVREQ,
- 0, UMSR_POSTADVISE,
- pAdviseItem->fsStatus & (DDE_FACKREQ | DDE_FNODATA),
- psi->ci.hwndPartner);
- } while (pAdviseItem = FindNextAdv(pAdviseItem, (HSZ)mp1));
- break;
-
- case UM_QUERY:
- /*
- * LOUSHORT(mp1) = info index.
- * mp2 = pData. If pData==0, return data else copy into pData.
- */
- switch (LOUSHORT(mp1)) {
- case Q_STATUS:
- mrData = (MRESULT)psi->ci.fs;
- break;
-
- case Q_CLIENT:
- mrData = FALSE;
- break;
-
- case Q_APPINFO:
- mrData = psi->ci.pai;
- break;
-
- case Q_APPNAME:
- mrData = psi->ci.hszServerApp;
- break;
-
- case Q_TOPIC:
- mrData = psi->ci.hszTopic;
- break;
-
- case Q_ALL:
- mrData = (MRESULT)(SERVERINFO FAR *)psi;
- break;
- }
- if (mp2 == 0)
- return(mrData);
- else
- *(MRESULT FAR *)mp2 = mrData;
- return(1);
- break;
-
- default:
- return(WinDefWindowProc(hwnd, msg, mp1, mp2));
- break;
- }
- return(0);
- #undef PDDES
- }
-
-
-
-
- /*
- * This assumes hwnd is a DDE window. It tries to locate the proper
- * top-level frame window that this window is associated with useing
- * process and thread IDs.
- */
- HWND FindFrame(
- HWND hwnd)
- {
- PID pid, pidFrame;
- TID tid, tidFrame;
- HWND hwndMaybe = NULL;
- HWND hwndBetter = NULL;
- HWND hwndFrame;
- HENUM hEnum;
- ULONG ul;
-
- WinQueryWindowProcess(hwnd, &pid, &tid);
- hEnum = WinBeginEnumWindows(HWND_DESKTOP);
- while (hwndFrame = WinGetNextWindow(hEnum)) {
- /*
- * for all top level windows ...
- */
- ul = (ULONG)WinSendMsg(hwndFrame, WM_QUERYFRAMEINFO, 0L, 0L);
- if (FI_FRAME & ul) {
- /*
- * that are frames ...
- */
- WinQueryWindowProcess(hwndFrame, &pidFrame, &tidFrame);
- if (pidFrame == pid) {
- /*
- * in this process - maybe - ...
- */
- hwndMaybe = hwndFrame;
- if (tidFrame == tid) {
- /*
- * in this thread - better - ...
- */
- hwndBetter = hwndFrame;
- if (WinQueryWindowPtr(hwndFrame, QWP_PFNWP) ==
- subframeWndProc) {
- /*
- * that are subclassed by us - certainly!
- */
- hwndBetter = hwndFrame;
- break;
- }
- }
- }
- }
- }
- WinEndEnumWindows(hEnum);
- return(hwndBetter ? hwndBetter : hwndMaybe);
- }
-
-
-
-
- /***************************** Private Function ****************************\
- * This routine handles server message replys. This may have been called
- * immediately in the case of enabled callbacks, or may have been called
- * via DdeEnableCallback in which case the server action has been
- * delayed. QReply is responsible for freeing the pddes given as well as
- * the pcbi->hDmgData and pcbi->hszItem.
- *
- * History:
- * Created 9/12/89 Sanfords
- * 6/12/90 sanfords Added checks for HDATA ownership.
- \***************************************************************************/
- void QReply(pcbi, pddes)
- PCBLI pcbi;
- PDDESTRUCT pddes; /* hDataRet */
- {
- PSERVERINFO psi;
- PADVLI pAdviseItem;
- USHORT fsStatus, msg;
-
- if ((pcbi->usType & XCLASS_MASK) == XCLASS_NOTIFICATION)
- return;
-
- SemCheckOut();
- psi = WinSendMsg(pcbi->hConv, UM_QUERY, (MPARAM)Q_ALL, 0L);
-
- switch (pcbi->msg) {
- case UMSR_POSTADVISE:
- /*
- * The NODATA case never gets here.
- */
- if ((psi) &&
- (pAdviseItem = FindAdvList(psi->ci.pAdviseList, pcbi->hszItem
- pcbi->usFmt))) {
- pAdviseItem->fsStatus &= ~ADVST_POSTED;
- if (pddes) {
- pAdviseItem->fsStatus &= ~ADVST_CHANGED;
- MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, WM_DDE_DATA,
- (PMYDDES)pddes, psi->ci.pai, MDPM_FREEHDATA);
- if (pAdviseItem->fsStatus & DDE_FACKREQ)
- pAdviseItem->fsStatus |= ADVST_WAITING;
- }
- }
- break;
-
- case WM_DDE_REQUEST:
- if (pddes) {
- pddes->fsStatus = (pcbi->fsStatus & DDE_FACKREQ) | DDE_FRESPONSE;
- msg = WM_DDE_DATA;
- } else {
- /*
- * send a -ACK
- */
- pddes = AllocDDESel(((USHORT)pddes & DDE_FAPPSTATUS) |
- ((USHORT)pddes & DDE_FBUSY ? DDE_FBUSY : DDE_NOTPROCESSED
- pcbi->usFmt, pcbi->hszItem, 0L, NULL);
- msg = WM_DDE_ACK;
- }
- MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, msg, (PMYDDES)pddes,
- psi->ci.pai, MDPM_FREEHDATA);
- break;
-
- case WM_DDE_POKE:
- case WM_DDE_EXECUTE:
- /*
- * pddes is supposed to be the proper DDE_ constants to return.
- * we just stick them in the given pddes (hDmgData) and return
- * it as an ACK. This frees pcbi->hDmgData in the process.
- */
- ((PDDESTRUCT)pcbi->hDmgData)->fsStatus =
- (USHORT)pddes & ~DDE_FRESERVED;
- MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, WM_DDE_ACK,
- (PMYDDES)pcbi->hDmgData, psi->ci.pai, MDPM_FREEHDATA);
- break;
-
- case WM_DDE_ADVISE:
- /*
- * pddes is fStartAdvise
- * If DDE_FACK, we add the item to the advise loop
- * list and +ACK else we -ACK.
- */
- if ((BOOL)pddes) {
- psi = (PSERVERINFO)WinQueryWindowULong(pcbi->hConv, QWL_USER);
- if (AddAdvList(psi->ci.pAdviseList, pcbi->hszItem,
- pcbi->fsStatus & (DDE_FNODATA | DDE_FACKREQ),
- pcbi->usFmt) == NULL) {
- psi->ci.pai->LastError = DMGERR_MEMORY_ERROR;
- fsStatus = DDE_NOTPROCESSED;
- } else {
- psi->ci.fs |= ST_ADVISE;
- fsStatus = DDE_FACK;
- }
- } else {
- fsStatus = DDE_NOTPROCESSED;
- }
- goto AckBack;
- break;
-
- case WM_DDE_UNADVISE:
- fsStatus = DDE_FACK;
- goto AckBack;
- break;
-
- case WM_DDE_DATA:
- /*
- * must be an advise data item for the CLIENT or maybe some requested
- * data mistakenly sent here due to the client queue being flushed.
- * pddes is fsStatus.
- *
- * send an ack back if requested.
- */
- if (pcbi->fsStatus & DDE_FACKREQ) {
- /*
- * Clean up the status incase the app is messed up.
- */
- fsStatus = (USHORT)pddes & ~DDE_FRESERVED;
- if (fsStatus & (DDE_NOTPROCESSED | DDE_FBUSY))
- fsStatus &= ~DDE_FACK;
- AckBack:
- MyDdePostMsg(pcbi->hConvPartner, pcbi->hConv, WM_DDE_ACK,
- (PMYDDES)AllocDDESel(fsStatus, pcbi->usFmt, pcbi->hszItem, 0L
- psi->ci.pai, MDPM_FREEHDATA);
- }
- break;
- }
- }
-
-
-
- /*
- * ----------------FRAME SECTION------------------
- *
- * A frame window exists on behalf of every registered thread. It
- * handles conversation initiation and therefore issues callbacks
- * to the server app as needed to notify or query the server app.
- * The callback queue is always bypassed for these synchronous
- * events.
- */
-
- /***************************** Private Function ****************************\
- * MRESULT EXPENTRY subframeWndProc(hwnd, msg, mp1, mp2)
- * HWND hwnd;
- * USHORT msg;
- * MPARAM mp1;
- * MPARAM mp2;
- *
- * This routine takes care of setting up server windows as needed to respond
- * to incomming WM_DDE_INTIIATE messages. It is subclassed from the top
- * level frame of the server application.
- *
- * History: created 12/20/88 sanfords
- \***************************************************************************/
- MRESULT EXPENTRY subframeWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- PAPPINFO pai;
-
- pai = GetCurrentAppInfo(FALSE);
-
- switch (msg) {
- case UM_REGISTER:
- case UM_UNREGISTER:
- /*
- * we pass notification messages through this proc so we can make the
- * xfer call within the correct thread's context.
- */
- MakeCallback(pai, (HCONV)0, (HSZ)0, (HSZ)mp1, 0,
- msg == UM_REGISTER ? XTYP_REGISTER : XTYP_UNREGISTER,
- (HDMGDATA)mp2, msg, 0, 0L);
- return(0);
- break;
-
- case WM_DDE_INITIATE:
- FrameInitConv((HWND)mp1, (PDDEINIT)mp2);
- FreeData((PMYDDES)mp2, pai);
- break;
-
- default:
- return((*lpfnFrameWndProc)(hwnd, msg, mp1, mp2));
- break;
- }
- }
-
-
-
- void FrameInitConv(hwndClient, pddei)
- HWND hwndClient;
- PDDEINIT pddei;
- {
- PAPPINFO pai, paiClient;
- INITINFO ii;
- HSZPAIR hp[2];
- PHSZPAIR php;
- HSZ hsz = 0;
- HDMGDATA hDataCC;
- PDDESTRUCT pddes;
- HWND hwndServer;
- CONVCONTEXT cc;
- BOOL fWild;
-
- if (!CheckSel(SELECTOROF(pddei))) {
- AssertF(FALSE, "Invalid DDEINIT selector");
- return;
- }
-
- SemCheckOut();
-
- pai = GetCurrentAppInfo(FALSE);
- /*
- * If we are filtering and no app names are registered, quit.
- */
- if ((pai->afCmd & DMGCMD_FILTERINITS) &&
- QPileItemCount(pai->pAppNamePile) == 0)
- return;
-
- /*
- * filter out inits from ourselves and other agents (if we are an agent)
- */
- if (WinQueryWindowPtr(hwndClient, QWP_PFNWP) == ClientWndProc) {
- paiClient = WinSendMsg(hwndClient, UM_QUERY, (MPARAM)Q_APPINFO, 0L);
- if (paiClient == pai)
- return;
-
- if ((pai->afCmd & DMGCMD_AGENT) && (paiClient->afCmd & DMGCMD_AGENT))
- return;
- }
-
- /*
- * make sure ii.pCC is set up right.
- */
- if (pddei->cb >= sizeof(DDEINIT) && pddei->offConvContext) {
- /*
- * new dde init structure!
- */
- ii.pCC = DDEI_PCONVCONTEXT(pddei);
- } else {
- ii.pCC = &cc;
- cc.cb = sizeof(CONVCONTEXT);
- cc.idCountry = syscc.country;
- cc.usCodepage = syscc.codepage;
- cc.fsContext = 0;
- }
-
-
- hp[0].hszApp = GetHsz(PSZAPP(pddei), ii.pCC->idCountry,
- ii.pCC->usCodepage, TRUE);
-
- /*
- * filter out unwanted app names.
- */
- if (hp[0].hszApp && (pai->afCmd & DMGCMD_FILTERINITS) &&
- !FindPileItem(pai->pAppNamePile, CmppHsz, (PBYTE)&hp[0].hszApp, 0
- FreeHsz(hp[0].hszApp);
- return;
- }
-
- hp[0].hszTopic = GetHsz(PSZTOPIC(pddei), ii.pCC->idCountry,
- ii.pCC->usCodepage, TRUE);
-
- hp[1].hszApp = hp[1].hszTopic = 0L;
-
- fWild = (hp[0].hszApp == 0L || hp[0].hszTopic == 0);
-
- hDataCC = PutData((PBYTE)ii.pCC, (ULONG)sizeof(CONVCONTEXT), 0L, (HSZ)NUL
- 0, 0, pai);
-
- if (hDataCC == NULL)
- goto CheckOut;
-
- pddes = (PDDESTRUCT)DoCallback(pai, NULL, hp[0].hszTopic,
- hp[0].hszApp, 0, (fWild ? XTYP_WILDINIT : XTYP_INIT),
- hDataCC);
-
- if (pddes == NULL)
- goto CheckOut;
-
- FindPileItem(pai->pHDataPile, CmpULONG, (PBYTE)&hDataCC, FPI_DELETE);
- DosFreeSeg(SELECTOROF(hDataCC));
-
- if (fWild) {
- php = (PHSZPAIR)DDES_PABDATA(pddes);
- } else {
- php = &hp[0];
- pddes = NULL;
- }
-
- /*
- * now php points to a 0 terminated list of hszpairs to respond to.
- */
- SemEnter();
- while (QuerylatomLength((LATOM)php->hszApp) &&
- QuerylatomLength((LATOM)php->hszTopic)) {
- SemLeave();
- if ((hwndServer = CreateServerWindow(pai, php->hszTopic)) == 0)
- break;
- /*
- * have the server respond
- */
- ii.hszAppName = php->hszApp;
- ii.hszTopic = php->hszTopic;
- WinSendMsg(hwndServer, UMSR_INITIATE, (MPARAM)&ii, hwndClient);
-
- /*
- * confirm initialization to server app
- */
- DoCallback(pai, (HCONV)hwndServer, php->hszTopic, php->hszApp,
- 0, XTYP_INIT_CONFIRM, 0L);
-
- php++;
- SemEnter();
- }
- SemLeave();
- SemCheckOut();
- CheckOut:
- FreeHsz(hp[0].hszApp);
- FreeHsz(hp[0].hszTopic);
- if (fWild)
- FreeData((PMYDDES)pddes, pai);
- }
-
- HWND CreateServerWindow(
- PAPPINFO pai,
- HSZ hszTopic)
- {
- HWND hwndTSvr, hwndServer;
-
- SemCheckOut();
- /*
- * locate or make a Topic server window...
- */
- if ((hwndTSvr =
- HwndFromHsz(hszTopic, pai->pSvrTopicList)) == 0) {
- /*
- * NO - make one.
- */
- if ((hwndTSvr = WinCreateWindow(pai->hwndDmg, SZDEFCLASS, "", 0L,
- 0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_SVRTOPIC,
- 0L, 0L)) == 0L) {
- pai->LastError = DMGERR_PMWIN_ERROR;
- return(NULL);
- }
- AddHwndHszList(hszTopic, hwndTSvr, pai->pSvrTopicList);
- }
-
- /*
- * Create the server window
- */
- if ((hwndServer = WinCreateWindow(hwndTSvr, SZSERVERCLASS, "", 0L,
- 0, 0, 0, 0, (HWND)NULL, HWND_BOTTOM, WID_SERVER, 0L, 0L)) == 0L)
- pai->LastError = DMGERR_PMWIN_ERROR;
- return(NULL);
- }
- return(hwndServer);
- }
-
- /*
- * main application window - parent of all others in app.
- *
- * 6/12/90 sanfords Fixed semaphore bug
- */
- MRESULT EXPENTRY DmgWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- #define pai ((PAPPINFO)mp1)
- PCBLI pli, pliNext;
- BOOL fException;
- HDMGDATA hDataRet;
-
- hwnd;
- mp2;
-
- switch (msg) {
- case UM_CHECKCBQ:
- /*
- * We consider everything to be blocked if we are in a client
- * transfer modal loop. This prevents recursive timeout
- * calls.
- */
- if (pai->hwndTimer)
- return(0);
-
- /*
- * This is where we actually do callbacks. We do them via this
- * window proc so that we can asynchronously institute callbacks
- * via a PostMsg().
- */
- SemCheckOut();
- SemEnter();
- /*
- * process all enabled conversation callbacks.
- */
- for (pli = (PCBLI)pai->plstCB->pItemFirst; pli; pli = (PCBLI)pliNext)
- pliNext = (PCBLI)pli->next;
- fException = FindLstItem(pai->plstCBExceptions, CmpULONG, (PLITEM
- == NULL ? FALSE : TRUE;
- if (fException == pai->fEnableCB)
- continue; /* blocked */
-
- pai->cInCallback++;
- SemLeave();
- /*
- * make the actual callback here.
- */
- hDataRet = DoCallback(pai, pli->hConv, pli->hszTopic,
- pli->hszItem, pli->usFmt, pli->usType, pli->hDmgData);
- SemEnter();
- if (pai->cInCallback > 0) /* test incase exlst processing messe
- pai->cInCallback--;
-
- /*
- * If the callback resulted in a BLOCK, disable this conversation
- */
- if (hDataRet == CBR_BLOCK && !(pli->usType & XTYPF_NOBLOCK)) {
- SemLeave();
- DdeEnableCallback(pli->hConv, FALSE);
- SemEnter();
- continue;
- } else {
- /*
- * otherwise finish processing the callback.
- */
- if (WinIsWindow(DMGHAB, pli->hConvPartner)) {
- SemLeave();
- QReply(pli, (PDDESTRUCT)hDataRet);
- SemEnter();
- }
- RemoveLstItem(pai->plstCB, (PLITEM)pli);
- }
- }
- SemLeave();
- return(0);
- break;
-
- default:
- WinDefWindowProc(hwnd, msg, mp1, mp2);
- break;
- }
- #undef pai
- }
-
-
- HDMGDATA DoCallback(
- PAPPINFO pai,
- HCONV hConv,
- HSZ hszTopic,
- HSZ hszItem,
- USHORT usFmt,
- USHORT usType,
- HDMGDATA hDmgData)
- {
- HDMGDATA hDataRet;
-
- AssertF(IncHszCount(hszTopic) && FreeHsz(hszTopic), "Bad hszTopic on call
- AssertF(IncHszCount(hszItem) && FreeHsz(hszItem), "Bad hszItem on callbac
-
- if (usType & XCLASS_DATAIN) {
- AssertF(CheckSel(SELECTOROF(hDmgData)), "invalid callback data handle
- ((PMYDDES)hDmgData)->fs |= HDATA_READONLY;
- }
-
- #ifdef CRUISER
- if (pai->afCmd & DMGCMD_32BIT)
- hDataRet = ThkCallback(hConv, hszTopic, hszItem, usFmt, usType, hDmgD
- pai->pfnCallback);
- else
- #endif
- hDataRet = (*pai->pfnCallback)(hConv, hszTopic, hszItem, usFmt, usTyp
- hDmgData);
-
- if (usType & XCLASS_DATA && CheckSel(SELECTOROF(hDataRet)) > sizeof(MYDDE
- ((PMYDDES)hDataRet)->magic == MYDDESMAGIC) {
- if (((PMYDDES)hDataRet)->pai != pai) {
- AssertF(FALSE, "hData from callback not created by same thread");
- pai->LastError = DMGERR_DLL_USAGE;
- hDataRet = NULL;
- }
- }
- return(hDataRet);
- }
-
-
-
-
- EA.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\STOCK\EA.C
-
- /*** ea.c - layer for EA support
- *
- * Author:
- * Benjamin W. Slivka
- * (c) 1990
- * Microsoft Corporation
- *
- * History:
- * 08-Feb-1990 bens Initial version (Subset from EA.EXE sou
- * 02-May-1990 bens Added SetEAValue (copied from ea.exe)
- * 01-Jun-1990 bens Support binary EAs
- */
-
- #define INCL_DOSERRORS
- #define INCL_DOSFILEMGR
- #define INCL_NOPM
-
- #include <os2.h>
-
- #include <ctype.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <memory.h>
-
- #include "ea.h"
- #include "mem.h"
-
-
- #ifdef CHECKASSERTS
- #define dbg(a) a
- #else
- #define dbg(a)
- #endif
-
- // Buffer sizes for EA API calls
- #define CB_GEAL 400 // Enough for one GEA in list
- #define CB_FEAL 2000 // Enough for large file list
-
-
- char * TranslateValue(char *pbValue,USHORT cbValue,USHORT *pcbValu
-
-
- /*** EAQueryValue - Get text EA value from file
- *
- * Entry
- * pszFile - File path
- * pszName - EA name
- * pcbValue - USHORT to receive value length
- *
- * Exit-Success
- * returns non-zero pointer to value; Caller must free this!
- * If value is ASCII
- * *pcbValue == 0;
- * If value is BINARY
- * *pcbValue == length of value;
- *
- * Exit-Failure
- * returns NULL
- */
- char *EAQueryValue(char *pszFile,char *pszName,USHORT *pcbValue)
- {
- USHORT cb;
- EAOP eaop;
- FEA * pfea;
- FEA * pfeaEnd;
- FEALIST * pFEAList;
- GEA * pgea;
- GEALIST * pGEAList;
- char * psz;
- char * pszValue;
- USHORT rc;
-
- //
- // Alloc GEAList and FEAList
- //
- pGEAList = MemAlloc(CB_GEAL);
- if (pGEAList == NULL) {
- return NULL;
- }
-
- pFEAList = MemAlloc(CB_FEAL);
- if (pFEAList == NULL) {
- MemFree(pGEAList);
- return NULL;
- }
-
- // Build GEA List with one GEA
-
- pgea = pGEAList->list; // Point at first GEA
- cb = strlen(pszName);
- pgea->cbName = (UCHAR)cb; // Set length
- memcpy(pgea->szName,pszName,cb+1); // Copy name and NUL
- pgea = (GEA *)((char *)pgea + cb + sizeof(GEA));
- pGEAList->cbList = (char *)pgea - (char *)pGEAList; // Set buffer size
-
- // Get attribute value
-
- pFEAList->cbList = CB_FEAL; // Set size of FEA list
- eaop.fpGEAList = pGEAList;
- eaop.fpFEAList = pFEAList;
-
- rc = DosQPathInfo(pszFile, // File path
- FIL_QUERYEASFROMLIST, // info level
- (PBYTE)&eaop, // EAOP structure
- sizeof(eaop), // Size of EAOP
- 0L); // Reserved
- pfea = (FEA *)pFEAList->list; // Point at FEA
-
- // NOTE: DosQPathInfo only fails if there is an inconsistency in
- // one of its parameters. It DOES NOT fail if the EA is
- // not present. Rather, on a file system that does not
- // support EAs, it appears to return pFEAList->cbList ==
- // sizeof(pFEAList->cbList), indicating no FEAs are present.
- // If the file system *does* support EAs, but the particular
- // EA is not present, pFEA->cbValue == 0.
-
- if ((rc == 0) && // Call succeeded,...
- ((pFEAList->cbList) > sizeof(pFEAList->cbList)) && // FEA is there,..
- (pfea->cbValue > 0)) { // and file has EA value!
- // Parse EA value
- cb = pfea->cbName;
- psz = (char *)pfea + sizeof(FEA); // Point at name
- pszValue = psz + cb + 1; // Point at value
- psz = TranslateValue(pszValue,pfea->cbValue,pcbValue);
- }
- else
- psz = NULL; // EA not present, or too big
-
- MemFree(pFEAList);
- MemFree(pGEAList);
- return psz;
- }
-
-
- /*** TranslateValue - produce printable representation of EA value
- *
- * Entry
- * pbValue - Value buffer
- * cbValue - Length of value buffer
- * pcbValue - USHORT to receive actual value length
- *
- * Exit-Success
- * Returns non-zero pointer to value; caller MUST free!
- * If value is ASCII
- * *pcbValue == 0;
- * If value is BINARY
- * *pcbValue == length of value;
- *
- * Exit-Failure
- * Returns NULL
- *
- *
- * EAT_MVMT - Multi-value, Multi-type
- *
- * +------+----------+-------+------+--------+-------+---+---+---+---+
- * | Type | Codepage | Count | Type | Length | Value |...| T | L | V |
- * +------+----------+-------+------+--------+-------+---+---+---+---+
- * us us us us us ?
- * \________________________/ \_____________________/ \_________/
- * MVMT header Value 1 Val
- *
- */
- char * TranslateValue(char *pbValue,USHORT cbValue,USHORT *pcbValue)
- {
- USHORT cb=cbValue;
- USHORT codePage;
- USHORT cValue;
- char * pbDst;
- char * pbSrc;
- char * pszNew;
- USHORT type;
-
- // Parse MVMT header, if present
-
- pbSrc = pbValue;
-
- type = *(USHORT *)pbSrc; // Get EA value type
- if (type == EAT_MVMT) {
- pbSrc += sizeof(USHORT); // Skip type
- codePage = *((USHORT*)pbSrc)++; // Get code page
- cValue = *((USHORT*)pbSrc)++; // Get count of values
- if (cValue != 1) // Not exactly one value
- return NULL; // Fail
- type = *(USHORT *)pbSrc; // Get EA value type
- }
-
-
- // Parse value
-
- if ( (type == EAT_ASCII) || (type == EAT_BINARY) ) {
- pbSrc += sizeof(USHORT); // Skip type
- cb = *((USHORT *)pbSrc)++; // Get data length
-
- // Allocate buffer for data
-
- pszNew = MemAlloc(cb+1); // Leave room for NUL, in ASCII case
- if (pszNew == NULL)
- return NULL;
- pbDst = pszNew;
-
- // Copy data
-
- memcpy(pbDst,pbSrc,cb); // Copy value
- pbDst += cb; // Advance destination pointer
-
- if (type == EAT_ASCII) {
- *pbDst++ = '\0'; // Terminate ASCIIZ string
- *pcbValue = 0; // Indicate value is ASCIIZ
- }
- else
- *pcbValue = cb; // Indicate value is binary
- return pszNew; // Return value
- }
- else
- return NULL; // Fail
- }
-
-
- /*** EASetValue - Create/Change/Delete an EA
- *
- * Entry
- * pszFile - file path
- * pszName - EA name
- * cbValue - EA length; 0 => pszValue is ASCIIZ
- * pszValue - EA value; NULL to delete EA
- *
- * Exit-Success
- * returns TRUE
- *
- * Exit-Failure
- * returns FALSE
- *
- */
- BOOL EASetValue(char *pszFile,char *pszName,USHORT cbValue,char *pszValue)
- {
- USHORT cbName;
- EAOP eaop;
- FEA * pfea;
- FEALIST * pFEAList;
- char * psz;
- USHORT rc;
- USHORT type;
-
- // Determine operation
-
- if (pszValue == NULL) { // Delete this EA
- type = EAT_ASCII;
- cbValue = 0;
- }
- else if (cbValue == 0) { // Create/Change value
- type = EAT_ASCII;
- cbValue = strlen(pszValue); // Compute length (do not count NU
- }
- else { // Create/Change Binary value
- type = EAT_BINARY;
- }
-
- //
- // Alloc FEA List
- //
- pFEAList = MemAlloc(CB_FEAL);
- if (pFEAList == NULL)
- return FALSE;
-
- cbName = strlen(pszName);
-
- //
- // Build EA structure
- //
- pfea = (FEA *)pFEAList->list; // Point at first FEA
- pfea->fEA = 0; // No flag settings
- pfea->cbName = (UCHAR)cbName; // Set name length
- pfea->cbValue = cbValue; // Set value length
-
- psz = (char *)pfea + sizeof(FEA); // Point at location for name
- memcpy(psz,pszName,cbName+1); // Copy Name *and* NUL
- psz += cbName+1; // Point at location for value
- if (cbValue > 0) { // Edit/Create EA
- *((USHORT *)psz)++ = EAT_MVMT; // Set MVMT type (to record cod
- *((USHORT *)psz)++ = NULL; // Set codepage
- *((USHORT *)psz)++ = 1; // Only one TLV record
- *((USHORT *)psz)++ = type; // Set EA type
- *((USHORT *)psz)++ = cbValue; // Set ASCII length
-
- pfea->cbValue += 5*sizeof(USHORT); // MVMT header and type and length
- memcpy(psz,pszValue,cbValue); // Copy Value
- }
- pfea = (FEA *)(psz + cbValue); // Point at byte after FEA
-
- //
- // Set size of FEA List (only one FEA)
- //
-
- pFEAList->cbList = (char *)pfea - (char *)pFEAList;
-
- eaop.fpGEAList = NULL;
- eaop.fpFEAList = pFEAList;
-
- rc = DosSetPathInfo(pszFile, // File path
- FIL_QUERYEASIZE, // Set EA
- (PBYTE)&eaop, // EAOP structure
- sizeof(eaop), // Size of EAOP
- 0, // Options
- 0L); // Reserved
- MemFree(pFEAList);
- return (rc == 0);
- }
-
-
- EDPLINE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\EDPLINE\EDPLINE.C
-
- /*
- edpline.c -- polyline editor, for practice in mouse handling
- Created by Microsoft Corporation, 1989
- */
- #define INCL_DOSMEMMGR
- #define INCL_WINWINDOWMGR
- #define INCL_WINMESSAGEMGR
- #define INCL_WINSWITCHLIST
- #define INCL_WINDIALOGS
- #define INCL_GPIBITMAPS
- #define INCL_GPIPRIMITIVES
- #define INCL_WINMENUS
- #define INCL_WININPUT
- #define INCL_WINFRAMEMGR
- #include <os2.h>
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "edpline.h"
-
-
-
- #define abs(x) (((x) > 0) ? (x) : -(x))
- #define PRIM_POLYLINE 0x0001
- #define PRIM_POLYFILLET 0x0002
- #define PRIM_POLYSPLINE 0x0004
- #define PRIM_POINTARC 0x0008
-
-
- /************************************************************************
- *
- * Function declarations
- *
- ************************************************************************/
-
- /* Private functions */
-
- VOID cdecl main(VOID);
- BOOL InitGlobals(VOID);
- BOOL InitApp(VOID);
- VOID Close(HWND);
- VOID Command(HWND, USHORT);
- VOID Paint(HPS, BOOL);
- VOID MouseMove(HWND, MPARAM);
- VOID ButtonUp(HWND, USHORT);
- VOID ButtonDown(HWND, USHORT, MPARAM);
- USHORT IsPtInList(PPOINTL);
- USHORT AddPtToList(PPOINTL);
- BOOL IsPtCloseToLine(PPOINTL, PPOINTL, PPOINTL);
- VOID DrawPrimitive(HPS, USHORT);
- VOID DrawPolyLine(HPS);
- VOID DrawPolyFillet(HPS);
- VOID DrawPolySpline(HPS);
- VOID DrawPointArc(HPS);
- VOID DrawControlPoints(HPS, LONG, PPOINTL);
- VOID MyMessageBox(HWND, PSZ);
- VOID SwapLong(PLONG, PLONG);
-
- /* Exported functions */
-
- ULONG EXPENTRY WndProc(HWND, USHORT, MPARAM, MPARAM);
- MRESULT EXPENTRY AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);
-
-
-
- /************************************************************************
- *
- * Global Variables
- *
- ************************************************************************/
-
- typedef struct
- {
- HAB hab;
- HMQ hMsgQ;
- HWND hwndFrame;
- HWND hwnd;
-
- ULONG flPrim;
- BOOL fDisplayControlPoints;
- LONG cptl;
- PPOINTL pptl;
-
- USHORT usPtGrabbed;
- BOOL fDragging;
-
- ULONG ulHitPrecision;
-
- } GLOBALDATA;
- GLOBALDATA global;
-
-
-
-
- /************************************************************************
- *
- * main
- *
- * WinInitialize resizes our ring 2 stack, among other things, so
- * we won't GP fault trying to do graphics. WinCreateMsgQueue defines
- * us as a REAL PM app. (as well as the WINDOWAPI statement in the .DEF
- * file...) Call a sub to register our window class and create a window.
- * Loop over messages. Exit cleanly.
- *
- ************************************************************************/
-
- VOID cdecl
- main()
- {
- QMSG qMsg;
- int iRet = 0;
-
-
- global.hab = WinInitialize(0);
- global.hMsgQ = WinCreateMsgQueue(global.hab, 0);
-
- if (InitApp())
- while (WinGetMsg( global.hab, (PQMSG)&qMsg, (HWND)NULL, 0, 0 ))
- WinDispatchMsg( global.hab, (PQMSG)&qMsg );
- else
- iRet = -1;
-
- WinDestroyWindow( global.hwndFrame );
- WinDestroyMsgQueue( global.hMsgQ );
- WinTerminate( global.hab );
- DosExit(EXIT_PROCESS, iRet);
- }
-
-
-
-
- /****************************************************************************
- *
- * InitGlobals
- *
- * Initialize global variables.
- *
- ****************************************************************************/
-
- BOOL
- InitGlobals()
- {
- global.flPrim = PRIM_POLYLINE;
- global.fDisplayControlPoints = TRUE;
-
- global.cptl = 0L;
- global.pptl = NULL;
- if (DosAllocSeg(CPTLMAX * sizeof(POINTL),
- ((PUSHORT)&global.pptl)+1, 0))
- return FALSE;
-
- global.usPtGrabbed = -1;
- global.fDragging = FALSE;
- global.ulHitPrecision = 0L;
-
- return TRUE;
- }
-
-
-
-
- /****************************************************************************
- *
- * InitApp
- *
- * Register application window class and creates standard window.
- *
- ****************************************************************************/
-
- #define INIT_MENU_ITEM(val, var) \
- TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var))
-
- BOOL
- InitApp()
- {
- char szTitle[24];
- ULONG ctldata;
- PID pid;
- TID tid;
- HSWITCH hsw;
- static SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE,
- SWL_JUMPABLE, "Edit Polyline", 0 };
-
- if (!InitGlobals())
- return FALSE;
-
-
- /* Register Application Window Class */
-
- WinLoadString( global.hab, (HMODULE) NULL, IDS_TITLE, sizeof(szTitle), (P
- if ( !WinRegisterClass( global.hab, (PCH)szTitle, (PFNWP)WndProc,
- CS_SIZEREDRAW, 0 ))
- return FALSE;
-
-
-
- /* Create a window instance of class "PolyLine Editor" */
-
- ctldata = FCF_STANDARD &
- ~(ULONG)(FCF_ICON | FCF_ACCELTABLE | FCF_TASKLIST);
-
- if (global.hwndFrame = WinCreateStdWindow(
- HWND_DESKTOP, /* specify desktop as parent window
- WS_VISIBLE, /* window styles
- &ctldata, /* frame creation flags
- (PCH)szTitle, /* window class name
- (PCH)szTitle, /* name appearing in window caption
- 0L, /*
- (HMODULE)NULL, /* use current executable module id
- IDR_EDPLINE, /* menu id
- (HWND FAR *)&global.hwnd /* window handle
- ))
- {
- INIT_MENU_ITEM(IDM_CTLPOINTS, global.fDisplayControlPoints);
-
- if (global.flPrim & PRIM_POLYLINE)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYLINE);
- if (global.flPrim & PRIM_POLYFILLET)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET);
- if (global.flPrim & PRIM_POLYSPLINE)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE);
- if (global.flPrim & PRIM_POINTARC)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POINTARC);
-
-
- /* Add ourselves to the switch list. */
-
- WinQueryWindowProcess(global.hwndFrame, &pid, &tid);
- swctl.hwnd = global.hwndFrame;
- swctl.idProcess = pid;
- hsw = WinAddSwitchEntry(&swctl);
-
- return TRUE;
- }
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * WndProc
- *
- * Process messages for the window class.
- *
- ************************************************************************/
-
- ULONG EXPENTRY
- WndProc( hwnd, usMsg, mp1, mp2 )
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- MPARAM mp2;
- {
- HPS hps;
-
-
- switch (usMsg)
- {
- case WM_CLOSE:
- Close(hwnd);
- break;
-
- case WM_COMMAND:
- Command(hwnd, LOUSHORT(mp1));
- break;
-
- case WM_PAINT:
- hps = WinBeginPaint(global.hwnd, NULL, NULL);
- if (global.ulHitPrecision == 0L)
- {
- HDC hdc;
- LONG cx;
-
- if (hdc = WinQueryWindowDC(global.hwnd)) {
- DevQueryCaps(hdc, CAPS_MARKER_WIDTH, 1L, &cx);
- global.ulHitPrecision = (cx >> 17) + 1L;
- } else {
- global.ulHitPrecision = 6L;
- }
- }
- Paint(hps, TRUE);
- WinEndPaint(hps);
- break;
-
- case WM_BUTTON1DOWN:
- case WM_BUTTON2DOWN:
- ButtonDown(hwnd, usMsg, mp1);
- break;
-
- case WM_BUTTON1UP:
- case WM_BUTTON2UP:
- ButtonUp(hwnd, usMsg);
- break;
-
- case WM_MOUSEMOVE:
- MouseMove(hwnd, mp1);
- return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));
- break;
-
- default:
- return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));
- break;
- }
-
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * MouseMove
- *
- ************************************************************************/
-
- VOID
- MouseMove(hwnd, mp1)
- HWND hwnd;
- MPARAM mp1;
- {
- POINTL ptl;
- HPS hps;
-
- if (hwnd == global.hwnd)
- if (global.fDragging)
- {
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- if (global.usPtGrabbed != -1)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, FALSE);
-
- *(global.pptl+global.usPtGrabbed) = ptl;
-
- Paint(hps, FALSE);
- WinReleasePS(hps);
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * ButtonUp
- *
- ************************************************************************/
-
- VOID
- ButtonUp(hwnd, usMsg)
- HWND hwnd;
- USHORT usMsg;
- {
- int i;
- HPS hps;
-
-
- if (hwnd == global.hwnd)
- if (global.fDragging)
- {
- global.fDragging = FALSE;
- if (global.usPtGrabbed != -1)
- {
- if (usMsg == WM_BUTTON2UP)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, FALSE);
-
- if ((i = global.usPtGrabbed) < (int) global.cptl-1)
- while (i < (int) global.cptl-1)
- {
- global.pptl[i] = global.pptl[i+1];
- ++i;
- }
-
- --global.cptl;
- global.usPtGrabbed = -1;
-
- Paint(hps, FALSE);
- WinReleasePS(hps);
- }
- else /* WM_BUTTON1UP */
- global.usPtGrabbed = -1;
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * ButtonDown
- *
- ************************************************************************/
-
- VOID
- ButtonDown(hwnd, usMsg, mp1)
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- {
- POINTL ptl;
- HPS hps;
- USHORT usNewPtGrabbed;
-
-
- if (hwnd == global.hwnd)
- if (!global.fDragging)
- {
- global.fDragging = TRUE;
-
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- if ((usNewPtGrabbed = IsPtInList(&ptl)) != -1)
- global.usPtGrabbed = usNewPtGrabbed;
-
- if (usMsg == WM_BUTTON1DOWN)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, FALSE);
-
- if (usNewPtGrabbed == -1)
- global.usPtGrabbed = AddPtToList(&ptl);
- else
- global.usPtGrabbed = usNewPtGrabbed;
-
- Paint(hps, FALSE);
- WinReleasePS(hps);
-
- if (global.usPtGrabbed == -1)
- MyMessageBox(global.hwnd, "Cannot add any more points.");
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * IsPtInList
- *
- ************************************************************************/
-
- USHORT
- IsPtInList(pptl)
- PPOINTL pptl;
- {
- int i;
-
-
- /* try to find pptl in the points we already have */
- for (i = 0; i < (int) global.cptl; ++i)
- if (((abs(pptl->x - global.pptl[i].x))
- <= (LONG) global.ulHitPrecision)
- && ((abs(pptl->y - global.pptl[i].y))
- <= (LONG) global.ulHitPrecision))
- return i;
-
- /* couldn't find it */
- return -1;
- }
-
-
-
-
- /************************************************************************
- *
- * AddPtToList
- *
- ************************************************************************/
-
- USHORT
- AddPtToList(pptl)
- PPOINTL pptl;
- {
- int i, j;
-
- if (global.cptl < CPTLMAX)
- {
- /* check for new points lying on a line segment */
- for (i = 0; i < (int) (global.cptl - 1L); ++i)
- if (IsPtCloseToLine(&global.pptl[i], &global.pptl[i+1], pptl))
- {
- for (j = (int) global.cptl; j > i+1; --j)
- global.pptl[j] = global.pptl[j - 1];
- global.pptl[i+1] = *pptl;
- ++global.cptl;
- return i+1;
- }
-
- /* append the point */
-
- i = (int) global.cptl;
- global.pptl[i] = *pptl;
- ++global.cptl;
- return i;
- }
-
- return -1;
- }
-
-
-
-
- /************************************************************************
- *
- * IsPtCloseToLine
- *
- ************************************************************************/
-
- BOOL
- IsPtCloseToLine(pptl1, pptl2, pptlTest)
- PPOINTL pptl1;
- PPOINTL pptl2;
- PPOINTL pptlTest;
- {
- POINTL ptlLL, ptlUR;
- LONG dx, dy, yIntercept, result;
-
-
- /* find the bounding box of the line segment */
-
- ptlLL = *pptl1; /* assume line goes lower left to upper right */
- ptlUR = *pptl2;
- if (pptl1->x > pptl2->x)
- SwapLong(&ptlLL.x, &ptlUR.x);
- if (pptl1->y > pptl2->y)
- SwapLong(&ptlLL.y, &ptlUR.y);
-
-
- /* adjust the bounding box if it's too narrow */
-
- dx = pptl2->x - pptl1->x;
- if (abs(dx) <= (LONG) (global.ulHitPrecision >> 1))
- {
- ptlLL.x -= (LONG) (global.ulHitPrecision >> 1);
- ptlUR.x += (LONG) (global.ulHitPrecision >> 1);
- }
- dy = pptl2->y - pptl1->y;
- if (abs(dy) <= (LONG) (global.ulHitPrecision >> 1))
- {
- ptlLL.y -= (LONG) (global.ulHitPrecision >> 1);
- ptlUR.y += (LONG) (global.ulHitPrecision >> 1);
- }
-
-
- /* see if the test point is in the bounding box of the line segment */
-
- if ((pptlTest->x >= ptlLL.x) &&
- (pptlTest->x <= ptlUR.x) &&
- (pptlTest->y >= ptlLL.y) &&
- (pptlTest->y <= ptlUR.y))
- {
- /* test for special cases */
-
- if (dx == 0)
- {
- if (abs(pptlTest->x - pptl1->x) <= (LONG) global.ulHitPrecision)
- return TRUE;
- else
- return FALSE;
- }
-
- if (dy == 0)
- {
- if (abs(pptlTest->y - pptl1->y) <= (LONG) global.ulHitPrecision)
- return TRUE;
- else
- return FALSE;
- }
-
-
- /* test for general case */
-
- yIntercept = pptl1->y - (pptl1->x * dy) / dx;
-
- result = pptlTest->y - (pptlTest->x * dy / dx) - yIntercept;
- if (abs(result) <= (LONG) global.ulHitPrecision)
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * SwapLong
- *
- ************************************************************************/
-
- VOID
- SwapLong(pl1, pl2)
- PLONG pl1, pl2;
- {
- LONG lTmp;
-
- lTmp = *pl1;
- *pl1 = *pl2;
- *pl2 = lTmp;
- }
-
-
-
-
- /************************************************************************
- *
- * Close
- *
- ************************************************************************/
-
- VOID
- Close(hwnd)
- HWND hwnd;
- {
- WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
- }
-
-
-
-
- /************************************************************************
- *
- * Command
- *
- * Dispatches menu commands to the proper handlers.
- *
- ************************************************************************/
-
- #define UPDATE_MENU_BOOL(var, val) \
- { \
- TOGGLE_BOOL((var)); \
- TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var)); \
- }
-
- #define UPDATE_MENU_LIST(var, val) \
- { \
- UNCHECK_MENU_ITEM(global.hwndFrame, (var)); \
- (var) = (val); \
- CHECK_MENU_ITEM(global.hwndFrame, (var)); \
- }
-
- VOID
- Command(hwnd, id)
- HWND hwnd;
- USHORT id;
- {
- HPS hps;
- BOOL fRedraw = FALSE;
- int rc;
-
- switch (id)
- {
- case IDM_ABOUT:
- rc = WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, (HMODULE) NULL, IDD_
- fRedraw = FALSE;
- break;
-
- case IDM_NOPRIM:
- global.flPrim = 0L;
- TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYLINE, 0);
- TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET, 0);
- TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE, 0);
- fRedraw = TRUE;
- break;
-
- case IDM_POLYLINE:
- global.flPrim ^= PRIM_POLYLINE;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYLINE
- fRedraw = TRUE;
- break;
-
- case IDM_POLYFILLET:
- global.flPrim ^= PRIM_POLYFILLET;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYFILL
- fRedraw = TRUE;
- break;
-
- case IDM_POLYSPLINE:
- global.flPrim ^= PRIM_POLYSPLINE;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYSPLI
- fRedraw = TRUE;
- break;
-
- case IDM_POINTARC:
- global.flPrim ^= PRIM_POINTARC;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POINTARC
- fRedraw = TRUE;
- break;
-
- case IDM_CTLPOINTS:
- UPDATE_MENU_BOOL(global.fDisplayControlPoints, IDM_CTLPOINTS);
- fRedraw = TRUE;
- break;
-
- case IDM_CLEARALL:
- global.cptl = 0L;
- fRedraw = TRUE;
- break;
- }
-
- if (fRedraw)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, TRUE);
- WinReleasePS(hps);
- }
- }
-
-
-
-
- /************************************************************************
- *
- * Paint
- *
- ************************************************************************/
-
- VOID
- Paint(hps, fClearScreen)
- HPS hps;
- BOOL fClearScreen;
- {
- LINEBUNDLE lb;
- RECTL rcl;
-
-
-
- if (fClearScreen)
- {
- /* clear the screen */
- WinQueryWindowRect(global.hwnd, &rcl);
- GpiBitBlt(hps, NULL, 2L, (PPOINTL) &rcl, ROP_ONE, 0L);
- }
-
-
- if (global.cptl > 0L)
- {
- if (global.fDisplayControlPoints)
- {
- if (fClearScreen)
- /* draw all the control points */
- DrawControlPoints(hps, global.cptl, global.pptl);
- else if (global.usPtGrabbed != -1)
- /* draw just the control point that moved */
- DrawControlPoints(hps, 1L, global.pptl+global.usPtGrabbed);
- }
-
- /* set mix mode to xor */
- lb.usMixMode = FM_XOR;
- GpiSetAttrs(hps, PRIM_LINE, LBB_MIX_MODE, 0L, &lb);
-
- /* draw the current primitives */
-
- if (global.flPrim & PRIM_POLYLINE)
- {
- lb.lColor = CLR_BROWN;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POLYLINE);
- }
-
- if (global.flPrim & PRIM_POLYFILLET)
- {
- lb.lColor = CLR_DARKCYAN;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POLYFILLET);
- }
-
- if (global.flPrim & PRIM_POLYSPLINE)
- {
- lb.lColor = CLR_DARKPINK;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POLYSPLINE);
- }
-
- if (global.flPrim & PRIM_POINTARC)
- {
- lb.lColor = CLR_BACKGROUND;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POINTARC);
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPrimitive
- *
- ************************************************************************/
-
- VOID
- DrawPrimitive(hps, usPrim)
- HPS hps;
- USHORT usPrim;
- {
- switch ( usPrim )
- {
- case IDM_POLYLINE:
- DrawPolyLine(hps);
- break;
-
- case IDM_POLYFILLET:
- DrawPolyFillet(hps);
- break;
-
- case IDM_POLYSPLINE:
- DrawPolySpline(hps);
- break;
-
- case IDM_POINTARC:
- DrawPointArc(hps);
- break;
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPolyLine
- *
- ************************************************************************/
-
- VOID
- DrawPolyLine(hps)
- HPS hps;
- {
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPolyLine( hps, global.cptl-1L, global.pptl+1 );
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPolyFillet
- *
- ************************************************************************/
-
- VOID
- DrawPolyFillet(hps)
- HPS hps;
- {
- if (global.cptl > 2)
- {
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPolyFillet( hps, global.cptl-1L, global.pptl+1 );
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPolySpline
- *
- ************************************************************************/
-
- VOID
- DrawPolySpline(hps)
- HPS hps;
- {
- USHORT cptSlack; /* # points in pptl not usable by PolySpline */
-
- /* GpiPolySpline expects the number of points to be a
- multiple of 3. If we have a non-multiple of three,
- (excluding the first point, which we've used to set
- the current position), only pass the largest multiple
- of three, saving the rest for the next go-round. */
-
- cptSlack = (int)((global.cptl-1L) % 3) + 1;
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPolySpline( hps, global.cptl-cptSlack,
- global.pptl+1 );
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPointArc
- *
- ************************************************************************/
-
- VOID
- DrawPointArc(hps)
- HPS hps;
- {
- if (global.cptl >= 3L)
- {
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPointArc( hps, global.pptl+1 );
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawControlPoints
- *
- ************************************************************************/
-
- VOID
- DrawControlPoints(hps, cptl, pptl)
- HPS hps;
- LONG cptl;
- PPOINTL pptl;
- {
- MARKERBUNDLE mb;
-
- mb.lColor = CLR_TRUE;
- mb.usMixMode = FM_XOR;
- GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR | MBB_MIX_MODE, 0L, &mb);
-
- GpiPolyMarker(hps, cptl, pptl);
- }
-
-
-
-
- /************************************************************************
- *
- * MyMessageBox
- *
- * Displays a message box with the given string. To simplify matters,
- * the box will always have the same title ("PolyLine Editor"), will always
- * have a single button ("Ok"), will always have an exclamation point
- * icon, and will always be application modal.
- *
- ************************************************************************/
-
- VOID
- MyMessageBox(hWnd, sz)
- HWND hWnd;
- PSZ sz;
- {
- static char *szTitle = "PolyLine Editor";
-
- WinMessageBox(HWND_DESKTOP, hWnd, sz, szTitle, (HMODULE) NULL,
- MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
-
- MRESULT EXPENTRY AboutDlgProc(hDlg, msg, mp1, mp2)
- /*
- About... dialog procedure
- */
- HWND hDlg;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hDlg, TRUE); break;
- default: break;
- }
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
-
- EDPLINE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\CLIPVIEW\EDPLINE\EDPLINE.C
-
- /*
- edpline.c -- polyline editor, for practice in mouse handling
- Created by Microsoft Corporation, 1989
- */
- #define INCL_DOSMEMMGR
- #define INCL_WINWINDOWMGR
- #define INCL_WINMESSAGEMGR
- #define INCL_WINSWITCHLIST
- #define INCL_WINDIALOGS
- #define INCL_GPIBITMAPS
- #define INCL_GPIPRIMITIVES
- #define INCL_GPITRANSFORMS
- #define INCL_WINMENUS
- #define INCL_WININPUT
- #define INCL_WINFRAMEMGR
- #define INCL_WINCLIPBOARD
- #include <os2.h>
-
- #include <stdio.h>
- #include <stdlib.h>
-
- #include "edpline.h"
-
-
-
- #define abs(x) (((x) > 0) ? (x) : -(x))
- #define PRIM_POLYLINE 0x0001
- #define PRIM_POLYFILLET 0x0002
- #define PRIM_POLYSPLINE 0x0004
- #define PRIM_POINTARC 0x0008
-
-
- /************************************************************************
- *
- * Function declarations
- *
- ************************************************************************/
-
- /* Private functions */
-
- VOID cdecl main(VOID);
- BOOL InitGlobals(VOID);
- BOOL InitApp(VOID);
- VOID Close(HWND);
- VOID Command(HWND, USHORT);
- VOID Paint(HPS, BOOL);
- VOID MouseMove(HWND, MPARAM);
- VOID ButtonUp(HWND, USHORT);
- VOID ButtonDown(HWND, USHORT, MPARAM);
- USHORT IsPtInList(PPOINTL);
- USHORT AddPtToList(PPOINTL);
- BOOL IsPtCloseToLine(PPOINTL, PPOINTL, PPOINTL);
- VOID DrawPrimitive(HPS, USHORT);
- VOID DrawPolyLine(HPS);
- VOID DrawPolyFillet(HPS);
- VOID DrawPolySpline(HPS);
- VOID DrawPointArc(HPS);
- VOID DrawControlPoints(HPS, LONG, PPOINTL);
- VOID MyMessageBox(HWND, PSZ);
- VOID SwapLong(PLONG, PLONG);
-
- /* Exported functions */
-
- ULONG CALLBACK WndProc(HWND, USHORT, MPARAM, MPARAM);
- MRESULT CALLBACK AboutDlgProc(HWND, USHORT, MPARAM, MPARAM);
-
-
-
- /************************************************************************
- *
- * Global Variables
- *
- ************************************************************************/
-
- typedef struct
- {
- HAB hab;
- HMQ hMsgQ;
- HWND hwndFrame;
- HWND hwnd;
-
- ULONG flPrim;
- BOOL fDisplayControlPoints;
- LONG cptl;
- PPOINTL pptl;
-
- USHORT usPtGrabbed;
- BOOL fDragging;
-
- ULONG ulHitPrecision;
-
- HPS hpsMetafile;
- HDC hdcMetafile;
- ULONG hItem;
- SIZEL sizlPage;
- DEVOPENSTRUC dop;
-
- } GLOBALDATA;
- GLOBALDATA global;
-
-
- /************************************************************************
- *
- * main
- *
- * WinInitialize resizes our ring 2 stack, among other things, so
- * we won't GP fault trying to do graphics. WinCreateMsgQueue defines
- * us as a REAL PM app. (as well as the WINDOWAPI statement in the .DEF
- * file...) Call a sub to register our window class and create a window.
- * Loop over messages. Exit cleanly.
- *
- ************************************************************************/
-
- VOID cdecl
- main()
- {
- QMSG qMsg;
- int iRet = 0;
-
-
- global.hab = WinInitialize(0);
- global.hMsgQ = WinCreateMsgQueue(global.hab, 0);
-
- if (InitApp())
- while (WinGetMsg( global.hab, (PQMSG)&qMsg, (HWND)NULL, 0, 0 ))
- WinDispatchMsg( global.hab, (PQMSG)&qMsg );
- else
- iRet = -1;
-
- WinDestroyWindow( global.hwndFrame );
- WinDestroyMsgQueue( global.hMsgQ );
- WinTerminate( global.hab );
- DosExit(EXIT_PROCESS, iRet);
- }
-
-
-
-
- /****************************************************************************
- *
- * InitGlobals
- *
- * Initialize global variables.
- *
- ****************************************************************************/
-
- BOOL
- InitGlobals()
- {
- global.flPrim = PRIM_POLYLINE;
- global.fDisplayControlPoints = TRUE;
-
- global.cptl = 0L;
- global.pptl = NULL;
- if (DosAllocSeg(CPTLMAX * sizeof(POINTL),
- ((PUSHORT)&global.pptl)+1, 0))
- return FALSE;
-
- global.usPtGrabbed = -1;
- global.fDragging = FALSE;
- global.ulHitPrecision = 0L;
-
- return TRUE;
- }
-
-
-
-
- /****************************************************************************
- *
- * InitApp
- *
- * Register application window class and creates standard window.
- *
- ****************************************************************************/
-
- #define INIT_MENU_ITEM(val, var) \
- TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var))
-
- BOOL
- InitApp()
- {
- char szTitle[24];
- ULONG ctldata;
- PID pid;
- TID tid;
- HSWITCH hsw;
- static SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE,
- SWL_JUMPABLE, "Edit Polyline", 0 };
-
- if (!InitGlobals())
- return FALSE;
-
-
- /* Register Application Window Class */
-
- WinLoadString( global.hab, (HMODULE) NULL, IDS_TITLE, sizeof(szTitle), (P
- if ( !WinRegisterClass( global.hab, (PCH)szTitle, (PFNWP)WndProc,
- CS_SIZEREDRAW, 0 ))
- return FALSE;
-
-
-
- /* Create a window instance of class "PolyLine Editor" */
-
- ctldata = FCF_STANDARD &
- ~(ULONG)(FCF_ICON | FCF_TASKLIST);
-
- if (global.hwndFrame = WinCreateStdWindow(
- HWND_DESKTOP, /* specify desktop as parent window
- WS_VISIBLE, /* window styles
- &ctldata, /* frame creation flags
- (PCH)szTitle, /* window class name
- (PCH)szTitle, /* name appearing in window caption
- 0L, /*
- (HMODULE)NULL, /* use current executable module id
- IDR_EDPLINE, /* menu id
- (HWND FAR *)&global.hwnd /* window handle
- ))
- {
- INIT_MENU_ITEM(IDM_CTLPOINTS, global.fDisplayControlPoints);
-
- if (global.flPrim & PRIM_POLYLINE)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYLINE);
- if (global.flPrim & PRIM_POLYFILLET)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET);
- if (global.flPrim & PRIM_POLYSPLINE)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE);
- if (global.flPrim & PRIM_POINTARC)
- CHECK_MENU_ITEM(global.hwndFrame, IDM_POINTARC);
-
-
- /* Add ourselves to the switch list. */
-
- WinQueryWindowProcess(global.hwndFrame, &pid, &tid);
- swctl.hwnd = global.hwndFrame;
- swctl.idProcess = pid;
- hsw = WinAddSwitchEntry(&swctl);
-
- return TRUE;
- }
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * WndProc
- *
- * Process messages for the window class.
- *
- ************************************************************************/
-
- ULONG CALLBACK
- WndProc( hwnd, usMsg, mp1, mp2 )
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- MPARAM mp2;
- {
- HPS hps;
-
- switch (usMsg)
- {
- case WM_CLOSE:
- Close(hwnd);
- break;
-
- case WM_COMMAND:
- Command(hwnd, LOUSHORT(mp1));
- break;
-
- case WM_PAINT:
- hps = WinBeginPaint(global.hwnd, NULL, NULL);
-
- if (global.ulHitPrecision == 0L)
- {
- HDC hdc;
- LONG cx;
-
- if (hdc = WinQueryWindowDC(global.hwnd)) {
- DevQueryCaps(hdc, CAPS_MARKER_WIDTH, 1L, &cx);
- global.ulHitPrecision = (cx >> 17) + 1L;
- } else {
- global.ulHitPrecision = 6L;
- }
- }
- Paint(hps, TRUE);
- WinEndPaint(hps);
- break;
-
- case WM_BUTTON1DOWN:
- case WM_BUTTON2DOWN:
- ButtonDown(hwnd, usMsg, mp1);
- break;
-
- case WM_BUTTON1UP:
- case WM_BUTTON2UP:
- ButtonUp(hwnd, usMsg);
- break;
-
- case WM_MOUSEMOVE:
- MouseMove(hwnd, mp1);
- return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));
- break;
-
- default:
- return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));
- break;
- }
-
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * MouseMove
- *
- ************************************************************************/
-
- VOID
- MouseMove(hwnd, mp1)
- HWND hwnd;
- MPARAM mp1;
- {
- POINTL ptl;
- HPS hps;
-
- if (hwnd == global.hwnd)
- if (global.fDragging)
- {
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- if (global.usPtGrabbed != -1)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, FALSE);
-
- *(global.pptl+global.usPtGrabbed) = ptl;
-
- Paint(hps, FALSE);
- WinReleasePS(hps);
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * ButtonUp
- *
- ************************************************************************/
-
- VOID
- ButtonUp(hwnd, usMsg)
- HWND hwnd;
- USHORT usMsg;
- {
- int i;
- HPS hps;
-
-
- if (hwnd == global.hwnd)
- if (global.fDragging)
- {
- global.fDragging = FALSE;
- if (global.usPtGrabbed != -1)
- {
- if (usMsg == WM_BUTTON2UP)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, FALSE);
-
- if ((i = global.usPtGrabbed) < (int) global.cptl-1)
- while (i < (int) global.cptl-1)
- {
- global.pptl[i] = global.pptl[i+1];
- ++i;
- }
-
- --global.cptl;
- global.usPtGrabbed = -1;
-
- Paint(hps, FALSE);
- WinReleasePS(hps);
- }
- else /* WM_BUTTON1UP */
- global.usPtGrabbed = -1;
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * ButtonDown
- *
- ************************************************************************/
-
- VOID
- ButtonDown(hwnd, usMsg, mp1)
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- {
- POINTL ptl;
- HPS hps;
- USHORT usNewPtGrabbed;
-
-
- if (hwnd == global.hwnd)
- if (!global.fDragging)
- {
- global.fDragging = TRUE;
-
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- if ((usNewPtGrabbed = IsPtInList(&ptl)) != -1)
- global.usPtGrabbed = usNewPtGrabbed;
-
- if (usMsg == WM_BUTTON1DOWN)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, FALSE);
-
- if (usNewPtGrabbed == -1)
- global.usPtGrabbed = AddPtToList(&ptl);
- else
- global.usPtGrabbed = usNewPtGrabbed;
-
- Paint(hps, FALSE);
- WinReleasePS(hps);
-
- if (global.usPtGrabbed == -1)
- MyMessageBox(global.hwnd, "Cannot add any more points.");
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * IsPtInList
- *
- ************************************************************************/
-
- USHORT
- IsPtInList(pptl)
- PPOINTL pptl;
- {
- int i;
-
-
- /* try to find pptl in the points we already have */
- for (i = 0; i < (int) global.cptl; ++i)
- if (((abs(pptl->x - global.pptl[i].x))
- <= (LONG) global.ulHitPrecision)
- && ((abs(pptl->y - global.pptl[i].y))
- <= (LONG) global.ulHitPrecision))
- return i;
-
- /* couldn't find it */
- return -1;
- }
-
-
-
-
- /************************************************************************
- *
- * AddPtToList
- *
- ************************************************************************/
-
- USHORT
- AddPtToList(pptl)
- PPOINTL pptl;
- {
- int i, j;
-
- if (global.cptl < CPTLMAX)
- {
- /* check for new points lying on a line segment */
- for (i = 0; i < (int) (global.cptl - 1L); ++i)
- if (IsPtCloseToLine(&global.pptl[i], &global.pptl[i+1], pptl))
- {
- for (j = (int) global.cptl; j > i+1; --j)
- global.pptl[j] = global.pptl[j - 1];
- global.pptl[i+1] = *pptl;
- ++global.cptl;
- return i+1;
- }
-
- /* append the point */
-
- i = (int) global.cptl;
- global.pptl[i] = *pptl;
- ++global.cptl;
- return i;
- }
-
- return -1;
- }
-
-
-
-
- /************************************************************************
- *
- * IsPtCloseToLine
- *
- ************************************************************************/
-
- BOOL
- IsPtCloseToLine(pptl1, pptl2, pptlTest)
- PPOINTL pptl1;
- PPOINTL pptl2;
- PPOINTL pptlTest;
- {
- POINTL ptlLL, ptlUR;
- LONG dx, dy, yIntercept, result;
-
-
- /* find the bounding box of the line segment */
-
- ptlLL = *pptl1; /* assume line goes lower left to upper right */
- ptlUR = *pptl2;
- if (pptl1->x > pptl2->x)
- SwapLong(&ptlLL.x, &ptlUR.x);
- if (pptl1->y > pptl2->y)
- SwapLong(&ptlLL.y, &ptlUR.y);
-
-
- /* adjust the bounding box if it's too narrow */
-
- dx = pptl2->x - pptl1->x;
- if (abs(dx) <= (LONG) (global.ulHitPrecision >> 1))
- {
- ptlLL.x -= (LONG) (global.ulHitPrecision >> 1);
- ptlUR.x += (LONG) (global.ulHitPrecision >> 1);
- }
- dy = pptl2->y - pptl1->y;
- if (abs(dy) <= (LONG) (global.ulHitPrecision >> 1))
- {
- ptlLL.y -= (LONG) (global.ulHitPrecision >> 1);
- ptlUR.y += (LONG) (global.ulHitPrecision >> 1);
- }
-
-
- /* see if the test point is in the bounding box of the line segment */
-
- if ((pptlTest->x >= ptlLL.x) &&
- (pptlTest->x <= ptlUR.x) &&
- (pptlTest->y >= ptlLL.y) &&
- (pptlTest->y <= ptlUR.y))
- {
- /* test for special cases */
-
- if (dx == 0)
- {
- if (abs(pptlTest->x - pptl1->x) <= (LONG) global.ulHitPrecision)
- return TRUE;
- else
- return FALSE;
- }
-
- if (dy == 0)
- {
- if (abs(pptlTest->y - pptl1->y) <= (LONG) global.ulHitPrecision)
- return TRUE;
- else
- return FALSE;
- }
-
-
- /* test for general case */
-
- yIntercept = pptl1->y - (pptl1->x * dy) / dx;
-
- result = pptlTest->y - (pptlTest->x * dy / dx) - yIntercept;
- if (abs(result) <= (LONG) global.ulHitPrecision)
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * SwapLong
- *
- ************************************************************************/
-
- VOID
- SwapLong(pl1, pl2)
- PLONG pl1, pl2;
- {
- LONG lTmp;
-
- lTmp = *pl1;
- *pl1 = *pl2;
- *pl2 = lTmp;
- }
-
-
-
-
- /************************************************************************
- *
- * Close
- *
- ************************************************************************/
-
- VOID
- Close(hwnd)
- HWND hwnd;
- {
- WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
- }
-
-
-
-
- /************************************************************************
- *
- * Command
- *
- * Dispatches menu commands to the proper handlers.
- *
- ************************************************************************/
-
- #define UPDATE_MENU_BOOL(var, val) \
- { \
- TOGGLE_BOOL((var)); \
- TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var)); \
- }
-
- #define UPDATE_MENU_LIST(var, val) \
- { \
- UNCHECK_MENU_ITEM(global.hwndFrame, (var)); \
- (var) = (val); \
- CHECK_MENU_ITEM(global.hwndFrame, (var)); \
- }
-
- VOID
- Command(hwnd, id)
- HWND hwnd;
- USHORT id;
- {
- HPS hps;
- BOOL fRedraw = FALSE;
- int rc;
-
- switch (id)
- {
- case IDM_ABOUT:
- rc = WinDlgBox(HWND_DESKTOP, hwnd, AboutDlgProc, (HMODULE) NULL, IDD_
- fRedraw = FALSE;
- break;
-
- case IDM_NOPRIM:
- global.flPrim = 0L;
- TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYLINE, 0);
- TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYFILLET, 0);
- TOGGLE_MENU_ITEM(global.hwndFrame, IDM_POLYSPLINE, 0);
- fRedraw = TRUE;
- break;
-
- case IDM_POLYLINE:
- global.flPrim ^= PRIM_POLYLINE;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYLINE
- fRedraw = TRUE;
- break;
-
- case IDM_POLYFILLET:
- global.flPrim ^= PRIM_POLYFILLET;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYFILL
- fRedraw = TRUE;
- break;
-
- case IDM_POLYSPLINE:
- global.flPrim ^= PRIM_POLYSPLINE;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POLYSPLI
- fRedraw = TRUE;
- break;
-
- case IDM_POINTARC:
- global.flPrim ^= PRIM_POINTARC;
- TOGGLE_MENU_ITEM(global.hwndFrame, id, (global.flPrim & PRIM_POINTARC
- fRedraw = TRUE;
- break;
-
- case IDM_CTLPOINTS:
- UPDATE_MENU_BOOL(global.fDisplayControlPoints, IDM_CTLPOINTS);
- fRedraw = TRUE;
- break;
-
- case IDM_CLEARALL:
- global.cptl = 0L;
- fRedraw = TRUE;
- break;
-
- case IDM_COPY:
- /*
- To put this image on the clipboard, create a Metafile DC.
-
- Associate a presentation space with the DC, then play the
- drawing orders into the metafile.
- */
- global.dop.pszLogAddress = NULL;
- global.dop.pszDriverName = "DISPLAY";
- global.dop.pdriv = NULL;
- global.dop.pszDataType = NULL;
-
- global.hdcMetafile = DevOpenDC(global.hab, OD_METAFILE,
- "*", 4L, (PDEVOPENDATA) &global.dop, NULL);
- global.hpsMetafile = GpiCreatePS(global.hab, global.hdcMetafile,
- &global.sizlPage, PU_PELS | GPIA_ASSOC);
-
- Paint(global.hpsMetafile, TRUE);
- /*
- Clean up. A handle to the metafile is obtained when
- calling DevCloseDC().
- */
- GpiAssociate(global.hpsMetafile, NULL);
- GpiDestroyPS(global.hpsMetafile);
- global.hItem = (ULONG) DevCloseDC(global.hdcMetafile);
- /*
- Be sure to empty the clipboard of other data. This will
- also empty previous data stored in other formats.
- Then, set the clipboard data with type METAFILE, passing
- the handle to our metafile.
- */
- if (WinOpenClipbrd(global.hab)) {
- WinEmptyClipbrd(global.hab);
- WinSetClipbrdData(global.hab,global.hItem, CF_METAFILE, CFI_HANDL
- WinCloseClipbrd(global.hab);
- }
- break;
- }
-
- if (fRedraw)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, TRUE);
- WinReleasePS(hps);
- }
- }
-
-
-
-
- /************************************************************************
- *
- * Paint
- *
- ************************************************************************/
-
- VOID
- Paint(hps, fClearScreen)
- HPS hps;
- BOOL fClearScreen;
- {
- LINEBUNDLE lb;
- RECTL rcl;
- if (fClearScreen)
- {
- /* clear the screen */
- WinQueryWindowRect(global.hwnd, &rcl);
- GpiBitBlt(hps, NULL, 2L, (PPOINTL) &rcl, ROP_ONE, 0L);
- }
-
-
- if (global.cptl > 0L)
- {
- if (global.fDisplayControlPoints)
- {
- if (fClearScreen)
- /* draw all the control points */
- DrawControlPoints(hps, global.cptl, global.pptl);
- else if (global.usPtGrabbed != -1)
- /* draw just the control point that moved */
- DrawControlPoints(hps, 1L, global.pptl+global.usPtGrabbed);
- }
-
- /* set mix mode to xor */
- lb.usMixMode = FM_XOR;
- GpiSetAttrs(hps, PRIM_LINE, LBB_MIX_MODE, 0L, &lb);
-
- /* draw the current primitives */
-
- if (global.flPrim & PRIM_POLYLINE)
- {
- lb.lColor = CLR_BROWN;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POLYLINE);
- }
-
- if (global.flPrim & PRIM_POLYFILLET)
- {
- lb.lColor = CLR_DARKCYAN;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POLYFILLET);
- }
-
- if (global.flPrim & PRIM_POLYSPLINE)
- {
- lb.lColor = CLR_DARKPINK;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POLYSPLINE);
- }
-
- if (global.flPrim & PRIM_POINTARC)
- {
- lb.lColor = CLR_BACKGROUND;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- DrawPrimitive(hps, IDM_POINTARC);
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPrimitive
- *
- ************************************************************************/
-
- VOID
- DrawPrimitive(hps, usPrim)
- HPS hps;
- USHORT usPrim;
- {
- switch ( usPrim )
- {
- case IDM_POLYLINE:
- DrawPolyLine(hps);
- break;
-
- case IDM_POLYFILLET:
- DrawPolyFillet(hps);
- break;
-
- case IDM_POLYSPLINE:
- DrawPolySpline(hps);
- break;
-
- case IDM_POINTARC:
- DrawPointArc(hps);
- break;
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPolyLine
- *
- ************************************************************************/
-
- VOID
- DrawPolyLine(hps)
- HPS hps;
- {
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPolyLine( hps, global.cptl-1L, global.pptl+1 );
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPolyFillet
- *
- ************************************************************************/
-
- VOID
- DrawPolyFillet(hps)
- HPS hps;
- {
- if (global.cptl > 2)
- {
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPolyFillet( hps, global.cptl-1L, global.pptl+1 );
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPolySpline
- *
- ************************************************************************/
-
- VOID
- DrawPolySpline(hps)
- HPS hps;
- {
- USHORT cptSlack; /* # points in pptl not usable by PolySpline */
-
- /* GpiPolySpline expects the number of points to be a
- multiple of 3. If we have a non-multiple of three,
- (excluding the first point, which we've used to set
- the current position), only pass the largest multiple
- of three, saving the rest for the next go-round. */
-
- cptSlack = (int)((global.cptl-1L) % 3) + 1;
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPolySpline( hps, global.cptl-cptSlack,
- global.pptl+1 );
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPointArc
- *
- ************************************************************************/
-
- VOID
- DrawPointArc(hps)
- HPS hps;
- {
- if (global.cptl >= 3L)
- {
- GpiSetCurrentPosition( hps, global.pptl );
- GpiPointArc( hps, global.pptl+1 );
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawControlPoints
- *
- ************************************************************************/
-
- VOID
- DrawControlPoints(hps, cptl, pptl)
- HPS hps;
- LONG cptl;
- PPOINTL pptl;
- {
- MARKERBUNDLE mb;
-
- mb.lColor = CLR_TRUE;
- mb.usMixMode = FM_XOR;
- GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR | MBB_MIX_MODE, 0L, &mb);
-
- GpiPolyMarker(hps, cptl, pptl);
- }
-
-
-
-
- /************************************************************************
- *
- * MyMessageBox
- *
- * Displays a message box with the given string. To simplify matters,
- * the box will always have the same title ("PolyLine Editor"), will always
- * have a single button ("Ok"), will always have an exclamation point
- * icon, and will always be application modal.
- *
- ************************************************************************/
-
- VOID
- MyMessageBox(hWnd, sz)
- HWND hWnd;
- PSZ sz;
- {
- static char *szTitle = "PolyLine Editor";
-
- WinMessageBox(HWND_DESKTOP, hWnd, sz, szTitle, 0,
- MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
-
- MRESULT CALLBACK AboutDlgProc(HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
- /*
- About... dialog procedure
- */
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hDlg, TRUE); break;
- default: break;
- }
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
-
- EXPAND.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\EXPAND\EXPAND.C
-
- #define INCL_PM
- #include <OS2.H>
- #include "Expand.H"
-
- MRESULT EXPENTRY WndProc (HWND, USHORT, MPARAM, MPARAM );
- MRESULT EXPENTRY AboutDlgProc (HWND, USHORT, MPARAM, MPARAM);
- MRESULT EXPENTRY DialogProc (HWND, USHORT, MPARAM, MPARAM);
-
- int cdecl main(void);
-
- char szAppName[] = "Expand";
-
- HAB hAB;
- HMQ hmqMsgQueue;
- HWND hWndMain,
- hWndFrame;
-
- int cdecl main()
- {
- QMSG qmsg;
- ULONG ctlData;
-
- hAB = WinInitialize (0);
- hmqMsgQueue = WinCreateMsgQueue (hAB, 0);
-
- if (!WinRegisterClass (hAB,
- szAppName,
- WndProc,
- CS_SYNCPAINT | CS_SIZEREDRAW,
- 0)) {
- return(0);
- }
-
-
- ctlData = FCF_STANDARD;
- hWndFrame = WinCreateStdWindow ( HWND_DESKTOP,
- WS_VISIBLE,
- &ctlData,
- szAppName,
- NULL,
- 0L,
- 0,
- ID_RESOURCE,
- &hWndMain);
- WinSetWindowText (hWndFrame, szAppName);
- WinShowWindow (hWndFrame, TRUE);
-
- while ( WinGetMsg (hAB, &qmsg, NULL, 0, 0)) {
- WinDispatchMsg (hAB, &qmsg);
- }
-
- WinDestroyWindow (hWndFrame);
- WinDestroyMsgQueue (hmqMsgQueue);
- WinTerminate (hAB);
- }
-
- MRESULT EXPENTRY WndProc (hWnd, msg, mp1, mp2)
- HWND hWnd;
- USHORT msg;
- MPARAM mp1, mp2;
- {
- HPS hPS;
- RECTL rclPaint, rclWindow;
- POINTL ptlPatternRef;
-
- switch (msg) {
-
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
- case IDM_ABOUT:
- WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,
- (HMODULE) NULL, ID_RESOURCE, NULL);
- break;
-
- case IDM_ITEM+1:
- WinDlgBox(HWND_DESKTOP, hWnd, DialogProc,
- (HMODULE) NULL, ID_DIALOG, NULL);
- break;
-
- case IDM_ITEM+2:
- case IDM_ITEM+3:
- case IDM_ITEM+4:
- break;
-
- case IDM_EXIT:
- WinPostMsg (hWnd, WM_CLOSE, 0L, 0L);
- break;
- }
- break;
-
- case WM_HELP:
- WinMessageBox (HWND_DESKTOP, hWnd,
- "Help Not Implemented Yet.",
- " - Help - ",
- 0,
- MB_OK | MB_MOVEABLE | MB_APPLMODAL);
- break;
-
- case WM_CLOSE:
- WinPostMsg (hWnd, WM_QUIT, 0L, 0L);
- break;
-
- case WM_PAINT:
- hPS = WinBeginPaint (hWnd, NULL, &rclPaint);
-
- WinQueryWindowRect(hWnd, &rclWindow);
- ptlPatternRef.x = rclWindow.xLeft;
- ptlPatternRef.y = rclWindow.yTop;
- GpiSetPatternRefPoint(hPS, &ptlPatternRef);
- WinFillRect(hPS, &rclPaint, SYSCLR_APPWORKSPACE);
-
- WinEndPaint (hPS);
- break;
-
- default:
- return (WinDefWindowProc (hWnd, msg, mp1, mp2));
- }
- return 0L;
- }
-
-
- MRESULT EXPENTRY AboutDlgProc (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- switch (msg) {
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
- case IDB_OK:
- WinDismissDlg (hwnd, TRUE);
- return 0;
- }
- break;
- }
- return WinDefDlgProc (hwnd, msg, mp1, mp2);
- }
-
- MRESULT EXPENTRY DialogProc (HWND hDlg, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- SWP swpDlg, swpParent, swpOwner;
- static HWND option, button1, button2, button3, button4;
-
- switch (msg) {
-
- case WM_INITDLG:
- WinSendDlgItemMsg (hDlg, 256, EM_SETTEXTLIMIT, MPFROMSHORT(8), 0L
- WinQueryWindowPos (hDlg, &swpDlg);
- WinQueryWindowPos (WinQueryWindow(hDlg, QW_PARENT, FALSE), &swpPa
- WinQueryWindowPos (WinQueryWindow(hDlg, QW_OWNER, FALSE), &swpOwn
- swpDlg.x = swpOwner.x + ((swpOwner.cx / 2) - ((swpDlg.cx+120) / 2
- swpDlg.y = swpOwner.y + ((swpOwner.cy / 2) - (swpDlg.cy / 2));
- WinSetMultWindowPos (hAB, &swpDlg, 1);
- option = WinWindowFromID (hDlg, IDB_OPTION);
- button1 = WinWindowFromID (hDlg, IDB_RADIO1);
- WinShowWindow (button1, FALSE);
- button2 = WinWindowFromID (hDlg, IDB_RADIO2);
- WinShowWindow (button2, FALSE);
- button3 = WinWindowFromID (hDlg, IDB_RADIO3);
- WinShowWindow (button3, FALSE);
- button4 = WinWindowFromID (hDlg, IDB_RADIO4);
- WinShowWindow (button4, FALSE);
- break;
-
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
- case IDB_OPTION:
- WinQueryWindowPos (hDlg, &swpDlg);
- swpDlg.fs = SWP_SIZE;
- swpDlg.cx += 120;
- WinSetMultWindowPos (hAB, &swpDlg, 1);
- WinEnableWindow (option, FALSE);
- WinShowWindow (button1, TRUE);
- WinShowWindow (button2, TRUE);
- WinShowWindow (button3, TRUE);
- WinShowWindow (button4, TRUE);
- WinSetFocus (HWND_DESKTOP, button1);
- return FALSE;
-
- case IDB_OK:
- case IDB_CANCEL:
- WinDismissDlg (hDlg, TRUE);
- return 0;
- }
- break;
- }
- return WinDefDlgProc (hDlg, msg, mp1, mp2);
- }
-
-
- FATPEL.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\FATPEL\FATPEL.C
-
- /************************************************************************
- *
- * fatpel.c -- The Diamond Metric, Theory vs. Practice
- *
- * Created by Microsoft Corporation, 1989
- *
- ************************************************************************/
-
- #define INCL_WINFRAMEMGR
- #define INCL_WINWINDOWMGR
- #define INCL_WINMESSAGEMGR
- #define INCL_WINPOINTERS
- #define INCL_WINSWITCHLIST
- #define INCL_WINTRACKRECT
- #define INCL_WINDIALOGS
- #define INCL_WINBUTTONS
- #define INCL_GPILOGCOLORTABLE
- #define INCL_GPIBITMAPS
- #define INCL_GPITRANSFORMS
- #define INCL_DOSMEMMGR
- #define INCL_DOSFILEMGR
- #define INCL_BITMAPFILEFORMAT
- #define INCL_GPIPRIMITIVES
- #define INCL_WINMENUS
- #define INCL_GPIREGIONS
- #define INCL_WINPOINTERS
- #define INCL_WININPUT
- #include <os2.h>
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- #include "opendlg.h"
- #include "fatpel.h"
-
-
-
-
- /************************************************************************
- *
- * Function declarations
- *
- ************************************************************************/
-
- /* Private functions */
-
- VOID cdecl main(VOID);
- BOOL FAR InitGlobals(VOID);
- BOOL FAR InitApp(VOID);
- VOID Close(HWND);
- VOID Command(HWND, USHORT);
- VOID Paint(HPS, USHORT);
- VOID EraseBackground(HPS);
- VOID DrawGrid(HPS);
- VOID DisplayRenderedPels(HPS, USHORT);
- VOID DisplayControlPoints(HPS, LONG, PPOINTL, USHORT);
- VOID DisplayMathematicalObject(HPS, USHORT);
- VOID DrawFatPels(HPS);
- VOID DrawOneFatPel(HPS, PPOINTL, COLOR);
- VOID GetFatPelFromPt(PPOINTL, PPOINTL);
- VOID SetFatPel(PPOINTL, COLOR);
- VOID RoundControlPoints(HPS, LONG, PPOINTL, PPOINTL, LONG, LONG);
- VOID ComputeTransform(PRECTL, PRECTL);
- VOID DrawPrimitive(HPS, LONG, PPOINTL);
- VOID UpdateSurfaceDims(VOID);
- VOID MySetWindowLong (HWND, USHORT, LONG);
- VOID MySetWindowLongHex(HWND, USHORT, LONG);
- LONG MyGetWindowLong (HWND, USHORT);
- VOID MouseMove(HWND, MPARAM);
- VOID ButtonUp(HWND, USHORT);
- VOID ButtonDown(HWND, USHORT, MPARAM);
- VOID DragPelSize(HWND, POINTS);
- VOID WriteFile(HWND, HPS);
- BOOL WriteBMP(HFILE, HPS, PBITMAPINFOHEADER);
- VOID MyMessageBox(HWND, PSZ);
- VOID SaveWindowToFile(HWND);
- SHORT IsPtInList(PPOINTL);
- SHORT AddPtToList(PPOINTL);
- BOOL IsPtCloseToLine(PPOINTL, PPOINTL, PPOINTL);
- VOID SwapLong(PLONG, PLONG);
-
-
- /* Exported functions */
-
- ULONG CALLBACK WndProc (HWND, USHORT, MPARAM, MPARAM);
- ULONG CALLBACK AboutDlg (HWND, USHORT, MPARAM, MPARAM);
- ULONG CALLBACK ColorsDlg (HWND, USHORT, MPARAM, MPARAM);
- ULONG CALLBACK PelSizeDlg(HWND, USHORT, MPARAM, MPARAM);
-
-
-
-
- /************************************************************************
- *
- * Global Variables
- *
- ************************************************************************/
-
- /* compute absolute value for arbitrary (in my case, LONG) number */
- /* this is to avoid compiler warnings about data conversion */
- #define L_ABS(x) (((x) > 0) ? (x) : (-(x)))
-
- typedef struct
- {
- HAB hab;
- HMQ hMsgQ;
- HWND hwndFrame;
- HWND hwnd;
-
- BOOL fFirstTime; /* TRUE --> first time initialization of rcl */
- RECTL rcl; /* dimensions of client rectangle */
-
- HPS hpsFat;
- HDC hdcFat;
- HBITMAP hbmFat;
- HPS hpsFatShadow;
- HDC hdcFatShadow;
- HBITMAP hbmFatShadow;
-
- RECTL rclFatBM; /* dimensions of fatbits bitmap */
- RECTL rclFat; /* dimensions of active fat bits grid */
- LONG cxFatPel; /* width of fat pel */
- LONG cyFatPel; /* height of fat pel */
- LONG cxHalfFatPel;
- LONG cyHalfFatPel;
- USHORT usPelShape;
-
- MATRIXLF matlf; /* goes from window coords to fatpel coords */
-
- BOOL fRGB; /* TRUE --> color mode is RGB */
- COLOR clrMathObj;
- COLOR clrRenderedObj;
- COLOR clrField;
- COLOR clrCrossHair;
- COLOR clrInterstice;
- COLOR clrControlPoints;
-
- COLOR clrBlackIndex;
- COLOR clrEditPel;
-
- USHORT usControlPointSymbol;
-
- BOOL fDisplayRenderedObj;
- BOOL fDisplayMathObj;
- BOOL fDisplayControlPoints;
- BOOL fDisplayCrossHairs;
- BOOL fDisplayPelBorder;
- BOOL fRoundControlPoints;
- BOOL fAutoRedraw;
- USHORT usCurPrim;
- USHORT usMix;
-
- LONG cptl;
- PPOINTL pptl;
- PPOINTL pptlTmp;
-
- BOOL fDraggingPelSize;
- HPOINTER hptrDragSize;
-
- BOOL fDraggingPelColor;
- HPOINTER hptrDragColor;
-
- SHORT sPtGrabbed;
- BOOL fDraggingControlPoint;
- LONG lHitPrecision;
-
- BOOL fEditPelColors;
-
- } GLOBALDATA;
- GLOBALDATA global;
-
-
-
-
- /************************************************************************
- *
- * main
- *
- * WinInitialize resizes our ring 2 stack, among other things, so
- * we won't GP fault trying to do graphics. WinCreateMsgQueue defines
- * us as a REAL PM app. (WINDOWAPI in .DEF file does also).
- * Call a sub to register our window class and create a window.
- * Loop over messages. Exit cleanly.
- *
- ************************************************************************/
-
- VOID cdecl
- main()
- {
- QMSG qMsg;
- int iRet = 0;
-
-
- global.hab = WinInitialize(0);
- global.hMsgQ = WinCreateMsgQueue(global.hab, 0);
-
- if (InitApp())
- while (WinGetMsg( global.hab, (PQMSG)&qMsg, (HWND)NULL, 0, 0 ))
- WinDispatchMsg( global.hab, (PQMSG)&qMsg );
- else
- iRet = -1;
-
- WinDestroyWindow( global.hwndFrame );
- WinDestroyMsgQueue( global.hMsgQ );
- WinTerminate( global.hab );
- DosExit(EXIT_PROCESS, iRet);
- }
-
-
-
-
- /****************************************************************************
- *
- * InitGlobals
- *
- * Initialize global variables.
- *
- ****************************************************************************/
-
- BOOL FAR
- InitGlobals()
- {
- global.fFirstTime = TRUE;
-
- global.rcl.xLeft = 0L;
- global.rcl.yBottom = 0L;
- global.rcl.xRight = 0L;
- global.rcl.yTop = 0L;
-
- global.hpsFat = NULL;
- global.hdcFat = NULL;
- global.hbmFat = NULL;
- global.hpsFatShadow = NULL;
- global.hdcFatShadow = NULL;
- global.hbmFatShadow = NULL;
- global.rclFatBM.xLeft = 0L;
- global.rclFatBM.yBottom = 0L;
- global.rclFatBM.xRight = 0L;
- global.rclFatBM.yTop = 0L;
-
- global.cxFatPel = 32L;
- global.cyFatPel = 32L;
- global.cxHalfFatPel = global.cxFatPel / 2L;
- global.cyHalfFatPel = global.cyFatPel / 2L;
- global.usPelShape = IDD_CIRCLE;
-
- global.fRGB = FALSE;
- global.clrMathObj = CLR_BLUE;
- global.clrRenderedObj = CLR_NEUTRAL;
- global.clrField = CLR_CYAN;
- global.clrCrossHair = CLR_DARKCYAN;
- global.clrInterstice = CLR_BACKGROUND;
- global.clrControlPoints = CLR_YELLOW;
-
- global.clrBlackIndex = CLR_ERROR;
- global.clrEditPel = CLR_ERROR;
-
- global.usControlPointSymbol = MARKSYM_SOLIDDIAMOND;
-
- global.fDisplayRenderedObj = TRUE;
- global.fDisplayMathObj = TRUE;
- global.fDisplayControlPoints = TRUE;
- global.fDisplayCrossHairs = TRUE;
- global.fDisplayPelBorder = TRUE;
- global.fRoundControlPoints = FALSE;
- global.fAutoRedraw = TRUE;
- global.usCurPrim = IDM_POLYLINE;
- global.usMix = FM_OVERPAINT;
-
- global.fDraggingPelSize = FALSE;
- global.fDraggingPelColor = FALSE;
- global.fDraggingControlPoint = FALSE;
- global.sPtGrabbed = NO_POINT;
- global.lHitPrecision = 0L;
-
- global.fEditPelColors = FALSE;
-
-
- global.cptl = 0L;
- global.pptl = NULL;
- if (DosAllocSeg(CPTLMAX * sizeof(POINTL),
- ((PUSHORT)&global.pptl)+1, 0))
- return FALSE;
- global.pptlTmp = NULL;
- if (DosAllocSeg(CPTLMAX * sizeof(POINTL),
- ((PUSHORT)&global.pptlTmp)+1, 0))
- return FALSE;
-
- return TRUE;
- }
-
-
-
-
- /****************************************************************************
- *
- * InitApp
- *
- * Register application window class and creates standard window.
- *
- ****************************************************************************/
-
- #define INIT_MENU_ITEM(val, var) \
- TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var))
-
- BOOL FAR
- InitApp()
- {
- char szTitle[24];
- ULONG ctldata;
- PID pid;
- TID tid;
- HSWITCH hsw;
- static SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE,
- SWL_JUMPABLE, "FatPels", 0 };
-
- if (!InitGlobals())
- return FALSE;
-
-
- /* Register Application Window Class */
-
- WinLoadString( global.hab, (HMODULE) NULL, IDS_TITLE, sizeof(szTitle), (P
- if ( !WinRegisterClass( global.hab, (PCH)szTitle, (PFNWP)WndProc,
- CS_SIZEREDRAW, 0 ))
- return FALSE;
-
-
- /* Load the pointer to use when dragging pel size. */
- if (!(global.hptrDragSize = WinLoadPointer( HWND_DESKTOP, (HMODULE) NULL,
- return FALSE;
-
- /* Load the pointer to use when dragging pel color. */
- if (!(global.hptrDragColor = WinLoadPointer( HWND_DESKTOP, (HMODULE) NULL
- return FALSE;
-
-
- /* Create a window instance of class "FatPel" */
-
- ctldata = FCF_STANDARD &
- ~(ULONG)(FCF_ICON | FCF_ACCELTABLE | FCF_TASKLIST);
-
- if (global.hwndFrame = WinCreateStdWindow(
- HWND_DESKTOP, /* specify desktop as parent window
- WS_VISIBLE, /* window styles
- &ctldata, /* frame creation flags
- (PCH)szTitle, /* window class name
- (PCH)szTitle, /* name appearing in window caption
- 0L, /*
- (HMODULE)NULL, /* use current executable module id
- IDR_FATPEL, /* menu id
- (HWND FAR *)&global.hwnd /* window handle
- ))
- {
- INIT_MENU_ITEM(IDM_RENDEREDOBJ, global.fDisplayRenderedObj);
- INIT_MENU_ITEM(IDM_MATHOBJ, global.fDisplayMathObj);
- INIT_MENU_ITEM(IDM_CTLPOINTS, global.fDisplayControlPoints);
- INIT_MENU_ITEM(IDM_CROSSHAIRS, global.fDisplayCrossHairs);
- INIT_MENU_ITEM(IDM_PELBORDER, global.fDisplayPelBorder);
- INIT_MENU_ITEM(IDM_ROUNDPOINTS, global.fRoundControlPoints);
- INIT_MENU_ITEM(IDM_AUTOREDRAW, global.fAutoRedraw);
- INIT_MENU_ITEM(IDM_EDITPELCOLORS, global.fEditPelColors);
-
- CHECK_MENU_ITEM(global.hwndFrame, global.usCurPrim);
-
-
- /* Add ourselves to the switch list. */
-
- WinQueryWindowProcess(global.hwndFrame, &pid, &tid);
- swctl.hwnd = global.hwndFrame;
- swctl.idProcess = pid;
- hsw = WinAddSwitchEntry(&swctl);
-
- return TRUE;
- }
- return FALSE;
- }
-
-
-
-
- /*************************************************************************
- *
- * WndProc
- *
- * Process messages for the window class.
- *
- ************************************************************************/
-
- ULONG CALLBACK
- WndProc( hwnd, usMsg, mp1, mp2 )
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch (usMsg)
- {
- case WM_CLOSE:
- Close(hwnd);
- break;
-
- case WM_COMMAND:
- Command(hwnd, LOUSHORT(mp1));
- break;
-
- case WM_PAINT:
- {
- HPS hps;
-
- if (global.fFirstTime)
- {
- SIZEF sizfx;
-
- hps = WinGetPS(hwnd);
- GpiQueryMarkerBox(hps, &sizfx);
- global.lHitPrecision = sizfx.cx / 0x20000L + 1L;
- WinReleasePS(hps);
-
- UpdateSurfaceDims();
- global.fFirstTime = FALSE;
- }
-
- /* The small bitmap may have been resized since we last
- * painted, in which case it will have been initialized to
- * the field color. Therefore, we will render the mathematical
- * object to make sure the right fatpels are there.
- */
- global.usMix = FM_OVERPAINT;
- hps = WinBeginPaint(global.hwnd, NULL, NULL);
- Paint(hps, CLEAR_BACKGROUND|RENDER_MATH_OBJ);
- WinEndPaint(hps);
- }
- break;
-
- case WM_BUTTON1DOWN:
- case WM_BUTTON2DOWN:
- ButtonDown(hwnd, usMsg, mp1);
- break;
-
- case WM_BUTTON1UP:
- case WM_BUTTON2UP:
- ButtonUp(hwnd, usMsg);
- break;
-
- case WM_MOUSEMOVE:
- MouseMove(hwnd, mp1);
- break;
-
- case WM_SIZE:
- UpdateSurfaceDims();
- return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));
- break;
-
- default:
- return( (ULONG)WinDefWindowProc(hwnd, usMsg, mp1, mp2));
- break;
- }
-
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * MouseMove
- *
- ************************************************************************/
-
- VOID
- MouseMove(hwnd, mp1)
- HWND hwnd;
- MPARAM mp1;
- {
- POINTL ptl;
- HPS hps;
-
-
- /* make sure we still have our pointer */
- /* notice the hierarchy of pointer modes */
-
- if (global.fDraggingPelSize)
- {
- if (global.hptrDragSize)
- WinSetPointer(HWND_DESKTOP,global.hptrDragSize);
- }
- else if (global.fEditPelColors)
- {
- if (global.hptrDragColor)
- WinSetPointer(HWND_DESKTOP,global.hptrDragColor);
- }
- else
- WinSetPointer(HWND_DESKTOP,
- WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,FALSE));
-
-
- if (global.fDraggingPelColor)
- {
- POINTL ptl, ptlFat;
- HPS hps;
-
-
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- /* letting the point go negative causes overflow errors */
- if (ptl.x < 0)
- ptl.x = 0;
- if (ptl.y < 0)
- ptl.y = 0;
-
- GetFatPelFromPt(&ptl, &ptlFat);
- SetFatPel(&ptlFat, global.clrEditPel);
-
- hps = WinGetPS(hwnd);
- Paint(hps, OVERRIDE_RENDERED_OBJ);
- Paint(hps, IGNORED); /* this call just copies fatpels to the s
- WinReleasePS(hps);
- }
- else if (global.fDraggingControlPoint)
- {
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- /* letting the point go negative causes overflow errors */
- if (ptl.x < 0)
- ptl.x = 0;
- if (ptl.y < 0)
- ptl.y = 0;
-
- if (global.sPtGrabbed != NO_POINT)
- {
- hps = WinGetPS(hwnd);
- Paint(hps, OVERRIDE_RENDERED_OBJ);
-
- global.pptl[global.sPtGrabbed] = ptl;
-
- Paint(hps, CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);
- WinReleasePS(hps);
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * ButtonUp
- *
- ************************************************************************/
-
- VOID
- ButtonUp(hwnd, usMsg)
- HWND hwnd;
- USHORT usMsg;
- {
- SHORT i;
- HPS hps;
-
-
- if (global.fDraggingPelColor)
- {
- global.fDraggingPelColor = FALSE;
- WinSetCapture(HWND_DESKTOP, NULL);
- }
- else if (global.fDraggingControlPoint)
- {
- global.fDraggingControlPoint = FALSE;
- WinSetCapture(HWND_DESKTOP, NULL);
- if (global.sPtGrabbed != NO_POINT)
- {
- if (usMsg == WM_BUTTON2UP) /* remove point? */
- {
- hps = WinGetPS(hwnd);
- Paint(hps, OVERRIDE_RENDERED_OBJ);
-
- /* squeeze out selected point */
- if ((i = global.sPtGrabbed) < (SHORT)(global.cptl-1))
- while (i < (SHORT)(global.cptl-1))
- {
- global.pptl[i] = global.pptl[i+1];
- ++i;
- }
-
- --global.cptl;
- global.sPtGrabbed = NO_POINT;
-
- Paint(hps, CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);
- WinReleasePS(hps);
- }
- else /* WM_BUTTON1UP */
- global.sPtGrabbed = NO_POINT;
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * ButtonDown
- *
- ************************************************************************/
-
- VOID
- ButtonDown(hwnd, usMsg, mp1)
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- {
- if (global.fDraggingPelSize)
- {
- POINTS pt;
- HPS hps;
-
- pt.x = LOUSHORT(mp1);
- pt.y = HIUSHORT(mp1);
- DragPelSize(hwnd, pt);
- global.fDraggingPelSize = FALSE;
-
- WinSetPointer(HWND_DESKTOP,
- WinQuerySysPointer(HWND_DESKTOP,SPTR_ARROW,FALSE));
-
- hps = WinGetPS(hwnd);
- global.usMix = FM_OVERPAINT;
- Paint(hps, CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);
- WinReleasePS(hps);
- }
- else if (global.fEditPelColors)
- {
- POINTL ptl, ptlFat;
- HPS hps;
-
- global.fDraggingPelColor = TRUE;
- WinSetCapture(HWND_DESKTOP, hwnd);
-
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- if (global.usMix != FM_XOR)
- {
- hps = WinGetPS(hwnd);
- global.usMix = FM_XOR;
- Paint(hps, CLEAR_BACKGROUND);
- WinReleasePS(hps);
- }
-
- if (usMsg == WM_BUTTON1DOWN)
- global.clrEditPel = global.clrRenderedObj;
- else
- global.clrEditPel = global.clrField;
-
- GetFatPelFromPt(&ptl, &ptlFat);
- SetFatPel(&ptlFat, global.clrEditPel);
-
- hps = WinGetPS(hwnd);
- Paint(hps, OVERRIDE_RENDERED_OBJ);
- Paint(hps, IGNORED); /* this call just copies fatpels to the s
- WinReleasePS(hps);
- }
- else if (!global.fDraggingControlPoint)
- {
- POINTL ptl;
- SHORT sNewPtGrabbed;
- HPS hps;
-
- global.fDraggingControlPoint = TRUE;
- WinSetCapture(HWND_DESKTOP, hwnd);
-
- ptl.x = (LONG) LOUSHORT(mp1);
- ptl.y = (LONG) HIUSHORT(mp1);
-
- sNewPtGrabbed = IsPtInList(&ptl);
-
- if (global.usMix != FM_XOR)
- {
- hps = WinGetPS(hwnd);
- global.usMix = FM_XOR;
- Paint(hps, CLEAR_BACKGROUND);
- WinReleasePS(hps);
- }
-
- if (usMsg == WM_BUTTON1DOWN) /* add/move point? */
- {
- hps = WinGetPS(hwnd);
-
- if (sNewPtGrabbed != NO_POINT)
- global.sPtGrabbed = sNewPtGrabbed;
- Paint(hps, OVERRIDE_RENDERED_OBJ);
-
- if (sNewPtGrabbed == NO_POINT)
- global.sPtGrabbed = AddPtToList(&ptl);
- else
- global.sPtGrabbed = sNewPtGrabbed;
-
- Paint(hps, CLEAR_FAT_BITMAP|RENDER_MATH_OBJ);
- WinReleasePS(hps);
-
- if (global.sPtGrabbed == NO_POINT)
- MyMessageBox(global.hwnd, "Cannot add any more points.");
- }
- else if (sNewPtGrabbed != NO_POINT)
- global.sPtGrabbed = sNewPtGrabbed;
- }
- }
-
-
-
-
- /************************************************************************
- *
- * GetFatPelFromPt
- *
- ************************************************************************/
-
- VOID
- GetFatPelFromPt(pptl, pptlFat)
- PPOINTL pptl;
- PPOINTL pptlFat;
- {
- pptlFat->x = pptl->x / global.cxFatPel;
- pptlFat->y = pptl->y / global.cyFatPel;
- }
-
-
-
-
- /************************************************************************
- *
- * SetFatPel
- *
- ************************************************************************/
-
- VOID
- SetFatPel(pptl, clr)
- PPOINTL pptl;
- COLOR clr;
- {
- LINEBUNDLE lb;
-
- if (global.hpsFat)
- {
- lb.lColor = clr;
- GpiSetAttrs(global.hpsFat, PRIM_LINE, LBB_COLOR, 0L, &lb);
- GpiSetPel(global.hpsFat, pptl);
- }
- }
-
-
-
-
- /************************************************************************
- *
- * IsPtInList
- *
- ************************************************************************/
-
- SHORT
- IsPtInList(pptl)
- PPOINTL pptl;
- {
- SHORT i;
-
-
- /* try to find pptl in the points we already have */
- for (i = 0; i < (SHORT)global.cptl; ++i)
- if (((L_ABS(pptl->x - global.pptl[i].x)) <= global.lHitPrecision) &&
- ((L_ABS(pptl->y - global.pptl[i].y)) <= global.lHitPrecision))
- return i;
-
- /* couldn't find it */
- return NO_POINT;
- }
-
-
-
-
- /************************************************************************
- *
- * AddPtToList
- *
- ************************************************************************/
-
- SHORT
- AddPtToList(pptl)
- PPOINTL pptl;
- {
- SHORT i, j;
-
- if (global.cptl < CPTLMAX)
- {
- /* check for new points lying on a line segment */
- for (i = 0; i < (SHORT)(global.cptl-1L); ++i)
- if (IsPtCloseToLine(&global.pptl[i], &global.pptl[i+1], pptl))
- {
- /* insert point between endpoints of nearest line segment */
- for (j = (SHORT)global.cptl; j > i+1; --j)
- global.pptl[j] = global.pptl[j - 1];
- global.pptl[i+1] = *pptl;
- ++global.cptl;
- return i+1;
- }
-
- /* append the point */
-
- i = (SHORT) global.cptl;
- global.pptl[i] = *pptl;
- ++global.cptl;
- return i;
- }
-
- return NO_POINT;
- }
-
-
-
-
- /************************************************************************
- *
- * IsPtCloseToLine
- *
- ************************************************************************/
-
- BOOL
- IsPtCloseToLine(pptl1, pptl2, pptlTest)
- PPOINTL pptl1;
- PPOINTL pptl2;
- PPOINTL pptlTest;
- {
- POINTL ptlLL, ptlUR;
- LONG dx, dy, yIntercept, error;
- LONG lBoxAdjustment;
-
-
- /* find the bounding box of the line segment */
-
- ptlLL = *pptl1; /* assume line goes lower left to upper right */
- ptlUR = *pptl2;
- if (pptl1->x > pptl2->x)
- SwapLong(&ptlLL.x, &ptlUR.x);
- if (pptl1->y > pptl2->y)
- SwapLong(&ptlLL.y, &ptlUR.y);
-
-
- /* adjust the bounding box if it's too narrow */
-
- lBoxAdjustment = global.lHitPrecision/2L;
-
- dx = pptl2->x - pptl1->x;
- if (L_ABS(dx) <= global.lHitPrecision)
- {
- ptlLL.x -= lBoxAdjustment;
- ptlUR.x += lBoxAdjustment;
- }
- dy = pptl2->y - pptl1->y;
- if (L_ABS(dy) <= global.lHitPrecision)
- {
- ptlLL.y -= lBoxAdjustment;
- ptlUR.y += lBoxAdjustment;
- }
-
-
- /* see if the test point is in the bounding box of the line segment */
-
- if ((pptlTest->x >= ptlLL.x) &&
- (pptlTest->x <= ptlUR.x) &&
- (pptlTest->y >= ptlLL.y) &&
- (pptlTest->y <= ptlUR.y))
- {
- /* test for special cases */
-
- if (dx == 0) /* vertical line */
- {
- return (L_ABS(pptlTest->x - pptl1->x) <= global.lHitPrecision);
- }
-
- if (dy == 0) /* horizontal line */
- {
- return (L_ABS(pptlTest->y - pptl1->y) <= global.lHitPrecision);
- }
-
-
- /* test for general case */
-
- yIntercept = pptl1->y - (pptl1->x * dy) / dx;
-
- error = pptlTest->y - (pptlTest->x * dy / dx) - yIntercept;
- if (L_ABS(error) <= global.lHitPrecision)
- return TRUE;
- }
-
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * SwapLong
- *
- ************************************************************************/
-
- VOID
- SwapLong(pl1, pl2)
- PLONG pl1, pl2;
- {
- LONG lTmp;
-
- lTmp = *pl1;
- *pl1 = *pl2;
- *pl2 = lTmp;
- }
-
-
-
-
- /************************************************************************
- *
- * DragPelSize
- *
- * Set the dimensions of a fat pel by dragging a rectangle
- * on the screen.
- *
- ************************************************************************/
-
- VOID
- DragPelSize(hwnd, pt)
- HWND hwnd;
- POINTS pt;
- {
- TRACKINFO ti;
-
- WinSendMsg(global.hwndFrame, WM_QUERYTRACKINFO, (MPARAM)TF_MOVE, (MPARAM)
-
- ti.cxBorder = 1;
- ti.cyBorder = 1;
- ti.rclTrack.xLeft = (LONG)pt.x;
- ti.rclTrack.yBottom = (LONG)pt.y;
- ti.rclTrack.xRight = (LONG)pt.x;
- ti.rclTrack.yTop = (LONG)pt.y;
- ti.fs = TF_RIGHT | TF_TOP;
- ti.ptlMinTrackSize.x = 1L;
- ti.ptlMinTrackSize.y = 1L;
-
- if (WinTrackRect(hwnd, NULL, &ti))
- {
- global.cxFatPel = (ti.rclTrack.xRight - ti.rclTrack.xLeft) ;
- global.cyFatPel = (ti.rclTrack.yTop - ti.rclTrack.yBottom);
-
- if (global.cxFatPel < 1L)
- global.cxFatPel = 1L;
-
- if (global.cyFatPel < 1L)
- global.cyFatPel = 1L;
-
- global.cxHalfFatPel = global.cxFatPel / 2L;
- global.cyHalfFatPel = global.cyFatPel / 2L;
-
- UpdateSurfaceDims();
- }
- }
-
-
-
-
- /************************************************************************
- *
- * Close
- *
- ************************************************************************/
-
- VOID
- Close(hwnd)
- HWND hwnd;
- {
- if (global.hptrDragSize)
- WinDestroyPointer(global.hptrDragSize);
- WinPostMsg(hwnd, WM_QUIT, 0L, 0L);
- }
-
-
-
-
- /************************************************************************
- *
- * Command
- *
- * Dispatches menu commands to the proper handlers.
- *
- ************************************************************************/
-
- #define UPDATE_MENU_BOOL(var, val) \
- { \
- TOGGLE_BOOL((var)); \
- TOGGLE_MENU_ITEM(global.hwndFrame, (val), (var)); \
- }
-
- #define UPDATE_MENU_LIST(var, val) \
- { \
- UNCHECK_MENU_ITEM(global.hwndFrame, (var)); \
- (var) = (val); \
- CHECK_MENU_ITEM(global.hwndFrame, (var)); \
- }
-
- VOID
- Command(hwnd, id)
- HWND hwnd;
- USHORT id;
- {
- BOOL fRedraw = FALSE;
- USHORT fsCmd = IGNORED;
-
-
- switch (id)
- {
- case IDM_SAVE:
- SaveWindowToFile(hwnd);
- break;
-
- case IDM_ABOUT:
- WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)AboutDlg, (HMODULE) NULL,
- IDR_ABOUTDLG, NULL );
- break;
-
- case IDM_REDRAW:
- fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;
- break;
-
- case IDM_SETPELSIZE:
- {
- LONG cxFatPel, cyFatPel;
-
- cxFatPel = global.cxFatPel;
- cyFatPel = global.cyFatPel;
-
- if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)PelSizeDlg, (HMODULE) N
- IDR_PELSIZEDLG, NULL ))
- {
- if ((cxFatPel == global.cxFatPel) &&
- (cyFatPel == global.cyFatPel))
- fsCmd = CLEAR_BACKGROUND;
- else
- fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ
- fRedraw = TRUE;
- }
- }
- break;
-
- case IDM_DRAGPELSIZE:
- global.fDraggingPelSize = TRUE;
- break;
-
- case IDM_RENDEREDOBJ:
- UPDATE_MENU_BOOL(global.fDisplayRenderedObj, IDM_RENDEREDOBJ);
- fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;
- fRedraw = TRUE;
- break;
-
- case IDM_MATHOBJ:
- UPDATE_MENU_BOOL(global.fDisplayMathObj, IDM_MATHOBJ);
- fsCmd = CLEAR_BACKGROUND;
- fRedraw = TRUE;
- break;
-
- case IDM_CTLPOINTS:
- UPDATE_MENU_BOOL(global.fDisplayControlPoints, IDM_CTLPOINTS);
- fsCmd = CLEAR_BACKGROUND;
- fRedraw = TRUE;
- break;
-
- case IDM_CROSSHAIRS:
- UPDATE_MENU_BOOL(global.fDisplayCrossHairs, IDM_CROSSHAIRS);
- fsCmd = CLEAR_BACKGROUND;
- fRedraw = TRUE;
- break;
-
- case IDM_PELBORDER:
- UPDATE_MENU_BOOL(global.fDisplayPelBorder, IDM_PELBORDER);
- fsCmd = CLEAR_BACKGROUND;
- fRedraw = TRUE;
- break;
-
- case IDM_ROUNDPOINTS:
- UPDATE_MENU_BOOL(global.fRoundControlPoints, IDM_ROUNDPOINTS);
- fsCmd = CLEAR_BACKGROUND;
- fRedraw = TRUE;
- break;
-
- case IDM_AUTOREDRAW:
- UPDATE_MENU_BOOL(global.fAutoRedraw, IDM_AUTOREDRAW);
- break;
-
- case IDM_NOPRIM:
- case IDM_POLYLINE:
- case IDM_POLYFILLET:
- case IDM_POLYSPLINE:
- case IDM_POINTARC:
- UPDATE_MENU_LIST(global.usCurPrim, id);
- fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;
- fRedraw = TRUE;
- break;
-
- case IDM_SETCOLORS:
- if (WinDlgBox( HWND_DESKTOP, hwnd, (PFNWP)ColorsDlg, (HMODULE) NULL,
- IDR_COLORSDLG, NULL ))
- {
- fsCmd = CLEAR_BACKGROUND|RENDER_MATH_OBJ;
- fRedraw = TRUE;
- }
- break;
-
- case IDM_EDITPELCOLORS:
- UPDATE_MENU_BOOL(global.fEditPelColors, IDM_EDITPELCOLORS);
- break;
-
- case IDM_CLEARALL:
- global.cptl = 0L;
- fsCmd = CLEAR_BACKGROUND|CLEAR_FAT_BITMAP|RENDER_MATH_OBJ;
- fRedraw = TRUE;
- break;
- }
-
- if ((global.fAutoRedraw && fRedraw) || (id == IDM_REDRAW))
- {
- HPS hps;
-
- hps = WinGetPS(hwnd);
- global.usMix = FM_OVERPAINT;
- Paint(hps, fsCmd);
- WinReleasePS(hps);
- }
- }
-
-
-
-
- /************************************************************************
- *
- * Paint
- *
- ************************************************************************/
-
- VOID
- Paint(hps, fsCmd)
- HPS hps;
- USHORT fsCmd;
- {
- HRGN hrgn, hrgnClipOld, hrgnT;
-
-
- /* Clear the unused part of the client rectangle to a hatch pattern. */
- if (fsCmd & CLEAR_BACKGROUND)
- EraseBackground(hps);
-
-
- /* Set up the color mode as the user has requested */
-
- if (global.fRGB)
- {
- GpiCreateLogColorTable(hps, LCOL_RESET, LCOLF_RGB, 0L, 0L, NULL);
- if (global.hpsFat)
- {
- GpiCreateLogColorTable(global.hpsFat, LCOL_RESET, LCOLF_RGB, 0L,
- GpiCreateLogColorTable(global.hpsFatShadow, LCOL_RESET, LCOLF_RGB
- }
- }
- else
- if (global.hpsFat)
- {
- GpiCreateLogColorTable(global.hpsFat, LCOL_RESET, LCOLF_INDRGB, 0
- GpiCreateLogColorTable(global.hpsFatShadow, LCOL_RESET, LCOLF_IND
- global.clrBlackIndex = GpiQueryColorIndex(hps, 0L, 0x000000L);
- }
-
-
- if (global.usPelShape == IDD_CIRCLE)
- {
- ARCPARAMS arcp;
-
- arcp.lP = global.cxFatPel / 2L;
- arcp.lQ = global.cyFatPel / 2L;
- arcp.lR = 0L;
- arcp.lS = 0L;
-
- GpiSetArcParams(hps, &arcp);
- }
-
-
- /* set clipping rectangle to the fatbit surface */
-
- if ((hrgn = GpiCreateRegion(hps, 1L, &global.rcl)) != HRGN_ERROR)
- GpiSetClipRegion(hps, hrgn, &hrgnClipOld);
-
-
- if (fsCmd & CLEAR_BACKGROUND)
- {
- DrawGrid(hps);
-
- if (global.hpsFatShadow)
- {
- AREABUNDLE ab;
-
- /* clear shadow fatpel surface to background color */
- ab.lColor = global.clrField;
- GpiSetAttrs(global.hpsFatShadow, PRIM_AREA, ABB_COLOR, 0L, &ab);
- GpiBitBlt(global.hpsFatShadow, NULL, 2L, (PPOINTL)&global.rclFat,
- }
- }
-
- if (global.fDisplayRenderedObj && !(fsCmd & OVERRIDE_RENDERED_OBJ))
- DisplayRenderedPels(hps, fsCmd);
-
- if (global.fDisplayControlPoints)
- {
- /* when rubberbanding with the rendered obj, newly drawn fatpels
- * can wipe out stationary control point markers, so we have to
- * redraw them all each time
- */
-
- if (global.fDisplayRenderedObj || (fsCmd & CLEAR_BACKGROUND))
- DisplayControlPoints(hps, global.cptl, global.pptl, global.usMix)
- else if (global.sPtGrabbed != NO_POINT)
- /* draw just the control point that moved */
- DisplayControlPoints(hps, 1L, global.pptl+global.sPtGrabbed, glob
- }
-
- if (global.fDisplayMathObj)
- DisplayMathematicalObject(hps, global.usMix);
-
- /* delete the clip region we set up */
-
- if (hrgnClipOld != HRGN_ERROR)
- GpiSetClipRegion(hps, hrgnClipOld, &hrgnT);
- if (hrgn != HRGN_ERROR)
- GpiDestroyRegion(hps, hrgn);
- }
-
-
-
-
- /************************************************************************
- *
- * DisplayMathematicalObject
- *
- ************************************************************************/
-
- VOID
- DisplayMathematicalObject(hps, usMix)
- HPS hps;
- USHORT usMix;
- {
- PPOINTL pptl;
- LINEBUNDLE lb;
-
- if (global.cptl > 0)
- {
- if (global.fRoundControlPoints)
- {
- RoundControlPoints(hps, global.cptl, global.pptl, global.pptlTmp,
- global.cxFatPel, global.cyFatPel);
- pptl = global.pptlTmp;
- }
- else
- pptl = global.pptl;
-
- /* draw line */
- lb.lColor = global.clrMathObj;
- lb.usMixMode = usMix;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR|LBB_MIX_MODE, 0L, &lb);
- DrawPrimitive(hps, global.cptl, pptl);
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DisplayControlPoints
- *
- ************************************************************************/
-
- VOID
- DisplayControlPoints(hps, cptl, pptl, usMix)
- HPS hps;
- LONG cptl;
- PPOINTL pptl;
- USHORT usMix;
- {
- PPOINTL pptlT;
- MARKERBUNDLE mb;
-
- if (cptl > 0)
- {
- if (global.fRoundControlPoints)
- {
- RoundControlPoints(hps, cptl, pptl, global.pptlTmp,
- global.cxFatPel, global.cyFatPel);
- pptlT = global.pptlTmp;
- }
- else
- pptlT = pptl;
-
-
- mb.lColor = global.clrControlPoints;
- mb.usMixMode = usMix;
- mb.usSymbol = global.usControlPointSymbol;
- GpiSetAttrs(hps, PRIM_MARKER, MBB_COLOR|MBB_MIX_MODE|MBB_SYMBOL, 0L,
-
- GpiPolyMarker(hps, cptl, pptlT);
- }
- }
-
-
-
-
- /************************************************************************
- *
- * EraseBackground
- *
- * Erase the unused part of the window to a hatch pattern.
- *
- ************************************************************************/
-
- VOID
- EraseBackground(hps)
- HPS hps;
- {
- RECTL rclClient, rclT;
- AREABUNDLE ab;
-
-
- WinQueryWindowRect(global.hwnd, &rclClient);
-
- ab.lColor = CLR_BLACK;
- ab.lBackColor = CLR_WHITE;
- ab.usSymbol = PATSYM_DIAG1;
- GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR|ABB_BACK_COLOR|ABB_SYMBOL,
- 0L, (PBUNDLE)&ab);
-
- if (global.rcl.yTop < rclClient.yTop)
- {
- rclT.xLeft = rclClient.xLeft;
- rclT.yBottom = global.rcl.yBottom;
- rclT.xRight = rclClient.xRight;
- rclT.yTop = rclClient.yTop;
- GpiBitBlt(hps, NULL, 2L, (PPOINTL)&rclT, ROP_PATCOPY, (ULONG) 0);
- }
-
- if (global.rcl.xRight < rclClient.xRight)
- {
- rclT.xLeft = global.rcl.xRight;
- rclT.yBottom = rclClient.yBottom;
- rclT.xRight = rclClient.xRight;
- rclT.yTop = global.rcl.yTop;
- GpiBitBlt(hps, NULL, 2L, (PPOINTL)&rclT, ROP_PATCOPY, (ULONG) 0);
- }
-
- ab.usSymbol = PATSYM_SOLID;
- GpiSetAttrs(hps, PRIM_AREA, ABB_SYMBOL, 0L, (PBUNDLE)&ab);
- }
-
-
-
-
- /************************************************************************
- *
- * DrawGrid
- *
- ************************************************************************/
-
- VOID
- DrawGrid(hps)
- HPS hps;
- {
- AREABUNDLE ab;
- POINTL ptl;
- POINTL aptl[3];
-
-
- /* clear fatpel surface to background color */
- ab.lColor = global.clrInterstice;
- GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR, 0L, &ab);
- GpiBitBlt(hps, NULL, 2L, (PPOINTL)&global.rcl, ROP_PATCOPY, (ULONG) 0);
-
-
- /* draw one pel in lower left corner */
-
- ptl.x = global.cxFatPel / 2L;
- ptl.y = global.cyFatPel / 2L;
- DrawOneFatPel(hps, &ptl, global.clrField);
-
-
- /* blt up first column then across -- we don't have to worry
- * about the edges because a clip region has been setup to do that.
- */
-
- aptl[0].x = 0L;
- aptl[0].y = global.cyFatPel;
- aptl[1].x = global.cxFatPel;
- aptl[2].x = 0L;
- aptl[2].y = 0L;
-
- while (aptl[0].y <= global.rcl.yTop)
- {
- aptl[1].y = aptl[0].y + aptl[0].y;
- GpiBitBlt(hps, hps, 3L, aptl, ROP_SRCCOPY, (LONG)NULL);
- aptl[0].y += aptl[1].y - aptl[0].y;
- }
-
- aptl[0].x = global.cxFatPel;
- aptl[0].y = 0L;
- aptl[1].y = global.rcl.yTop;
- aptl[2].x = 0L;
- aptl[2].y = 0L;
-
- while (aptl[0].x <= global.rcl.xRight)
- {
- aptl[1].x = aptl[0].x + aptl[0].x;
- GpiBitBlt(hps, hps, 3L, aptl, ROP_SRCCOPY, (LONG)NULL);
- aptl[0].x += aptl[1].x - aptl[0].x;
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DisplayRenderedPels
- *
- ************************************************************************/
-
- VOID
- DisplayRenderedPels(hps, fsCmd)
- HPS hps;
- USHORT fsCmd;
- {
- LINEBUNDLE lb;
- AREABUNDLE ab;
- POINTL aptl[3];
-
- /* Call GPI to draw the current primitive into the small bitmap,
- * then fatbit it to the display.
- */
-
- if (global.hbmFat)
- {
- if (fsCmd & CLEAR_FAT_BITMAP)
- {
- /* clear fatpel surface to background color */
- ab.lColor = global.clrField;
- GpiSetAttrs(global.hpsFat, PRIM_AREA, ABB_COLOR, 0L, &ab);
- GpiBitBlt(global.hpsFat, NULL, 2L, (PPOINTL)&global.rclFat, ROP_P
- }
-
- if (fsCmd & RENDER_MATH_OBJ)
- {
- if (global.cptl > 0)
- {
- /* draw line */
- lb.lColor = global.clrRenderedObj;
- GpiSetAttrs(global.hpsFat, PRIM_LINE, LBB_COLOR, 0L, &lb);
- GpiSetModelTransformMatrix(global.hpsFat, 9L,
- &global.matlf, TRANSFORM_REPLACE);
- DrawPrimitive(global.hpsFat, global.cptl, global.pptl);
- GpiSetModelTransformMatrix(global.hpsFat, 0L, NULL, TRANSFORM
- }
- }
-
- /* xor the new rendered bitmap into the shadow bitmap */
- *((PRECTL)&aptl[0]) = global.rclFat;
- aptl[2].x = 0L;
- aptl[2].y = 0L;
- GpiBitBlt(global.hpsFatShadow, global.hpsFat, 3L, aptl, ROP_SRCINVERT
-
- /* fatbit object to the display */
- DrawFatPels(hps);
-
- /* get the new shadow bitmap */
- GpiBitBlt(global.hpsFatShadow, global.hpsFat, 3L, aptl, ROP_SRCCOPY,
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawFatPels
- *
- ************************************************************************/
-
- VOID
- DrawFatPels(hps)
- HPS hps;
- {
- POINTL ptl, ptlCenter;
- LONG i, j;
- COLOR clr;
-
-
- /* if the pel size is 1,1, then just blt the small bitmap to the
- * display.
- */
-
- if ((global.cxFatPel == 1L) && (global.cyFatPel == 1L))
- {
- POINTL aptl[3];
-
- *((PRECTL)&aptl[0]) = global.rcl;
- aptl[2].x = 0L;
- aptl[2].y = 0L;
- GpiBitBlt(hps, global.hpsFat, 3L, aptl, ROP_SRCCOPY, 0L);
-
- return;
- }
-
- for (i = 0; i < global.rclFat.xRight; ++i)
- for (j = 0; j < global.rclFat.yTop; ++j)
- {
- ptl.x = i;
- ptl.y = j;
-
- clr = GpiQueryPel(global.hpsFatShadow, &ptl);
- if ((global.fRGB && (clr != 0x000000L)) ||
- (!global.fRGB && (clr != global.clrBlackIndex)))
- {
- clr = GpiQueryPel(global.hpsFat, &ptl);
- ptlCenter.x = (i * global.cxFatPel) + global.cxHalfFatPel;
- ptlCenter.y = (j * global.cyFatPel) + global.cyHalfFatPel;
- DrawOneFatPel(hps, &ptlCenter, clr);
- }
- }
- }
-
-
-
-
- /************************************************************************
- *
- * DrawOneFatPel
- *
- ************************************************************************/
-
- VOID
- DrawOneFatPel(hps, pptl, clr)
- HPS hps;
- PPOINTL pptl;
- COLOR clr;
- {
- POINTL ptl;
- LINEBUNDLE lb;
- AREABUNDLE ab;
-
-
- if (global.fDisplayPelBorder || global.fDisplayCrossHairs)
- {
- lb.lColor = global.clrCrossHair;
- GpiSetAttrs(hps, PRIM_LINE, LBB_COLOR, 0L, &lb);
- }
-
- ab.lColor = clr;
- GpiSetAttrs(hps, PRIM_AREA, ABB_COLOR, 0L, &ab);
-
-
- switch (global.usPelShape)
- {
- case IDD_SQUARE:
- {
- POINTL ptlT;
- ULONG flCmd;
-
- if (global.fDisplayPelBorder)
- flCmd = DRO_OUTLINEFILL;
- else
- flCmd = DRO_FILL;
-
- ptlT.x = pptl->x - global.cxHalfFatPel;
- ptlT.y = pptl->y - global.cyHalfFatPel;
- GpiSetCurrentPosition(hps, &ptlT);
- ptlT.x = pptl->x + global.cxHalfFatPel;
- ptlT.y = pptl->y + global.cyHalfFatPel;
- GpiBox(hps, flCmd, &ptlT, 0L, 0L);
- }
- break;
-
- case IDD_DIAMOND:
- {
- POINTL aptlT[4];
- ULONG flCmd;
-
- if (global.fDisplayPelBorder)
- flCmd = BA_BOUNDARY;
- else
- flCmd = 0L;
-
- aptlT[0].x = pptl->x;
- aptlT[0].y = pptl->y - global.cyHalfFatPel;
- aptlT[1].x = pptl->x - global.cxHalfFatPel;
- aptlT[1].y = pptl->y;
- aptlT[2].x = pptl->x;
- aptlT[2].y = pptl->y + global.cyHalfFatPel;
- aptlT[3].x = pptl->x + global.cxHalfFatPel;
- aptlT[3].y = pptl->y;
-
- GpiSetCurrentPosition(hps, &aptlT[3]);
- GpiBeginArea(hps, flCmd);
- GpiPolyLine(hps, 4L, aptlT);
- GpiEndArea(hps);
- }
-
- break;
-
- case IDD_CIRCLE:
- {
- ULONG flCmd;
-
- if (global.fDisplayPelBorder)
- flCmd = DRO_OUTLINEFILL;
- else
- flCmd = DRO_FILL;
-
- GpiSetCurrentPosition(hps, pptl);
- GpiFullArc(hps, flCmd, 0x10000L);
- }
- break;
- }
-
-
- if (global.fDisplayCrossHairs)
- {
- /* draw cross in center of pel */
-
- ptl.x = pptl->x - global.cxHalfFatPel;
- ptl.y = pptl->y;
- GpiSetCurrentPosition(hps, &ptl);
- ptl.x = pptl->x + global.cxHalfFatPel;
- GpiPolyLine(hps, 1L, &ptl);
-
- ptl.x = pptl->x;
- ptl.y = pptl->y - global.cyHalfFatPel;
- GpiSetCurrentPosition(hps, &ptl);
- ptl.y = pptl->y + global.cyHalfFatPel;
- GpiPolyLine(hps, 1L, &ptl);
- }
- }
-
-
-
-
- /************************************************************************
- *
- * RoundControlPoints
- *
- ************************************************************************/
-
- VOID
- RoundControlPoints(hps, cptl, pptl1, pptl2, cx, cy)
- HPS hps;
- LONG cptl;
- PPOINTL pptl1;
- PPOINTL pptl2;
- LONG cx;
- LONG cy;
- {
- LONG cx2, cy2;
- LONG i;
- MATRIXLF matlf;
-
-
- /* copy the input buffer to the output/scratch buffer */
- for (i = 0; i < cptl; ++i)
- pptl2[i] = pptl1[i];
-
-
- /* set the transform, transform the points to device space (i.e. to
- * hpsFat dimensions), then restore the original transform
- */
- GpiQueryModelTransformMatrix(hps, 9L, &matlf);
- GpiSetModelTransformMatrix(hps, 9L, &global.matlf, TRANSFORM_REPLACE);
- GpiConvert(hps, CVTC_WORLD, CVTC_DEVICE, cptl, pptl2);
- GpiSetModelTransformMatrix(hps, 9L, &matlf, TRANSFORM_REPLACE);
-
-
- /* position each point in the center of its fatpel */
-
- cx2 = cx / 2L;
- cy2 = cy / 2L;
-
- for (i = 0; i < cptl; ++i, ++pptl2)
- {
- pptl2->x = pptl2->x * cx + cx2;
- pptl2->y = pptl2->y * cy + cy2;
- }
- }
-
-
-
-
- /************************************************************************
- *
- * ComputeTransform
- *
- ************************************************************************/
-
- VOID
- ComputeTransform(prcl1, prcl2)
- PRECTL prcl1;
- PRECTL prcl2;
- {
- LONG xExt1, yExt1;
- LONG xExt2, yExt2;
- FIXED xScale, yScale;
-
-
- xExt1 = prcl1->xRight - prcl1->xLeft;
- yExt1 = prcl1->yTop - prcl1->yBottom;
- xExt2 = prcl2->xRight - prcl2->xLeft;
- yExt2 = prcl2->yTop - prcl2->yBottom;
-
-
- /* If the rectangles are of exactly the same dimensions, then
- * set the unity transform. If not, compute the x and y scale
- * factors. Note that in world coordinates rectangles are
- * inclusive-inclusive, whereas in device coordinates they are
- * inclusive-exclusive. The extents of the destination are
- * therefore one pel too large as computed, so we subtract one
- * in the scale factor computation.
- */
-
- if (xExt1 == xExt2)
- xScale = 0x10000L;
- else
- xScale = ((xExt2-1L) * 0x10000L) / xExt1;
-
- if (yExt1 == yExt2)
- yScale = 0x10000L;
- else
- yScale = ((yExt2-1L) * 0x10000L) / yExt1;
-
-
- /* store the transform matrix for easy access */
-
- global.matlf.fxM11 = xScale;
- global.matlf.fxM12 = 0L;
- global.matlf. lM13 = 0L;
- global.matlf.fxM21 = 0L;
- global.matlf.fxM22 = yScale;
- global.matlf. lM23 = 0L;
- global.matlf. lM31 = 0L;
- global.matlf. lM32 = 0L;
- global.matlf. lM33 = 1L;
- }
-
-
-
-
- /************************************************************************
- *
- * DrawPrimitive
- *
- ************************************************************************/
-
- VOID
- DrawPrimitive(hps, cptl, pptl)
- HPS hps;
- LONG cptl;
- PPOINTL pptl;
- {
- switch (global.usCurPrim)
- {
- case IDM_NOPRIM:
- break;
-
- case IDM_POLYLINE:
- GpiSetCurrentPosition(hps, pptl);
- GpiPolyLine(hps, cptl-1L, pptl + 1);
- break;
-
- case IDM_POLYFILLET:
- if (cptl >= 3L)
- {
- GpiSetCurrentPosition(hps, pptl);
- GpiPolyFillet(hps, cptl-1L, pptl + 1);
- }
- break;
-
- case IDM_POLYSPLINE:
- if (cptl >= 4L)
- {
- LONG cptSlack; /* # points in pptl not usable by PolySpline */
-
- cptSlack = ((cptl-1L) % 3) + 1;
- GpiSetCurrentPosition( hps, pptl );
- GpiPolySpline( hps, cptl-cptSlack, pptl+1 );
- }
- break;
-
- case IDM_POINTARC:
- if (cptl >= 3L)
- {
- GpiSetCurrentPosition( hps, pptl );
- GpiPointArc( hps, pptl+1 );
- }
- break;
- }
- }
-
-
-
-
- /************************************************************************
- *
- * UpdateSurfaceDims
- *
- ************************************************************************/
-
- VOID
- UpdateSurfaceDims()
- {
- SIZEL size;
- BITMAPINFOHEADER bminfo;
- AREABUNDLE ab;
-
-
- WinQueryWindowRect(global.hwnd, &global.rcl);
-
- /* compute size of small surface */
- global.rclFat.xLeft = 0L;
- global.rclFat.yBottom = 0L;
- global.rclFat.xRight = global.rcl.xRight / global.cxFatPel;
- global.rclFat.yTop = global.rcl.yTop / global.cyFatPel;
-
- /* compute size of fatpel version of small surface */
- global.rcl.xLeft = 0L;
- global.rcl.yBottom = 0L;
- global.rcl.xRight = global.rclFat.xRight * global.cxFatPel;
- global.rcl.yTop = global.rclFat.yTop * global.cyFatPel;
-
- ComputeTransform(&global.rcl, &global.rclFat);
-
- if ((global.rclFat.xRight <= global.rclFatBM.xRight) &&
- (global.rclFat.yTop <= global.rclFatBM.yTop))
- return;
-
-
-
- /* The new fatbits surface doesn't fit in the bitmap, so we
- * have to make a new one. If we don't have a DC or PS, make
- * those before making the bitmap. If we do have a bitmap,
- * delete it before making the new one.
- */
-
- global.rclFatBM = global.rclFat;
-
- if (global.hbmFat)
- {
- GpiSetBitmap(global.hpsFat, NULL);
- GpiDeleteBitmap(global.hbmFat);
- GpiSetBitmap(global.hpsFatShadow, NULL);
- GpiDeleteBitmap(global.hbmFatShadow);
- }
-
- if (!global.hdcFat)
- {
- global.hdcFat = DevOpenDC(global.hab, OD_MEMORY, "*", 0L, NULL, NULL)
- if (!global.hdcFat)
- goto usd_error;
-
- global.hdcFatShadow = DevOpenDC(global.hab, OD_MEMORY, "*", 0L, NULL,
- if (!global.hdcFatShadow)
- goto usd_error;
- }
-
- if (!global.hpsFat)
- {
- size.cx = 0L;
- size.cy = 0L;
- global.hpsFat = GpiCreatePS(global.hab, global.hdcFat, &size,
- PU_PELS|GPIT_MICRO|GPIA_ASSOC);
- if (!global.hpsFat)
- goto usd_error;
-
- global.hpsFatShadow = GpiCreatePS(global.hab, global.hdcFatShadow, &s
- PU_PELS|GPIT_MICRO|GPIA_ASSOC);
- if (!global.hpsFatShadow)
- goto usd_error;
- }
-
- /* create bitmap with maximum color resolution (24-bit color) */
- bminfo.cbFix = sizeof(BITMAPINFOHEADER);
- bminfo.cx = (USHORT) (global.rclFatBM.xRight - global.rclFatBM.xLeft);
- bminfo.cy = (USHORT) (global.rclFatBM.yTop - global.rclFatBM.yBot
- bminfo.cPlanes = 1L;
- bminfo.cBitCount = 24L;
- global.hbmFat = GpiCreateBitmap(global.hpsFat, &bminfo, 0L, 0L, 0L);
- if (!global.hbmFat)
- goto usd_error;
- GpiSetBitmap(global.hpsFat, global.hbmFat);
-
- /* create a shadow bitmap of the one we just created */
- bminfo.cbFix = sizeof(BITMAPINFOHEADER);
- bminfo.cx = (USHORT) (global.rclFatBM.xRight - global.rclFatBM.xLeft);
- bminfo.cy = (USHORT) (global.rclFatBM.yTop - global.rclFatBM.yBot
- bminfo.cPlanes = 1L;
- bminfo.cBitCount = 24L;
- global.hbmFatShadow = GpiCreateBitmap(global.hpsFatShadow, &bminfo, 0L, 0
- if (!global.hbmFat)
- goto usd_error;
- GpiSetBitmap(global.hpsFatShadow, global.hbmFatShadow);
-
- /* clear bitmap surface to field color */
- ab.lColor = global.clrField;
- GpiSetAttrs(global.hpsFat, PRIM_AREA, ABB_COLOR, 0L, &ab);
- GpiBitBlt(global.hpsFat, NULL, 2L, (PPOINTL)&global.rclFat, ROP_PATCOPY,
-
- return;
-
-
- /* error exit point */
-
- usd_error:
- if (global.hpsFat)
- GpiDestroyPS(global.hpsFat);
- if (global.hpsFatShadow)
- GpiDestroyPS(global.hpsFatShadow);
- if (global.hdcFat)
- DevCloseDC(global.hdcFat);
- if (global.hdcFatShadow)
- DevCloseDC(global.hdcFatShadow);
-
- global.hpsFat = NULL;
- global.hdcFat = NULL;
- global.hpsFatShadow = NULL;
- global.hdcFatShadow = NULL;
- }
-
-
-
-
- /************************************************************************
- *
- * AboutDlg
- *
- * Process messages for the About box.
- *
- ************************************************************************/
-
- ULONG CALLBACK
- AboutDlg(hwnd, usMsg, mp1, mp2)
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch (usMsg)
- {
- case WM_COMMAND:
- if (SHORT1FROMMP(mp1) == DID_OK)
- WinDismissDlg(hwnd, TRUE);
- else
- return FALSE;
- break;
-
- default:
- return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);
- }
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * PelSizeDlg
- *
- * Process messages for the Pel Size dialog box.
- *
- ************************************************************************/
-
- ULONG CALLBACK
- PelSizeDlg(hwnd, usMsg, mp1, mp2)
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- MPARAM mp2;
- {
- BOOL fRet = FALSE;
-
- switch (usMsg)
- {
- case WM_INITDLG:
- MySetWindowLong(hwnd, IDD_PELWIDTH, global.cxFatPel);
- MySetWindowLong(hwnd, IDD_PELHEIGHT, global.cyFatPel);
- WinSendDlgItemMsg(hwnd, global.usPelShape,
- BM_SETCHECK, (MPARAM)TRUE, 0L);
- return FALSE;
- break;
-
- case WM_COMMAND:
- switch (SHORT1FROMMP(mp1))
- {
- case IDD_OK:
- global.cxFatPel = MyGetWindowLong(hwnd, IDD_PELWIDTH);
- global.cyFatPel = MyGetWindowLong(hwnd, IDD_PELHEIGHT);
-
- if (global.cxFatPel < 1L)
- global.cxFatPel = 1L;
-
- if (global.cyFatPel < 1L)
- global.cyFatPel = 1L;
-
- global.cxHalfFatPel = global.cxFatPel / 2L;
- global.cyHalfFatPel = global.cyFatPel / 2L;
-
- global.usPelShape = SHORT1FROMMR( WinSendDlgItemMsg(hwnd, IDD_SQU
- BM_QUERYCHECKINDEX, 0L, 0L) + IDD_SQUARE);
-
-
- UpdateSurfaceDims();
-
- fRet = TRUE;
-
- /* fall through to some common code */
-
- case IDD_CANCEL:
- WinDismissDlg(hwnd, fRet);
- break;
-
- default:
- return FALSE;
- }
- break;
-
- default:
- return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);
- }
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * ColorsDlg
- *
- * Process messages for the Set Colors dialog box.
- *
- ************************************************************************/
-
- ULONG CALLBACK
- ColorsDlg(hwnd, usMsg, mp1, mp2)
- HWND hwnd;
- USHORT usMsg;
- MPARAM mp1;
- MPARAM mp2;
- {
- BOOL fRet = FALSE;
- BOOL fRGB;
- COLOR clrMathObj;
- COLOR clrRenderedObj;
- COLOR clrField;
- COLOR clrCrossHair;
- COLOR clrInterstice;
- COLOR clrControlPoints;
-
- switch (usMsg)
- {
- case WM_INITDLG:
- if (global.fRGB)
- {
- MySetWindowLongHex(hwnd, IDD_MATHOBJ, global.clrMathObj);
- MySetWindowLongHex(hwnd, IDD_RENDEREDOBJ, global.clrRenderedObj);
- MySetWindowLongHex(hwnd, IDD_FIELD, global.clrField);
- MySetWindowLongHex(hwnd, IDD_CROSSHAIRS, global.clrCrossHair);
- MySetWindowLongHex(hwnd, IDD_INTERSTICE, global.clrInterstice);
- MySetWindowLongHex(hwnd, IDD_CTLPOINTS, global.clrControlPoints
- }
- else
- {
- MySetWindowLong (hwnd, IDD_MATHOBJ, global.clrMathObj);
- MySetWindowLong (hwnd, IDD_RENDEREDOBJ, global.clrRenderedObj);
- MySetWindowLong (hwnd, IDD_FIELD, global.clrField);
- MySetWindowLong (hwnd, IDD_CROSSHAIRS, global.clrCrossHair);
- MySetWindowLong (hwnd, IDD_INTERSTICE, global.clrInterstice);
- MySetWindowLong (hwnd, IDD_CTLPOINTS, global.clrControlPoints
- }
- WinSendDlgItemMsg(hwnd, IDD_RGB, BM_SETCHECK, MPFROM2SHORT(global.fRG
- return FALSE;
- break;
-
- case WM_CONTROL:
- if ((SHORT1FROMMP(mp1) == IDD_RGB) && (SHORT2FROMMP(mp1)== BN_CLICKED
- {
- fRGB = !SHORT1FROMMR(WinSendDlgItemMsg(hwnd, IDD_RGB, BM_QUERYCHE
- WinSendDlgItemMsg(hwnd, IDD_RGB, BM_SETCHECK, MPFROM2SHORT(fRGB,0
-
- clrMathObj = MyGetWindowLong(hwnd, IDD_MATHOBJ);
- clrRenderedObj = MyGetWindowLong(hwnd, IDD_RENDEREDOBJ);
- clrField = MyGetWindowLong(hwnd, IDD_FIELD);
- clrCrossHair = MyGetWindowLong(hwnd, IDD_CROSSHAIRS);
- clrInterstice = MyGetWindowLong(hwnd, IDD_INTERSTICE);
- clrControlPoints = MyGetWindowLong(hwnd, IDD_CTLPOINTS);
-
- if (fRGB)
- {
- HPS hps;
-
- /* for each color, get rgb value from index */
-
- hps = WinGetPS(hwnd);
-
- clrMathObj = GpiQueryRGBColor(hps, 0L, clrMathObj);
- clrRenderedObj = GpiQueryRGBColor(hps, 0L, clrRendere
- clrField = GpiQueryRGBColor(hps, 0L, clrField);
- clrCrossHair = GpiQueryRGBColor(hps, 0L, clrCrossHair
- clrInterstice = GpiQueryRGBColor(hps, 0L, clrIntersti
- clrControlPoints = GpiQueryRGBColor(hps, 0L, clrControlPoints
-
- WinReleasePS(hps);
-
- MySetWindowLongHex(hwnd, IDD_MATHOBJ, clrMathObj);
- MySetWindowLongHex(hwnd, IDD_RENDEREDOBJ, clrRenderedObj);
- MySetWindowLongHex(hwnd, IDD_FIELD, clrField);
- MySetWindowLongHex(hwnd, IDD_CROSSHAIRS, clrCrossHair);
- MySetWindowLongHex(hwnd, IDD_INTERSTICE, clrInterstice);
- MySetWindowLongHex(hwnd, IDD_CTLPOINTS, clrControlPoi
- }
- else
- {
- HPS hps;
-
- /* for each color, get nearest index value from rgb */
-
- hps = WinGetPS(hwnd);
-
- clrMathObj = GpiQueryColorIndex(hps, 0L, clrMathObj);
- clrRenderedObj = GpiQueryColorIndex(hps, 0L, clrRende
- clrField = GpiQueryColorIndex(hps, 0L, clrField);
- clrCrossHair = GpiQueryColorIndex(hps, 0L, clrCrossHa
- clrInterstice = GpiQueryColorIndex(hps, 0L, clrInters
- clrControlPoints = GpiQueryColorIndex(hps, 0L, clrControlPoin
-
- WinReleasePS(hps);
-
- MySetWindowLong (hwnd, IDD_MATHOBJ, clrMathObj);
- MySetWindowLong (hwnd, IDD_RENDEREDOBJ, clrRenderedObj);
- MySetWindowLong (hwnd, IDD_FIELD, clrField);
- MySetWindowLong (hwnd, IDD_CROSSHAIRS, clrCrossHair);
- MySetWindowLong (hwnd, IDD_INTERSTICE, clrInterstice);
- MySetWindowLong (hwnd, IDD_CTLPOINTS, clrControlPoi
- }
- }
- return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);
- break;
-
- case WM_COMMAND:
- switch (SHORT1FROMMP(mp1))
- {
- case IDD_OK:
- global.clrMathObj = MyGetWindowLong(hwnd, IDD_MATHOBJ)
- global.clrRenderedObj = MyGetWindowLong(hwnd, IDD_RENDEREDOBJ);
- global.clrField = MyGetWindowLong(hwnd, IDD_FIELD);
- global.clrCrossHair = MyGetWindowLong(hwnd, IDD_CROSSHAIRS);
- global.clrInterstice = MyGetWindowLong(hwnd, IDD_INTERSTICE);
- global.clrControlPoints = MyGetWindowLong(hwnd, IDD_CTLPOINTS);
-
- global.fRGB = SHORT1FROMMR(WinSendDlgItemMsg(hwnd, IDD_RGB, BM_QU
-
- fRet = TRUE;
-
- /* fall through to some common code */
-
- case IDD_CANCEL:
- WinDismissDlg(hwnd, fRet);
- break;
-
- default:
- return FALSE;
- }
- break;
-
- default:
- return (ULONG) WinDefDlgProc(hwnd, usMsg, mp1, mp2);
- }
- return FALSE;
- }
-
-
-
-
- /************************************************************************
- *
- * MySetWindowLong
- *
- * Sets the given control id to the value specified.
- *
- ************************************************************************/
-
- VOID
- MySetWindowLong(hWnd, id, num)
- HWND hWnd;
- USHORT id;
- LONG num;
- {
- char szStr[CCHSTR];
-
- sprintf((NPCH)szStr, "%ld", num);
- WinSetWindowText(WinWindowFromID(hWnd, id), (PCH)szStr);
- }
-
-
-
-
- /************************************************************************
- *
- * MySetWindowLongHex
- *
- * Sets the given control id to the value specified, in hexadecimal
- * notation.
- *
- ************************************************************************/
-
- VOID
- MySetWindowLongHex(hWnd, id, num)
- HWND hWnd;
- USHORT id;
- LONG num;
- {
- char szStr[CCHSTR];
-
- sprintf((NPCH)szStr, "0x%06lX", num);
- WinSetWindowText(WinWindowFromID(hWnd, id), (PCH)szStr);
- }
-
-
-
-
- /************************************************************************
- *
- * MyGetWindowLong
- *
- * Returns the value from the given control id.
- *
- ************************************************************************/
-
- LONG
- MyGetWindowLong(hWnd, id)
- HWND hWnd;
- USHORT id;
- {
- char szStr[CCHSTR];
- LONG num;
-
- WinQueryWindowText(WinWindowFromID(hWnd, id), CCHSTR, (PCH)szStr);
-
- if (strchr(szStr, 'x'))
- sscanf((NPCH)szStr, "0x%lx", &num);
- else if (strchr(szStr, 'X'))
- sscanf((NPCH)szStr, "0X%lx", &num);
- else
- sscanf((NPCH)szStr, "%ld", &num);
-
- return num;
- }
-
-
-
-
- /************************************************************************
- *
- * SaveWindowToFile
- *
- * Copy the bits from the client rectangle (actually, just the fatpel
- * area) into a bitmap, then save that bitmap.
- *
- ************************************************************************/
-
- VOID
- SaveWindowToFile(hwnd)
- HWND hwnd;
- {
- BITMAPINFOHEADER bminfo;
- HBITMAP hbm;
- HPS hps;
- POINTL aptl[3];
-
- /* create bitmap in display's favorite format */
- bminfo.cbFix = sizeof(BITMAPINFOHEADER);
- bminfo.cx = (USHORT) (global.rcl.xRight - global.rcl.xLeft);
- bminfo.cy = (USHORT) (global.rcl.yTop - global.rcl.yBottom);
- bminfo.cPlanes = 0L;
- bminfo.cBitCount = 0L;
- if (hbm = GpiCreateBitmap(global.hpsFat, &bminfo, 0L, 0L, 0L))
- {
- /* select it into the small bitmap's PS */
- GpiSetBitmap(global.hpsFat, hbm);
-
- /* GpiBitBlt from the window to the bitmap */
- hps = WinGetPS(hwnd);
-
- *((PRECTL)&aptl[0]) = global.rcl;
- aptl[2].x = 0L;
- aptl[2].y = 0L;
- GpiBitBlt(global.hpsFat, hps, 3L, aptl, ROP_SRCCOPY, 0L);
-
- WinReleasePS(hps);
-
- /* save the bitmap */
- WriteFile(hwnd, global.hpsFat);
- }
-
- /* deselect the bitmap and delete it */
- GpiSetBitmap(global.hpsFat, global.hbmFat);
- if (hbm)
- GpiDeleteBitmap(hbm);
- }
-
-
-
-
- /************************************************************************
- *
- * WriteFile
- *
- * Calls the OpenDlg's DlgFile function to ask the user what file name to
- * save under.
- *
- ************************************************************************/
-
- VOID
- WriteFile(hwnd, hps)
- HWND hwnd;
- HPS hps;
- {
- HFILE hfile;
- DLF dlf;
- BITMAPINFOHEADER bmih;
-
- dlf.rgbAction = DLG_SAVEDLG;
- dlf.rgbFlags = 0;
- dlf.phFile = &hfile;
- dlf.pszExt = "";
- dlf.pszAppName = "FatPel";
- dlf.pszInstructions = NULL;
- dlf.szFileName[0] = '\0';
- dlf.szOpenFile[0] = '\0';
- dlf.pszTitle = "Save Bitmap";
-
-
- switch (DlgFile(hwnd,&dlf))
- {
- case TDF_ERRMEM:
- case TDF_INVALID:
- MyMessageBox(hwnd, "Error opening file.");
- break;
-
- case TDF_NOSAVE:
- break;
-
- default:
- bmih.cbFix = sizeof(BITMAPINFOHEADER);
- bmih.cx = (USHORT) global.rcl.xRight;
- bmih.cy = (USHORT) global.rcl.yTop;
- bmih.cPlanes = 0L;
- bmih.cBitCount = 0L;
-
- if (!WriteBMP(hfile, hps, &bmih))
- MyMessageBox(hwnd, "Error writing file.");
- }
- }
-
-
-
-
- /************************************************************************
- *
- * WriteBMP
- *
- * Write the bitmap out to a BMP format file. Write the file
- * header first, then the bitmap bits. Space for the header
- * and the bits is allocated. Huge bitmaps are supported.
- * Free up memory and close the file before leaving. The file
- * will have been opened by the time this function is called,
- * and the file handle will be in the *pdlf structure.
- *
- ************************************************************************/
-
- BOOL
- WriteBMP(hfile, hps, pbmih)
- HFILE hfile;
- HPS hps; /* hps from which to get bitmap bits. */
- PBITMAPINFOHEADER pbmih; /* Bitmap information. */
- {
- ULONG cScans;
- ULONG ulSize; /* Number of bytes occupied by bitmap bits.
- USHORT cSegs; /* Number of 64K segments in ulSize.
- USHORT cbExtra; /* Bytes in last segment of ulSize.
- SEL selBits; /* Base selector to bitmap bits.
- USHORT hugeshift; /* Segment index shift value.
- USHORT cbBMHdr; /* Size of bitmap header.
- PBITMAPFILEHEADER pbfh; /* Pointer to private copy of bitmap info data.
- USHORT cbWrite1; /* Number of bytes to write first call to DosWri
- USHORT cbWrite2; /* Number of bytes to write second call to DosWr
- USHORT cbWritten; /* Number of bytes written by DosWrite.
- BOOL fRet = FALSE; /* Function return code.
- int i; /* Generic loop index.
- struct
- {
- LONG cPlanes;
- LONG cBitCount;
- } bmFmt;
-
-
- /*******************************************************************
- * If the bitmap was created with either 0 planes or 0 bits per
- * pixel, then query the format to write with. By asking for just
- * one format (two LONGs, or one instance of structure of bmFmt),
- * we'll get the device's favored format.
- *******************************************************************/
-
- if ((pbmih->cPlanes == 0) || (pbmih->cBitCount == 0))
- {
- if (!GpiQueryDeviceBitmapFormats(hps, 2L, (PLONG)&bmFmt))
- goto lfwrite_error_close_file;
- }
- else
- {
- bmFmt.cPlanes = pbmih->cPlanes;
- bmFmt.cBitCount = pbmih->cBitCount;
- }
-
-
- /*******************************************************************
- * Determine size of bitmap header. The header consists of a
- * a fixed-size part and a variable-length color table. The
- * latter has 2^cBitCount entries, each of which is sizeof(RGB)
- * bytes long. The exception is when cBitCount is 24, in which
- * case the color table is omitted because the pixels are direct
- * rgb values.
- *******************************************************************/
-
- i = (int) bmFmt.cBitCount;
- if (i == 24)
- cbBMHdr = 0;
- else
- for (cbBMHdr = sizeof(RGB); i > 0; --i)
- cbBMHdr *= 2;
- cbBMHdr += sizeof(BITMAPFILEHEADER);
-
-
- /*******************************************************************
- * Copy structure from input to work buffer. The call to
- * GpiQueryBitmapBits will have write-access to this, so we won't
- * let it have the user's data.
- *******************************************************************/
-
- pbfh = 0;
- if (DosAllocSeg(cbBMHdr, ((PUSHORT)&pbfh)+1, 0))
- goto lfwrite_error_close_file;
- pbfh->bmp = *pbmih;
- if ((pbmih->cPlanes == 0) || (pbmih->cBitCount))
- {
- pbfh->bmp.cPlanes = (USHORT) bmFmt.cPlanes;
- pbfh->bmp.cBitCount = (USHORT) bmFmt.cBitCount;
- }
-
-
- /*******************************************************************
- * Allocate space for the bitmap bits -- all of them at once.
- * The extra ULONG casts are there to force all the arithmetic
- * to be done in 32 bits.
- *******************************************************************/
-
- ulSize = (
- (
- (
- (ULONG)pbfh->bmp.cBitCount
- * (ULONG)pbfh->bmp.cx
- + 31L
- ) / 32L
- ) * (ULONG)pbfh->bmp.cPlanes * 4L
- ) * (ULONG)pbfh->bmp.cy;
-
- cSegs = (USHORT)(ulSize/0x10000L);
- cbExtra = (USHORT)(ulSize%0x10000L);
- if (DosAllocHuge(cSegs, cbExtra, (PSEL)&selBits, 0, 0))
- goto lfwrite_error_free_header;
- if (DosGetHugeShift(&hugeshift))
- goto lfwrite_error_free_bits;
-
-
- /*******************************************************************
- * Tell GPI to give us the bits. The function returns the number
- * of scan lines of the bitmap that were copied. We want all of
- * them at once.
- *******************************************************************/
-
- cScans = GpiQueryBitmapBits( hps
- , 0L
- , (ULONG)pbfh->bmp.cy
- , (PBYTE)MAKEP(selBits, 0)
- , (PBITMAPINFO)&pbfh->bmp);
- if (cScans != pbfh->bmp.cy) /* compare with original number of scans */
- goto lfwrite_error_free_bits;
-
-
- /*******************************************************************
- * Fill in the extra header fields and write the header out to
- * the file.
- *******************************************************************/
-
- pbfh->usType = 0x4D42; /* 'MB' */
- pbfh->cbSize = ulSize + cbBMHdr;
- pbfh->xHotspot = pbfh->bmp.cx / 2;
- pbfh->yHotspot = pbfh->bmp.cy / 2;
- pbfh->offBits = cbBMHdr;
-
- if (DosWrite( hfile
- , (PVOID)pbfh
- , cbBMHdr
- , &cbWritten))
- goto lfwrite_error_free_bits;
- if (cbWritten != cbBMHdr)
- goto lfwrite_error_free_bits;
-
-
- /*******************************************************************
- * Write the bits out to the file. The DosWrite function allows a
- * maximum of 64K-1 bytes written at a time. We get around this
- * by writing two 32K chunks for each 64K segment, and writing the
- * last segment in one piece.
- *******************************************************************/
-
- for (i = 0; i <= (SHORT) cSegs; ++i)
- {
- if (i < (SHORT) cSegs)
- {
- /* This segment is 64K bytes long, so split it up. */
- cbWrite1 = 0x8000;
- cbWrite2 = 0x8000;
- }
- else
- {
- /* This segment is less than 64K bytes long, so write it all. */
- cbWrite1 = cbExtra;
- cbWrite2 = 0;
- }
-
- /* There's a possibility that cbExtra will be 0, so check
- * to avoid an unnecessary system call.
- */
- if (cbWrite1 > 0)
- {
- if (DosWrite( hfile
- , (PVOID)MAKEP(selBits+(i<<hugeshift), 0)
- , cbWrite1
- , &cbWritten))
- goto lfwrite_error_free_bits;
- if (cbWrite1 != cbWritten)
- goto lfwrite_error_free_bits;
- }
-
- /* This will always be skipped on the last partial segment. */
- if (cbWrite2 > 0)
- {
- if (DosWrite( hfile
- , (PVOID)MAKEP(selBits+(i<<hugeshift), cbWrite1)
- , cbWrite2
- , &cbWritten))
- goto lfwrite_error_free_bits;
- if (cbWrite2 != cbWritten)
- goto lfwrite_error_free_bits;
- }
- }
-
- fRet = TRUE; /* The bits are on the disk. */
-
-
- /*******************************************************************
- * Close the file, free the buffer space and leave. This is a
- * common exit point from the function. Since the same cleanup
- * operations need to be performed for such a large number of
- * possible error conditions, this is concise way to do the right
- * thing.
- *******************************************************************/
-
- lfwrite_error_free_bits:
- DosFreeSeg(selBits);
- lfwrite_error_free_header:
- DosFreeSeg(*((PUSHORT)&pbfh+1));
- lfwrite_error_close_file:
- DosClose(hfile);
- return fRet;
- }
-
-
-
-
- /************************************************************************
- *
- * MyMessageBox
- *
- * Displays a message box with the given string. To simplify matters,
- * the box will always have the same title ("FatPel"), will always
- * have a single button ("Ok"), will always have an exclamation point
- * icon, and will always be application modal.
- *
- ************************************************************************/
-
- VOID
- MyMessageBox(hWnd, sz)
- HWND hWnd;
- PSZ sz;
- {
- static char *szTitle = "FatPel Application";
-
- WinMessageBox(HWND_DESKTOP, hWnd, sz, szTitle, 0,
- MB_OK|MB_ICONEXCLAMATION|MB_APPLMODAL);
- }
-
-
- FDIR.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\FDIR\FDIR.C
-
- /*************************************************************
-
- This sample code demonstrates conversion from longnames to 8.3 and how
- to determine the longname from the EA of a FAT file.
- Should be compiled with the Large model.
-
- Written by Jeff Johnson 6/20/89
-
- This code was written to demonstrate two new features of OS/2 V1.2:
- 1) How to convert long filenames to the appropriate 8.3 names.
- 2) How to find a file's longname on a FAT system by checking its EA.
-
- Procedures in this file:
- main() Does the main directory program calling support modules
- Convert_to_8dot3() Converts a longname to 8.3 name
- ParsePathName() Breaks a full path into its 3 components
- QueryLongname() Gets the .LONGNAME EA for a given file
- QueryIFS() Determines the IFS type of a drive
-
- **************************************************************/
-
- #define INCL_DOSFILEMGR
- #define INCL_BASE
- #include <os2.h>
-
- #include <string.h>
- #include <malloc.h>
- #include <stdio.h>
-
- #define FAT 0
- #define HPFS 1
- #define GetInfoLevel1 0x0001
- #define GetInfoLevel3 0x0003
-
- VOID Convert_to_8dot3(CHAR *,CHAR *);
- VOID ParsePathName(CHAR *,CHAR *,CHAR *,CHAR *);
- VOID QueryLongname(CHAR *,CHAR *);
- VOID QueryIFS(CHAR *,PUSHORT,PUSHORT);
-
-
- /*
- * Function name: main()
- *
- * Parameters: argc, argv. If the user places a file spec on the command
- * line it is used to select/filter the directory listing.
- * Otherwise, the default directory is listed.
- *
- * Returns: Always exits with 0.
- *
- * Purpose: main() coordinates the directory process by calling the
- * appropriate setup routines, then handling the DosFindNext
- * loop for each file.
- *
- * Usage/Warnings: Very little error checking is done as the code is written
- * to demonstrate longname conversion/EA reading, not as
- * a finished app.
- *
- * Calls: ParsePathName(), QueryIFS(), Convert_to_8dot3(), QueryLongname()
- */
-
- main (int argc, char *argv[])
- {
- USHORT uRetval,hdir=0xffff,SearchCount=1;
- PFILEFINDBUF pfbuf;
- char szDrive[3],szPath[260],szFilename[CCHMAXPATH],szFullPath[CCHMAXPATH]
- USHORT ifsloc,ifsname;
- char *szFilePtr,szLongName[260];
-
- if(argc<2)
- ParsePathName("",szDrive,szPath,szFilename);
- else
- ParsePathName(argv[1],szDrive,szPath,szFilename);
-
- if(strlen(szFilename) == 0)
- strcpy(szFilename,"*");
-
- strcpy(szFullPath,szDrive);
- strcat(szFullPath,szPath);
- szFilePtr = szFullPath + strlen(szFullPath);
- strcat(szFullPath,szFilename);
-
- QueryIFS(szDrive,&ifsloc,&ifsname);
-
- if(ifsname != FAT && ifsname != HPFS)
- {
- printf("Unrecognized file system.\n");
- return 0;
- }
-
- if(ifsname == FAT)
- printf("FAT -> HPFS directory listing\n");
- else
- printf("HPFS -> FAT directory listing\n");
-
-
- pfbuf = (PFILEFINDBUF) malloc(sizeof(FILEFINDBUF));
- uRetval=DosFindFirst(szFullPath,(PHDIR) &hdir,FILE_DIRECTORY,
- pfbuf,sizeof(FILEFINDBUF),&SearchCount,0L);
-
- if(uRetval)
- {
- printf("No files found.\n");
- return 0;
- }
-
- do
- {
- if(ifsname == FAT)
- {
- strcpy(szFilePtr,pfbuf->achName); /* Drop in name after path */
-
- QueryLongname(szFullPath,szLongName);
-
- if(strlen(szLongName) == 0)
- printf("%s\n",pfbuf->achName);
- else
- printf("%s\n",szLongName);
- }
- else /* It's HPFS */
- {
- Convert_to_8dot3(pfbuf->achName,szFilename);
- printf("%s\n",szFilename);
- }
- } while(!(uRetval=DosFindNext(hdir,pfbuf,
- sizeof(FILEFINDBUF),&SearchCount)));
- }
-
-
- /*
- * Function name: Convert_to_8dot3()
- *
- * Parameters: szLong points to the input long file name.
- * szFat points to a return buffer for the FAT compatible name.
- *
- * Returns: VOID. The converted string is placed in szFat buffer.
- *
- * Purpose: Converts a HPFS longname to the standard 8.3 name. This is
- * done as follows: The extension is the first 3 characters after
- * the last dot, no extension if there are no dots. The file stem
- * is at most 8 character and is taken from the beginning of the
- * longname string, replacing all dots with underscores.
- *
- * Usage/Warnings: Should be bulletproof. Exception code included to allow
- * the special file name '..' through.
- *
- * Calls:
- */
-
- VOID Convert_to_8dot3(CHAR *szLong,CHAR *szFat)
- {
- USHORT usStemMaxLen; /* Holds the max size the 8 char base can be */
- USHORT cnt;
- CHAR szStem[9],szExt[4]; /* Holds the Stem and Extension */
- CHAR *szLastDot; /* Pointer to the last dot */
-
- if(!strcmp(szLong,"..")) /* Allow the predecessor file to pass thru */
- {
- strcpy(szFat,"..");
- return;
- }
-
- szLastDot = strrchr(szLong,'.'); /* Find the last period */
-
- if(szLastDot) /* There is at least one period */
- {
- strncpy(szExt,szLastDot+1,3); /* 1st 3 chars after . are ext */
- szExt[3]=0;
- usStemMaxLen = szLastDot - szLong; /* Max stem is everything b4 . */
- }
- else
- {
- *szExt = 0; /* No extension */
- usStemMaxLen = strlen(szLong); /* Stem can be whole string */
- }
-
- if(usStemMaxLen>8) /* Limit stem to 8 chars */
- usStemMaxLen = 8;
-
- for(cnt=0;cnt<usStemMaxLen;cnt++) /* Copy in chars to form stem */
- {
- switch(szLong[cnt])
- {
- case '.': /* Convert .'s to _'s */
- szStem[cnt] = '_';
- break;
- default: /* Copy all other chars */
- szStem[cnt] = szLong[cnt];
- break;
- }
- }
- szStem[cnt] = 0;
-
- /* Put it all together */
- strcpy(szFat,szStem);
- strcat(szFat,".");
- strcat(szFat,szExt);
- }
-
-
- /*
- * Function name: ParsePathName()
- *
- * Parameters: szFullPath points to the input full path name.
- * szDrive points to the return buffer for the drive letter.
- * szPath points to the return buffer for the path.
- * szFilename points to the return buffer for the Filename.
- *
- * Returns: VOID. The converted string is placed in last 3 passed params.
- *
- * Purpose: Break a full path string and break it into its three components.
- * If the passed string doesn't have a drive, the current letter is
- * fetched an placed in the return buffer. The same is true for
- * the path buffer.
- *
- * Usage/Warnings: Error checking should be done on the DOS calls.
- *
- * Calls:
- */
-
- VOID ParsePathName(CHAR *szFullPath,CHAR *szDrive,CHAR *szPath,CHAR *szFilena
- {
- CHAR *szBack; /* Used to find last backslach */
- USHORT usPathLen; /* Holds the length of the path part of string */
-
- *szPath = *szFilename = 0;
-
- /* Do the Drive letter */
- if(*(szFullPath+1)==':') /* If there is a drive letter */
- {
- szDrive[0] = *szFullPath;
-
- szFullPath += 2;
- }
- else /* We take the default */
- {
- USHORT dno; /* Drive number */
- ULONG dmap; /* Map of available drives */
-
- DosQCurDisk((PUSHORT) &dno,(PULONG) &dmap);
- *szDrive = (CHAR)( dno + 'A'-1);
- }
- szDrive[1] = ':'; /* Add the colon */
- szDrive[2] = (CHAR) 0;
-
- /* Now do the path */
- szBack = strrchr(szFullPath,'\\');
- if(szBack) /* There is at least 1 backslash */
- {
- usPathLen = szBack - szFullPath + 1;
- strncpy(szPath,szFullPath,usPathLen); /* Copy path */
- szPath[usPathLen] = (CHAR) 0;
- }
- else
- {
- *szPath = (CHAR) 0;
- szBack = szFullPath-1; /* Points 1 char before the file name */
- }
-
- /* Finally do the file name */
- strcpy(szFilename,szBack+1);
- }
-
-
- /*
- * Function name: QueryLongname()
- *
- * Parameters: szfile points to the file to be queried.
- * szLong points to the return buffer for the long filename.
- *
- * Returns: VOID. The converted string is placed in last 3 passed params.
- *
- * Purpose: Looks for an EA named .LONGNAME attached to szfile. If found,
- * it places the EA value in the return buffer.
- *
- * Usage/Warnings: Routine assumes that the EA format is LP ASCII which
- * is what the specs required, but probably the exception
- * handling should be a bit tighter. Return buf should be
- * at least CCHMAXPATH long to accomodate max length names.
- * Note also that no check is made to prevent overwriting
- * the end of the return buffer.
- *
- * Calls:
- */
-
- VOID QueryLongname(CHAR *szfile,CHAR *szLong)
- {
- CHAR *szEAName; /* Points to the .LONGNAME string */
- SHORT cbEAName; /* Length of the .LONGNAME string */
-
- SHORT cbFEAList; /* The length of the FEA buf to be used */
- SHORT cbGEAList; /* " GEA */
-
- CHAR cvFdump[300],cvGdump[50]; /* FEA and GEA buffers */
- FEALIST *pFEAList; /* Pointers to the buffers */
- GEALIST *pGEAList;
- EAOP eaop;
- /* Pass struct for Dos call */
- USHORT usRetval;
- SHORT cbRet;
- CHAR *szT;
-
- *szLong = (CHAR) 0; /* Default if we can't get the EA */
-
- szEAName = ".LONGNAME"; /* The particular EA we are interested in
- cbEAName = strlen(szEAName);
-
- cbGEAList = sizeof(GEALIST) + cbEAName; /* Set buf lengths */
- cbFEAList = sizeof(FEALIST) + cbEAName+1 + 256 + 2;
-
- pFEAList = (FEALIST *) cvFdump; /* Set pointers to 2 buffers */
- pGEAList = (GEALIST *) cvGdump;
-
- eaop.fpGEAList = (PGEALIST) pGEAList; /* Build the EAOP struct */
- eaop.fpFEAList = (PFEALIST) pFEAList;
-
- pGEAList->cbList = cbGEAList; /* Fill in GEA buf length */
- pGEAList->list[0].cbName = (CHAR) cbEAName; /* Set .longname length */
- strcpy((char *) pGEAList->list[0].szName, (char *) szEAName);
-
- pFEAList -> cbList = cbFEAList; /* Set length of receiving buffer */
-
- usRetval = DosQPathInfo(szfile, /* Get the .LONGNAME EA */
- GetInfoLevel3,
- (PVOID) &eaop,
- sizeof(EAOP),
- 0L);
-
- if(usRetval != 0) /* There was an error */
- return;
-
- if(pFEAList->list[0].cbValue <=0) /* It couldn't return EA value */
- return;
-
- szT = (CHAR *) pFEAList + sizeof(FEALIST) + cbEAName + 1;
- if (*((USHORT *) szT) == 0xfffd) /* length preceeded ASCII */
- {
- szT += 2;
- cbRet = *((USHORT *) szT);
-
- szT += 2;
- strncpy(szLong,szT,cbRet);
- szLong[cbRet]=0;
- }
- }
-
-
- /*
- * Function name: QueryIFS()
- *
- * Parameters: szDrive points to drive letter to be queried.
- * pusLocale will contain the location of the drive:
- * 3=local, 4=remote.
- * pusFSDName will contain the IFS type: 0=FAT, 1=HPFS, 2=Other.
- *
- * Returns: VOID. All returns are in the last 2 params.
- *
- * Purpose: Mainly used to determine whether the file system is FAT or HPFS.
- * also returns info on whether the drive is local or remote.
- *
- * Usage/Warnings: Error checking on the DOS call should be implemented.
- * The buffer filled by DosQFSAttach is structured as follow
- * USHORT iType;
- * USHORT cbName;
- * UCHAR szName[];
- * USHORT cbFSDName;
- * UCHAR szFSDName[];
- * ...
- *
- * Calls:
- */
-
- VOID QueryIFS(CHAR *szDrive,PUSHORT pusLocale,PUSHORT pusFSDName)
- {
- CHAR vChunk[100]; /* Buffer for data from DosQFSAttach */
- USHORT usChunkLen=100;
- USHORT usTemp; /* Holds offset for FSDName */
-
- DosQFSAttach(szDrive,0,GetInfoLevel1, vChunk,&usChunkLen,0L);
-
- *pusLocale = *((PUSHORT) vChunk); /* Set local from 1st USHORT *);*/
-
- /* Skip over iType, cbName, szName, and cbFSDName fields to szFSDName */
- usTemp = *((PUSHORT) &vChunk[sizeof(USHORT)]) + sizeof(USHORT)*3 + 1;
-
- if(!strcmp("FAT",&vChunk[usTemp]))
- {
- *pusFSDName = 0;
- return;
- }
- if(!strcmp("HPFS",&vChunk[usTemp]))
- {
- *pusFSDName = 1;
- return;
- }
-
- *pusFSDName = 2;
- return;
- }
-
-
-
- FILE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\STOCK\FILE.C
-
- /*** file.C - standard file dialogs
- *
- */
-
- #define INCL_DOSERRORS
- #define INCL_WINCOMMON
- #define INCL_WINBUTTONS
- #define INCL_WINDIALOGS
- #define INCL_WINFRAMEMGR
- #define INCL_WININPUT
- #define INCL_WINLISTBOXES
- #define INCL_WINMENUS
- #define INCL_WINMESSAGEMGR
-
- #include <os2.h>
- #include <stddef.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
-
- #include "fileid.h"
- #include "file.h"
- #include "mem.h"
-
- #define dbg(x) x
-
- typedef struct { /* fctl */
- char *pszTitle; // Dialog box title
- char *pszPattern; // wild-card file pattern
- char achPath[CCHMAXPATH]; // full path of file
- } FILECTL;
- typedef FILECTL *PFILECTL;
-
- MRESULT EXPENTRY FileDlgProc(HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2);
-
- USHORT beginSearch(char *psz, USHORT *pattr);
- BOOL changeDir(HWND hwndDlg, PFILECTL pfctl);
- BOOL changeDrive(HWND hwndDlg, PFILECTL pfctl);
- BOOL changeFile(HWND hwndDlg, PFILECTL pfctl);
- void endSearch(void);
- USHORT nextSearch(char *psz, USHORT *pattr);
- USHORT niceWinDlgBox(HWND hwndParent, HWND hwndOwner, PFNWP pf
- HMODULE hmod, USHORT idDlg, PVOID pCreateParams);
- BOOL setCurDir(HWND hwndDlg);
- BOOL setDir(HWND hwndDlg);
- BOOL setDrive(HWND hwndDlg);
- BOOL setFile(HWND hwndDlg);
- char * trimBlanks(char * psz);
-
-
- static BOOL fDidOK; // true if OK was just pres
-
- static HDIR hdir; // directory search handle
-
- static USHORT itDrive; // last item selected in Drive L
- static USHORT itDir; // last item selected in D
- static USHORT itFile; // last item selected in
-
-
- char *FileOpen(HWND hwndOwner,char *pszTitle,char *pszPattern)
- {
- BOOL fOK;
- FILECTL fctl;
-
- fctl.pszTitle = pszTitle;
- fctl.pszPattern = pszPattern;
-
- fOK = niceWinDlgBox(HWND_DESKTOP, hwndOwner, FileDlgProc,
- NULL, IDD_FILE, &fctl);
-
- if (fOK)
- return MemStrDup(fctl.achPath);
- else
- return NULL;
- }
-
-
- USHORT niceWinDlgBox(HWND hwndParent, HWND hwndOwner, PFNWP pfnDlgProc
- HMODULE hmod, USHORT idDlg, PVOID pCreateParams)
- {
- HAB hab;
- HWND hwndDlg;
- USHORT us;
- SWP swp;
- SWP swpDesk;
-
- hwndDlg = WinLoadDlg(hwndParent, hwndOwner, pfnDlgProc,
- hmod, idDlg, pCreateParams);
-
- WinQueryWindowPos(hwndDlg,&swp); // get window position
- WinQueryWindowPos(HWND_DESKTOP,&swpDesk); // get desktop
-
- // center dialog box on screen
-
- swp.x = (swpDesk.cx - swp.cx) >> 1;
- swp.y = (swpDesk.cy - swp.cy) >> 1;
-
- hab = WinQueryAnchorBlock(hwndDlg);
- WinSetMultWindowPos(hab,&swp,1);
-
- us = WinProcessDlg(hwndDlg);
- WinDestroyWindow(hwndDlg);
-
- return us;
- }
-
- /*** FileDlgProc - "File" Dialog Procedure
- *
- */
- MRESULT EXPENTRY FileDlgProc(HWND hwnd,USHORT msg,MPARAM mp1,MPARAM mp2)
- {
- static char ach[CCHMAXPATH];
- USHORT attr;
- static HWND hwndFocus;
- static HWND hwndLBDir;
- static HWND hwndLBDrive;
- static HWND hwndLBFile;
- static HWND hwndText;
- static USHORT idLB;
- static USHORT idLBPrevious;
- USHORT it;
- static PFILECTL pfctl;
- USHORT rc;
-
- switch (msg) {
-
- case WM_INITDLG:
- pfctl = (PFILECTL)(VOID *)SHORT1FROMMP(mp2); // set file contr
-
- hwndLBDir = WinWindowFromID(hwnd, IDL_DIR);
- hwndLBDrive = WinWindowFromID(hwnd, IDL_DRIVE);
- hwndLBFile = WinWindowFromID(hwnd, IDL_FILE);
- hwndText = WinWindowFromID(hwnd, IDC_TEXT);
- idLBPrevious = 0; // no previous focus
-
- WinSetWindowText(hwnd, pfctl->pszTitle); // set dialog title
- WinSetWindowText(hwndText, pfctl->pszPattern); // init file pa
-
- setDrive(hwnd); // init drive list box
- setDir(hwnd); // update dir list
- setFile(hwnd); // update file list
- setCurDir(hwnd); // init current drive/dir string
-
- WinDefDlgProc(hwnd, msg, mp1, mp2); // do default stuff
-
- hwndFocus = hwndText;
- WinSetFocus(HWND_DESKTOP,hwndFocus);
- return (MRESULT) TRUE;
-
- case WM_COMMAND:
- switch (LOUSHORT(mp1)) {
-
- case DID_OK: // store updated list
- dbg( printf("WM_COMMAND: DID_OK\n") );
- WinQueryWindowText(hwndText, CCHMAXPATH, ach);
- trimBlanks(ach); // Trim leading/trailing blanks
- WinSetWindowText(hwndText, ach);
- dbg( printf(" opening %s\n",ach) );
- rc = DosQFileMode(ach,&attr,0L); // Does file exist?
- dbg( printf(" DosQFileMode rc=%d\n",rc) );
-
- // If directory is specified, pretend file not found
-
- if (attr & FILE_DIRECTORY)
- rc = ERROR_FILE_NOT_FOUND;
-
- fDidOK = TRUE;
- switch (rc) {
-
- case NO_ERROR: {
- USHORT cch=CCHMAXPATH;
-
- rc = DosQPathInfo(
- ach, // Path specifiec
- FIL_QUERYFULLNAME, // Get fully-qualified name
- pfctl->achPath, // Return buffer
- CCHMAXPATH, // Return buffer size
- 0L // Reserved
- );
- if (rc == 0)
- WinDismissDlg(hwnd,TRUE); // return SUCCESS
- }
- return FALSE;
-
- case ERROR_FILE_NOT_FOUND:
- case ERROR_PATH_NOT_FOUND:
- // check for and process user wild-card pattern
- if (strcmp(ach,pfctl->pszPattern) != 0)
- setFile(hwnd);
- break; // continue dialog
-
- case ERROR_ACCESS_DENIED:
- case ERROR_DRIVE_LOCKED:
- case ERROR_NOT_DOS_DISK:
- WinMessageBox(HWND_DESKTOP, hwnd, "Access Denied",
- "Error", NULL, MB_ICONEXCLAMATION);
- break;
-
- default:
- break;
- }
- WinSetFocus(HWND_DESKTOP,hwndFocus);
- break;
-
- case DID_CANCEL:
- WinDismissDlg(hwnd, NULL);
- break;
- }
- break;
-
- case WM_CONTROL:
- idLBPrevious = idLB; // remember previous focus
- idLB = SHORT1FROMMP(mp1);
- dbg (printf("WM_CONTROL: id = %04x hwndLB=%08x\n",idLB,mp2) );
- switch (SHORT2FROMMP(mp1)) {
- case LN_ENTER:
- switch (idLB) {
-
- case IDL_DRIVE:
- dbg( printf("LN_ENTER: IDL_DRIVE\n") );
- changeDrive(hwnd,pfctl);
- return FALSE;
-
- case IDL_DIR:
- dbg( printf("LN_ENTER: IDL_DIR\n") );
- changeDir(hwnd,pfctl);
- return FALSE;
-
- case IDL_FILE:
- dbg( printf("LN_ENTER: IDL_FILE\n") );
- changeFile(hwnd,pfctl);
- WinSendMsg(hwnd,WM_COMMAND,MPFROMSHORT(DID_OK),NULL);
- return FALSE;
-
- default:
- dbg( printf("LN_ENTER: unknown list box = %04x\n",idLB) )
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- break;
- }
- break;
-
- case LN_SELECT:
- switch (idLB) {
-
- case IDL_DRIVE:
- dbg( printf("LN_SELECT: IDL_DRIVE\n") );
- it = SHORT1FROMMR(WinSendMsg(hwndFocus, LM_QUERYSELECTION
- if (it != LIT_NONE) {
- if (fDidOK)
- fDidOK = FALSE;
- else {
- itDrive = it;
- WinSendMsg(hwndFocus, LM_QUERYITEMTEXT,
- MPFROM2SHORT(it,CCHMAXPATH), MPFROMP(ach));
- strcat(ach,pfctl->pszPattern);
- WinSetWindowText(hwndText, ach);
- }
- }
- idLB = 0; // allow LN_SETFOCUS to work
- return FALSE;
-
- case IDL_DIR:
- dbg( printf("LN_SELECT: IDL_DIR\n") );
- it = SHORT1FROMMR(WinSendMsg(hwndFocus, LM_QUERYSELECTION
- if (it != LIT_NONE) {
- if (fDidOK)
- fDidOK = FALSE;
- else {
- itDir = it;
- WinSendMsg(hwndFocus, LM_QUERYITEMTEXT,
- MPFROM2SHORT(it,CCHMAXPATH), MPFROMP(ach));
- strcat(ach,"\\");
- strcat(ach,pfctl->pszPattern);
- WinSetWindowText(hwndText, ach);
- }
- }
- idLB = 0; // allow LN_SETFOCUS to work
- return FALSE;
-
- case IDL_FILE:
- dbg( printf("LN_SELECT: IDL_FILE\n") );
- it = SHORT1FROMMR(WinSendMsg(hwndFocus, LM_QUERYSELECTION
- if (it != LIT_NONE) {
- if (fDidOK)
- fDidOK = FALSE;
- else {
- itFile = it;
- changeFile(hwnd,pfctl);
- }
- }
- idLB = 0; // allow LN_SETFOCUS to work
- return FALSE;
-
- default:
- dbg( printf("LN_SELECT: unknown list box = %04x\n",idLB)
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- break;
- }
- break;
-
- case LN_SETFOCUS:
- //* The following test prevents reselecting the last
- // selected list box item when the user is scrolling
- // the list box.
-
- if (idLB == idLBPrevious)
- break; // no actual focus change
-
- switch (idLB) {
-
- case IDL_DRIVE:
- dbg( printf("LN_SETFOCUS: IDL_DRIVE\n") );
- hwndFocus = hwndLBDrive;
- WinSendMsg(hwndFocus, LM_SELECTITEM,
- MPFROMSHORT(itDrive), MPFROMSHORT(TRUE));
- return FALSE;
-
- case IDL_DIR:
- dbg( printf("LN_SETFOCUS: IDL_DIR\n") );
- hwndFocus = hwndLBDir;
- WinSendMsg(hwndFocus, LM_SELECTITEM,
- MPFROMSHORT(itDir), MPFROMSHORT(TRUE));
- return FALSE;
-
- case IDL_FILE:
- dbg( printf("LN_SETFOCUS: IDL_FILE\n") );
- hwndFocus = hwndLBFile;
- WinSendMsg(hwndFocus, LM_SELECTITEM,
- MPFROMSHORT(itFile), MPFROMSHORT(TRUE));
- return FALSE;
-
- default:
- dbg( printf("LN_SETFOCUS: unknown list box = %04x\n",idLB
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- break;
- }
- break;
-
- case LN_KILLFOCUS:
- switch (idLB) {
-
- case IDL_DRIVE:
- dbg( printf("LN_KILLFOCUS: IDL_DRIVE\n") );
- hwndFocus = hwndLBDrive;
- WinSendMsg(hwndFocus, LM_SELECTITEM,
- MPFROMSHORT(LIT_NONE), MPFROMSHORT(FALSE));
- return FALSE;
-
- case IDL_DIR:
- dbg( printf("LN_KILLFOCUS: IDL_DIR\n") );
- hwndFocus = hwndLBDir;
- WinSendMsg(hwndFocus, LM_SELECTITEM,
- MPFROMSHORT(LIT_NONE), MPFROMSHORT(FALSE));
- return FALSE;
-
- case IDL_FILE:
- dbg( printf("LN_KILLFOCUS: IDL_FILE\n") );
- hwndFocus = hwndLBFile;
- WinSendMsg(hwndFocus, LM_SELECTITEM,
- MPFROMSHORT(LIT_NONE), MPFROMSHORT(FALSE));
- return FALSE;
-
- default:
- dbg( printf("LN_KILLFOCUS: unknown list box = %04x\n",idL
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- break;
- }
- break;
-
- default:
- dbg( printf("notify code= %04x\n",SHORT2FROMMP(mp1)) );
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- }
- return FALSE;
-
- default:
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- }
- return FALSE;
- }
-
-
- BOOL changeDrive(HWND hwndDlg, PFILECTL pfctl)
- {
- USHORT it;
- USHORT drv;
- HWND hwndLBDrive;
- HWND hwndText;
-
- hwndLBDrive = WinWindowFromID(hwndDlg, IDL_DRIVE);
- hwndText = WinWindowFromID(hwndDlg, IDC_TEXT);
-
- it = SHORT1FROMMR(WinSendMsg(hwndLBDrive, LM_QUERYSELECTION, 0L, 0L));
- if (it != LIT_NONE) {
- itDrive = it;
- drv = SHORT1FROMMR(WinSendMsg(hwndLBDrive, // get drive number
- LM_QUERYITEMHANDLE, MPFROMSHORT(it), 0L));
- DosSelectDisk(drv); // change drive
- WinSetWindowText(hwndText, pfctl->pszPattern); // reset patter
- setDir(hwndDlg); // update dir list
- setFile(hwndDlg); // update file list
- setCurDir(hwndDlg); // update current drive/dir text
- return TRUE;
- }
- return FALSE;
- }
-
-
- BOOL changeDir(HWND hwndDlg, PFILECTL pfctl)
- {
- char ach[CCHMAXPATH];
- HWND hwndLBDir;
- HWND hwndText;
- USHORT it;
-
- hwndLBDir = WinWindowFromID(hwndDlg, IDL_DIR);
- hwndText = WinWindowFromID(hwndDlg, IDC_TEXT);
-
- it = SHORT1FROMMR(WinSendMsg(hwndLBDir, LM_QUERYSELECTION, 0L, 0L));
- if (it != LIT_NONE) {
- itDir = it;
- WinSendMsg(hwndLBDir, LM_QUERYITEMTEXT, // get dir
- MPFROM2SHORT(it,CCHMAXPATH), MPFROMP(ach));
- DosChDir(ach, 0L);
- WinSetWindowText(hwndText, pfctl->pszPattern); // reset patter
- setDir(hwndDlg); // update dir list
- setFile(hwndDlg); // update file list
- setCurDir(hwndDlg); // update current drive/dir text
- return TRUE;
- }
- return FALSE;
- }
-
- BOOL changeFile(HWND hwndDlg, PFILECTL pfctl)
- {
- char ach[CCHMAXPATH];
- HWND hwndLBFile;
- HWND hwndText;
- USHORT it;
-
- hwndText = WinWindowFromID(hwndDlg, IDC_TEXT);
- hwndLBFile = WinWindowFromID(hwndDlg, IDL_FILE);
-
- it = SHORT1FROMMR(WinSendMsg(hwndLBFile, LM_QUERYSELECTION, 0L, 0L));
- if (it != LIT_NONE) {
- itFile = it;
- WinSendMsg(hwndLBFile, LM_QUERYITEMTEXT, // get dir
- MPFROM2SHORT(it,CCHMAXPATH), MPFROMP(ach));
- WinSetWindowText(hwndText, ach); // set file name
- return TRUE;
- }
- return FALSE;
- }
-
- BOOL setDrive(HWND hwndDlg)
- {
- char ach[3];
- ULONG bmlDrives;
- USHORT drvCurrent;
- HWND hwndLBDrive;
- USHORT i;
- USHORT us;
-
-
- hwndLBDrive = WinWindowFromID(hwndDlg, IDL_DRIVE);
-
- if (DosQCurDisk(&drvCurrent,&bmlDrives) != 0) {
- dbg( printf("DosQCurDisk failed!\n") );
- return FALSE;
- }
- drvCurrent--; // 0-based drive number
-
- ach[1] = ':'; // init drive string
- ach[2] = '\0';
-
- WinEnableWindowUpdate(hwndLBDrive,FALSE); // turn off list box updates
- WinSendMsg(hwndLBDrive, LM_DELETEALL, NULL, NULL); // delete old entries
-
- for (i=0; bmlDrives != NULL; i++) { // get all 1 bits!
- if (bmlDrives & 1) { // drive exists
- ach[0] = (char)(i + 'a');
- us = SHORT1FROMMR(WinSendMsg(hwndLBDrive, LM_INSERTITEM,
- MPFROMSHORT(LIT_SORTASCENDING), MPFROMP(ach)));
- WinSendMsg(hwndLBDrive, LM_SETITEMHANDLE, // set drive nu
- MPFROMSHORT(us), MPFROMSHORT(i+1));
- if (i == drvCurrent) {
- itDrive = us; // save index for selection
- }
- }
- bmlDrives >>= 1; // get next drive bit in bit 0
- }
-
- WinEnableWindowUpdate(hwndLBDrive,TRUE); // repaint list box
- return TRUE;
- }
-
- BOOL setCurDir(HWND hwndDlg)
- {
- char ach[CCHMAXPATH];
- ULONG bmlDrives;
- USHORT cch;
- USHORT drvCurrent;
- HWND hwndCurDir;
- USHORT rc;
-
- rc = DosQCurDisk(&drvCurrent,&bmlDrives); // get current drive
-
- ach[0] = (char)((char)drvCurrent + 'a' - (char)1) ; // make drive letter
- ach[1] = ':'; // rest of drive string
- ach[2] = '\\';
-
- cch = CCHMAXPATH-3; // room for drive string
-
- rc = DosQCurDir(drvCurrent, &ach[3], &cch);
-
- hwndCurDir = WinWindowFromID(hwndDlg, IDC_CURDIR);
- WinSetWindowText(hwndCurDir,ach); // set current drive/dir text
- return TRUE;
- }
-
-
- BOOL setDir(HWND hwndDlg)
- {
- char ach[20];
- static USHORT attr;
- USHORT cch;
- HWND hwndLBDir;
-
- hwndLBDir = WinWindowFromID(hwndDlg, IDL_DIR);
-
- WinEnableWindowUpdate(hwndLBDir,FALSE); // turn off list box updates
- WinSendMsg(hwndLBDir, LM_DELETEALL, NULL, NULL); // delete old entries
-
- // get all directories
-
- strcpy(ach,"*.*");
- attr = 0x37;
- for (cch = beginSearch(ach,&attr);
- cch != 0;
- cch = nextSearch(ach,&attr)) {
- if (attr & 0x0010) { // only get directories
- // if ((cch > 1) || (ach[0] != '.')) { // do all but "."
- WinSendMsg(hwndLBDir, LM_INSERTITEM,
- MPFROMSHORT(LIT_SORTASCENDING), MPFROMP(ach));
- // }
- }
- }
- endSearch();
-
- WinEnableWindowUpdate(hwndLBDir,TRUE); // repaint list box
- itDir = 1;
- return TRUE;
- }
-
-
- BOOL setFile(HWND hwndDlg)
- {
- char ach[20];
- static USHORT attr;
- USHORT cch;
- HWND hwndLBFile;
- HWND hwndText;
-
- hwndLBFile = WinWindowFromID(hwndDlg, IDL_FILE);
- hwndText = WinWindowFromID(hwndDlg, IDC_TEXT);
-
- WinEnableWindowUpdate(hwndLBFile,FALSE); // turn off list box updates
- WinSendMsg(hwndLBFile, LM_DELETEALL, NULL, NULL); // delete old entries
-
- // get only files that match user's pattern
-
- WinQueryWindowText(hwndText,CCHMAXPATH,ach);
- dbg( printf("file pattern = %s\n",ach) );
- attr = 0x27; // do all but directories
- for (cch = beginSearch(ach,&attr);
- cch != 0;
- cch = nextSearch(ach,&attr) ) {
- WinSendMsg(hwndLBFile, LM_INSERTITEM,
- MPFROMSHORT(LIT_SORTASCENDING), MPFROMP(ach));
-
- }
- endSearch();
- WinEnableWindowUpdate(hwndLBFile,TRUE); // repaint list box
- itFile = 1; // default selection
-
- return TRUE;
- }
-
-
- USHORT beginSearch(char *psz, USHORT *pattr)
- {
- FILEFINDBUF findbuf;
- USHORT cf;
- USHORT rc;
-
- cf = 1; // only return 1 file
- hdir = 0xFFFF; // create a search handle
-
- rc = DosFindFirst(psz, // file specification
- &hdir, // pointer to variable for handle
- *pattr, // search attribute (everything)
- &findbuf, // pointer to result buffer
- sizeof(FILEFINDBUF), // length of result buffer
- &cf, // files to find/files found
- 0L); // Must be zero
-
- if (cf != 0) {
- psz[findbuf.cchName] = '\0'; // terminate name
- strncpy(psz,findbuf.achName,findbuf.cchName); // copy name to caller
- *pattr = findbuf.attrFile;
- return findbuf.cchName;
- }
- return 0;
- }
-
-
- USHORT nextSearch(char *psz, USHORT *pattr)
- {
- FILEFINDBUF findbuf;
- USHORT cf;
- USHORT rc;
-
- cf = 1; // only return 1 file
-
- rc = DosFindNext(hdir, // pointer to variable for handle
- &findbuf, // pointer to result buffer
- sizeof(FILEFINDBUF), // length of result buffer
- &cf); // files to find/files found
-
- if (cf != 0) {
- psz[findbuf.cchName] = '\0'; // terminate name
- strncpy(psz,findbuf.achName,findbuf.cchName); // copy name to caller
- *pattr = findbuf.attrFile;
- return findbuf.cchName;
- }
- return 0;
- }
-
-
- void endSearch(void)
- {
- DosFindClose(hdir);
- }
-
-
- /*** trimBlanks - trim off leading and trailing blanks
- *
- * ENTRY psz - string to be trimmed
- */
-
- char * trimBlanks(char *psz)
- {
- char *pch;
- char *pchDst;
- char *pchRight;
-
- // Find right-most non-blank character
-
- for (pch = psz+strlen(psz)-1; // start at last character
- (pch >= psz) && (*pch == ' '); // scan backward to non-blank
- pch--)
- ;
-
- *(pch+1) = '\0'; // trim trailing blanks
-
- pchRight = pch;
-
- // Find left-most non-blank character
-
- for (pch = psz; // start at first character
- (pch <= pchRight) && (*pch == ' '); // scan forward to non-blank
- pch++)
- ;
-
- // Shift string left to trim leading blanks
-
- if (pch > psz) { // leading blanks to trim
- pchRight++; // grab traling null
- pchDst = psz; // do not destroy psz
- while (pchDst <= pchRight)
- *pchDst++ = *pch++; // shift string left
- }
- return psz;
- }
-
-
- FILE.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\OPENDLG\FILE.C
-
- /*
- FILE.C -- Open/Save As Dialog Box library routines
- Created by Microsoft Corporation, 1989
- */
- #define INCL_DOS
- #define INCL_DOSQUEUES
- #include "tool.h"
-
-
- /****************************************************************************
- * This function is the Open dialog box window procedure. It handles input,
- * allows the user to change directories, checks for legal filenames, opens
- * specified files, appends default extensions and returns the file's name.
- *
- * The return values are
- * TDF_INVALID - Library error (internal error),
- * TDF_NOOPEN - User hits cancel
- * TDF_NEWOPEN - Created new file (file left open)
- * TDF_OLDOPEN - Opened existing file (file left open)
- \****************************************************************************
-
- MRESULT EXPENTRY DlgOpenWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- PDLF pdlf;
- PSZ lpchFile;
- CHAR sz[MAX_FNAME_LEN];
-
- switch (msg)
- {
- case WM_INITDLG:
- /* initialize dialog box */
- DlgInitOpen(hwnd, LONGFROMMP(mp2));
-
- /* fill static field with path name and fill list box with
- filenames that lMatch spec */
- if (!DlgDirList(hwnd, ((PDLF)(mp2))->pszExt+1, ID_DIRLIST,
- ID_FILELIST, ID_PATH, ((PDLF)(mp2))->rgbFlags))
- /* NOTE: shouldn't we post a message if something screws up? */
- WinDismissDlg(hwnd, TDF_INVALID);
- break;
-
- case WM_COMMAND:
- pdlf = (PDLF) WinQueryWindowULong(hwnd, 0);
- switch (SHORT1FROMMP(mp1))
- {
- case MBID_OK:
- /* Open button pressed */
- /* get name from edit box */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)pdlf->szFileName);
- Upper((PSZ)pdlf->szFileName);
- if (lstrlen((PSZ)pdlf->szFileName))
- DlgOpenName(hwnd, pdlf);
- break;
-
- case MBID_CANCEL:
- /* Cancel button pressed, dismiss dialog box */
- WinDismissDlg(hwnd, TDF_NOOPEN);
- break;
-
- case MBID_HELP:
- /* Help button pressed */
- WinMessageBox( HWND_DESKTOP
- , hwnd
- , pdlf->pszInstructions
- , pdlf->pszTitle
- , NULL
- , MB_OK | MB_APPLMODAL );
- break;
- }
- break;
-
- case WM_CONTROL:
- pdlf = (PDLF) WinQueryWindowULong(hwnd, 0);
- switch (SHORT1FROMMP(mp1))
- {
- case ID_DIRLIST:
- /* user clicked in directory list box */
- switch (SHORT2FROMMP(mp1))
- {
- case LN_SELECT:
- /* single click case */
- /* get current edit string */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)sz);
- Upper((PSZ)sz);
-
- /* get selected string */
- if (DlgDirSelect(hwnd, (PSZ)pdlf->szFileName, ID_DIRLIST))
- {
- /* if edit field contains wild card, then append file
- part to selected directory, otherwise append
- last wildcard search spec */
- lpchFile = FileInPath((PSZ)sz);
- lstrcat( (PSZ)pdlf->szFileName
- , DlgSearchSpec( lpchFile)
- ? lpchFile
- : (PSZ)pdlf->szLastWild );
- /* set edit box to resulting name */
- WinSetWindowText(WinWindowFromID(hwnd, ID_EDIT),
- (PSZ)pdlf->szFileName);
- }
- break;
-
- case LN_ENTER:
- /* get text from edit box */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)pdlf->szFileName);
- Upper((PSZ)pdlf->szFileName);
- if( DlgSearchSpec( (PSZ)pdlf->szFileName))
- {
- DlgDirList( hwnd
- , (PSZ)pdlf->szFileName
- , ID_DIRLIST
- , ID_FILELIST
- , ID_PATH
- , pdlf->rgbFlags );
- lstrcpy( (PSZ)pdlf->szLastWild
- , FileInPath( (PSZ)pdlf->szFileName));
- WinSetWindowText( WinWindowFromID( hwnd, ID_EDIT)
- , (PSZ)pdlf->szFileName );
- }
- break;
- }
- break;
-
- case ID_FILELIST:
- /* user clicked in file list box */
- switch (SHORT2FROMMP(mp1))
- {
- case LN_SELECT:
- /* single click case */
-
- /* get current edit string */
- /* if it contains a wildcard, save it before obliteration */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)sz);
- Upper((PSZ)sz);
- if( DlgSearchSpec( (PSZ)sz))
- lstrcpy( (PSZ)pdlf->szLastWild, FileInPath( (PSZ)sz));
-
- /* get selected file name */
- DlgDirSelect(hwnd, (PSZ)pdlf->szFileName, ID_FILELIST);
- /* set edit box to resulting name */
- WinSetWindowText(WinWindowFromID(hwnd, ID_EDIT),
- (PSZ)pdlf->szFileName);
- break;
-
- case LN_ENTER:
- /* double click case, single click already processed */
- DlgOpenName(hwnd, pdlf);
- break;
- }
- break;
- }
- break;
-
- default:
- return (WinDefDlgProc(hwnd, msg, mp1, mp2));
- }
-
- return (MRFROMLONG(0L)); /* message processed */
- }
-
-
-
-
- /****************************************************************************
- * This function stores the pdlf in the dialog window structure, sets
- * the title and instruction texts and limits the text size.
- \****************************************************************************
-
- VOID PASCAL DlgInitOpen (hwnd, lpParm)
- HWND hwnd;
- ULONG lpParm;
- {
- PDLF pdlf;
-
- /* Set pdlf local to window */
- pdlf = (PDLF) lpParm;
- WinSetWindowULong(hwnd, 0, lpParm);
-
- /* set edit box text size limit */
- WinSendDlgItemMsg(hwnd, ID_EDIT, EM_SETTEXTLIMIT, (MPARAM)CBROOTNAMEMAX,
-
- /* set edit window to search spec */
- if (pdlf->pszExt != (PSZ)NULL)
- WinSetWindowText(WinWindowFromID(hwnd, ID_EDIT), pdlf->pszExt+1);
-
- /* set title window */
- if (pdlf->pszTitle != (PSZ)NULL)
- WinSetWindowText(WinWindowFromID(hwnd, FID_TITLEBAR), pdlf->pszTitle)
- }
-
-
-
-
- /****************************************************************************
- * This function processes the currently selected name in the open dialog
- * box. If the name represents a directory, the current directory is
- * changed to that one and the corresponding files are displayed. If the
- * name is a file, then it is opened.
- \****************************************************************************
-
- VOID PASCAL DlgOpenName(hwnd, pdlf)
- HWND hwnd;
- PDLF pdlf;
- {
- PSZ lpch;
- USHORT wVal;
- CHAR sz[MAX_FNAME_LEN];
-
- /* try using current name as a directory */
- lstrcpy((PSZ)sz, (PSZ)pdlf->szFileName);
- if (!DlgSearchSpec((PSZ)sz))
- DlgAddSearchExt(pdlf, (PSZ)sz);
- if (DlgDirList(hwnd, (PSZ)sz, ID_DIRLIST, ID_FILELIST, ID_PATH,
- pdlf->rgbFlags))
- {
- /* name was a directory, extract and set file name */
- lpch = FileInPath((PSZ)sz);
- lstrcpy((PSZ)pdlf->szFileName, lpch);
- WinSetWindowText(WinWindowFromID(hwnd, ID_EDIT),
- (PSZ)pdlf->szFileName);
- }
- else
- /* try to open name as a file */
- if ((wVal = DlgOpenFile(pdlf, hwnd)) != TDF_NOOPEN)
- WinDismissDlg(hwnd, wVal);
- }
-
-
-
-
- /****************************************************************************
- * This function is the SaveAs dialog box window procedure. It handles input,
- * tests for legal filenames and uses message boxes to report any problems.
- *
- * Return values are:
- * TDF_INVALID - Library error (internal error),
- * TDF_NOOPEN - User hits cancel
- * Specific for DLG_NOOPEN
- * TDF_NEWSAVE - user wants to save to a new file (file not created)
- * TDF_OLDSAVE - user wants to save over existing file (file not opened)
- * else
- * TDF_NEWSAVE - user wants to save to a new file (file left open)
- * TDF_OLDSAVE - user wants to save over existing file (file left open)
- \****************************************************************************
-
- MRESULT EXPENTRY DlgSaveAsWndProc(hwnd, msg, mp1, mp2)
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- PDLF pdlf;
- PSZ lpchFile;
- CHAR sz[MAX_FNAME_LEN];
-
- switch (msg)
- {
- case WM_INITDLG:
- /* Store pdlf, set instructions, limit text size */
- DlgInitSaveAs(hwnd, LONGFROMMP(mp2));
-
- /* fill static field with path name and fill list box with
- filenames that lMatch spec */
- if (!DlgDirList(hwnd, ((PDLF)(mp2))->pszExt+1, ID_DIRLIST,
- ID_FILELIST, ID_PATH, ((PDLF)(mp2))->rgbFlags))
- /* NOTE: shouldn't we post a message if something screws up? */
- WinDismissDlg(hwnd, TDF_INVALID);
- break;
-
- case WM_COMMAND:
- pdlf = (PDLF) WinQueryWindowULong(hwnd, 0);
- switch (SHORT1FROMMP(mp1))
- {
- case MBID_OK:
- /* get text from edit box */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)pdlf->szFileName);
- Upper((PSZ)pdlf->szFileName);
- if( DlgSearchSpec( (PSZ)pdlf->szFileName))
- {
- DlgDirList( hwnd
- , (PSZ)pdlf->szFileName
- , ID_DIRLIST
- , ID_FILELIST
- , ID_PATH
- , pdlf->rgbFlags );
- lstrcpy( (PSZ)pdlf->szLastWild
- , FileInPath( (PSZ)pdlf->szFileName));
- lstrcpy( (PSZ)pdlf->szFileName, (PSZ)pdlf->szLastFile);
- WinSetWindowText( WinWindowFromID( hwnd, ID_EDIT)
- , (PSZ)pdlf->szFileName );
- }
- else if( lstrlen( (PSZ)pdlf->szFileName))
- DlgSaveAsName( hwnd, pdlf);
- break;
-
- case MBID_CANCEL:
- WinDismissDlg(hwnd, TDF_NOSAVE);
- break;
-
- case MBID_HELP:
- /* Help button pressed */
- WinMessageBox( HWND_DESKTOP
- , hwnd
- , pdlf->pszInstructions
- , pdlf->pszTitle
- , NULL
- , MB_OK | MB_APPLMODAL );
- break;
- }
- break;
-
- case WM_CONTROL:
- pdlf = (PDLF) WinQueryWindowULong(hwnd, 0);
- switch (SHORT1FROMMP(mp1))
- {
- case ID_DIRLIST:
- /* user clicked in directory list box */
- switch (SHORT2FROMMP(mp1))
- {
- case LN_SELECT:
- /* single click case */
- /* get current edit string */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)sz);
- Upper((PSZ)sz);
-
- /* get selected string */
- if (DlgDirSelect(hwnd, (PSZ)pdlf->szFileName, ID_DIRLIST))
- {
- /* if edit field contains wild card, then append file
- part to selected directory, otherwise append
- last wildcard search spec */
- lpchFile = FileInPath((PSZ)sz);
- if( DlgSearchSpec( lpchFile))
- {
- lstrcat( (PSZ)pdlf->szFileName, lpchFile );
- lstrcpy( (PSZ)pdlf->szLastWild, lpchFile);
- }
- else
- {
- lstrcat( (PSZ)pdlf->szFileName, (PSZ)pdlf->szLastWild
- lstrcpy( (PSZ)pdlf->szLastFile, lpchFile);
- }
- /* set edit box to resulting name */
- WinSetWindowText(WinWindowFromID(hwnd, ID_EDIT),
- (PSZ)pdlf->szFileName);
- }
- break;
-
- case LN_ENTER:
- /* get text from edit box */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)pdlf->szFileName);
- Upper((PSZ)pdlf->szFileName);
- if( DlgSearchSpec( (PSZ)pdlf->szFileName))
- {
- DlgDirList( hwnd
- , (PSZ)pdlf->szFileName
- , ID_DIRLIST
- , ID_FILELIST
- , ID_PATH
- , pdlf->rgbFlags );
- lstrcpy( (PSZ)pdlf->szLastWild
- , FileInPath( (PSZ)pdlf->szFileName));
- lstrcpy( (PSZ)pdlf->szFileName, (PSZ)pdlf->szLastFile);
- WinSetWindowText( WinWindowFromID( hwnd, ID_EDIT)
- , (PSZ)pdlf->szFileName );
- }
- break;
- }
- break;
-
- case ID_FILELIST:
- /* user clicked in file list box */
- switch (SHORT2FROMMP(mp1))
- {
- case LN_SELECT:
- /* single click case */
-
- /* get current edit string */
- /* if it contains a wildcard, save it before obliteration */
- WinQueryWindowText(WinWindowFromID(hwnd, ID_EDIT),
- CBROOTNAMEMAX, (PSZ)sz);
- Upper((PSZ)sz);
- if( DlgSearchSpec( (PSZ)sz))
- lstrcpy( (PSZ)pdlf->szLastWild, FileInPath( (PSZ)sz));
-
- /* get selected file name */
- DlgDirSelect(hwnd, (PSZ)pdlf->szFileName, ID_FILELIST);
- /* set edit box to resulting name */
- WinSetWindowText(WinWindowFromID(hwnd, ID_EDIT),
- (PSZ)pdlf->szFileName);
- break;
-
- case LN_ENTER:
- /* double click case, single click already processed */
- DlgSaveAsName(hwnd, pdlf);
- break;
- }
- break;
- }
- break;
-
- default:
- return (WinDefDlgProc(hwnd, msg, mp1, mp2));
- }
-
- return (MRFROMLONG(0L)); /* message processed */
- }
-
-
-
- /****************************************************************************
- /*
- /* This function attempts to open a file for writing. It queries if over-
- /* write is OK if the file already exists.
- /*
- /****************************************************************************
- VOID PASCAL DlgSaveAsName( hwnd, pdlf)
- HWND hwnd;
- PDLF pdlf;
- {
- USHORT usTdf;
-
- /* add extension if there is not one already */
- AddExt((PSZ)pdlf->szFileName, pdlf->pszExt);
- /* test file name legality */
- if (!DlgParseFile((PSZ)pdlf->szFileName,
- (PSZ)pdlf->szOpenFile, FALSE, FALSE))
- {
- /* illegal filename */
- DlgAlertBox(hwnd, IDS_IFN, pdlf,
- MB_OK | MB_ICONEXCLAMATION);
- return;
- }
- usTdf = TDF_NEWSAVE;
- /* test if file already exists */
- if (DlgParseFile((PSZ)pdlf->szFileName,
- (PSZ)pdlf->szOpenFile, TRUE, FALSE))
- {
- /* overwrite? */
- if (DlgAlertBox(hwnd, IDS_REF, pdlf,
- MB_YESNO | MB_DEFBUTTON2 | MB_ICONQUESTION)
- == MBID_NO)
- return;
- usTdf = TDF_OLDSAVE;
- }
- if (!(pdlf->rgbAction & DLG_NOOPEN) &&
- !(OpenFile( (PSZ)pdlf->szFileName
- , pdlf->phFile
- , (PSZ)pdlf->szOpenFile
- , OF_WRITE)))
- {
- DlgAlertBox(hwnd, IDS_EOF, pdlf,
- MB_OK | MB_ICONEXCLAMATION);
- return;
- }
- WinDismissDlg(hwnd, usTdf);
- }
-
-
-
- /****************************************************************************
- * This function initializes the SaveAs dialog box. It puts the current
- * directory string in the ID_PATH field and initializes the edit box
- * with the proposed filename. It is the simple relative file name if current
- * dir == pdlf->szOpenFile. Otherwise, it is the fully qualified name.
- \****************************************************************************
-
- VOID PASCAL DlgInitSaveAs (hwnd, lpParm)
- HWND hwnd;
- ULONG lpParm;
- {
- PDLF pdlf;
- CHAR sz[MAX_FNAME_LEN];
- PSZ lpszFile, lpszFN, lpszCD;
-
- /* set pdlf local to window */
- pdlf = (PDLF) lpParm;
- WinSetWindowULong(hwnd, 0, lpParm);
-
- /* set edit box text size limit */
- WinSendDlgItemMsg(hwnd, ID_EDIT, EM_SETTEXTLIMIT, (MPARAM)CBROOTNAMEMAX,
-
- /* set title window */
- if (pdlf->pszTitle != (PSZ)NULL)
- WinSetWindowText(WinWindowFromID(hwnd, FID_TITLEBAR), pdlf->pszTitle)
-
- /* set szLastWild to search spec */
- if (pdlf->pszExt != (PSZ)NULL)
- lstrcpy( (PSZ)pdlf->szLastWild, (PSZ)pdlf->pszExt+1 );
-
- /* get current directory */
- DosSearchPath(0, (PSZ)szDot, (PSZ)szStarStar, (PSZ)sz, MAX_FNAME_LEN);
- lpszFile = FileInPath((PSZ)sz);
- if (lpszFile > (PSZ)sz + 3)
- lpszFile--;
- *lpszFile = '\0';
-
- /* compare path part name to previously opened file name and
- make the file name relative if they are the same */
- lpszFN = (PSZ)pdlf->szOpenFile;
- lpszCD = (PSZ)sz;
- lpszFile = FileInPath((PSZ)pdlf->szOpenFile);
- while (lpszFN < lpszFile && *lpszFN == *lpszCD)
- {
- lpszFN = NextChar(lpszFN);
- lpszCD = NextChar(lpszCD);
- }
- if (*lpszCD)
- lpszFN = (PSZ)pdlf->szOpenFile;
- else if (*lpszFN == '\\')
- lpszFN = NextChar(lpszFN);
- Upper( lpszFN);
- WinSetWindowText(WinWindowFromID(hwnd, ID_EDIT), lpszFN);
- lstrcpy( (PSZ)pdlf->szLastFile, lpszFN);
-
- /* set current path field */
- WinSetWindowText(WinWindowFromID(hwnd, ID_PATH),
- DlgFitPathToBox(hwnd, ID_PATH, (PSZ)sz));
- }
-
-
-
-
- /****************************************************************************
- * This function returns the filename part of the given path string.
- \****************************************************************************
-
- PSZ EXPENTRY FileInPath(lpsz)
- PSZ lpsz;
- {
- PSZ lpch;
-
- /* strip path/drive specification from name if there is one */
- lpch = lpsz + lstrlen(lpsz);
- while (lpch > lpsz)
- {
- lpch = PrevChar(lpsz, lpch);
- if (*lpch == '\\' || *lpch == ':')
- {
- lpch = NextChar(lpch);
- break;
- }
- }
- return(lpch);
- }
-
-
-
-
- /****************************************************************************
- * This function adds the extension to a file name if it is missing.
- \****************************************************************************
-
- VOID EXPENTRY AddExt(lpsz, lpszExt)
- PSZ lpsz;
- PSZ lpszExt;
- {
- PSZ lpch;
-
- lpch = lpsz + lstrlen(lpsz);
- while (*lpch != '.' && *lpch != '\\' && *lpch != ':' && lpch > lpsz)
- lpch = PrevChar(lpsz, lpch);
-
- if (*lpch != '.')
- lstrcat(lpsz, (PSZ)(lpszExt+2));
- }
-
-
-
-
- /****************************************************************************
- * This function adds the "appropriate" extension to a filename, partial
- * filename, search spec or partial search spec.
- \****************************************************************************
-
- VOID PASCAL DlgAddSearchExt(pdlf, lpszEdit)
- PDLF pdlf;
- PSZ lpszEdit;
- {
- PSZ lpchLast;
-
- lpchLast = PrevChar(lpszEdit, lpszEdit + lstrlen(lpszEdit));
- if (*lpchLast == '\\' || *lpchLast == ':')
- lstrcat(lpszEdit, pdlf->pszExt + 1);
- else
- lstrcat(lpszEdit, pdlf->pszExt);
- }
-
-
-
-
- /****************************************************************************
- * This function returns TRUE if lpsz contains a wildcard character '*' or '?'
- \****************************************************************************
-
- BOOL PASCAL DlgSearchSpec(lpsz)
- PSZ lpsz;
- {
- for (; *lpsz; lpsz = NextChar(lpsz))
- if (*lpsz == '*' || *lpsz == '?')
- return TRUE;
- return FALSE;
- }
-
-
-
-
- /****************************************************************************
- * This function displays an error or warning msg.
- \****************************************************************************
-
- int PASCAL DlgAlertBox(hwnd, ids, pdlf, wStyle)
- HWND hwnd;
- int ids;
- PDLF pdlf;
- USHORT wStyle;
- {
- /* note: 5th param is idHelp */
- return (AlertBox(hwnd, ids, (PSZ)pdlf->szFileName, pdlf->pszAppName,
- NULL, wStyle | MB_APPLMODAL));
- }
-
-
- FILE1.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\OPENDLG\FILE1.C
-
- /*
- FILE1.C -- Dialog Directory Listbox and Open File functions
- Created by Microsoft Corporation, 1989
- */
-
- #define INCL_DOS
- #include "tool.h"
-
- /****************************************************************************
- * This function builds a directory list in a list box.
- \****************************************************************************
-
- int FAR PASCAL DlgDirList(hwnd, lpszPath, idDirList, idFileList,
- idStaticPath, attr)
- HWND hwnd;
- PSZ lpszPath;
- int idDirList;
- int idFileList;
- int idStaticPath;
- USHORT attr;
- {
- CHAR szPath[MAX_FNAME_LEN];
- CHAR chTmp;
- PSZ lpszFile, lpszNull;
- HPOINTER hPointer;
-
- /* ensure path is legal and expand to full search path */
- if (!DlgParseFile(lpszPath, (PSZ)szPath, FALSE, TRUE))
- return FALSE;
-
- /* set pointer to hours glass */
- hPointer = WinQueryPointer(HWND_DESKTOP);
- WinSetPointer(HWND_DESKTOP, WinQuerySysPointer(HWND_DESKTOP, SPTR_WAIT, F
-
- /* set current drive */
- DosSelectDisk(*szPath - 'A' + 1);
-
- /* temporarily put zero after directory spec and set current directory */
- lpszFile = FileInPath((PSZ)szPath);
- lpszNull = lpszFile;
- if (lpszNull > (PSZ)szPath + 3)
- lpszNull--;
- chTmp = *lpszNull;
- *lpszNull = '\0';
- DosChDir((PSZ)szPath, 0l);
- if (idStaticPath)
- WinSetWindowText(WinWindowFromID(hwnd, idStaticPath),
- DlgFitPathToBox(hwnd, idStaticPath, (PSZ)szPath));
- *lpszNull = chTmp;
-
- /* fill list box with file names */
- if (idDirList && idFileList)
- {
- /* fill them up with new entries */
- DlgFillListBoxes(hwnd, idDirList, idFileList, attr, lpszFile);
- }
-
- /* reset pointer to previous figure */
- WinSetPointer(HWND_DESKTOP, hPointer);
-
- return TRUE;
- }
-
-
-
-
- /****************************************************************************
- * This function gets the file name selected by the user.
- \****************************************************************************
-
- int FAR PASCAL DlgDirSelect(hwnd, lpszIn, idListBox)
- HWND hwnd;
- PSZ lpszIn;
- int idListBox;
- {
- CHAR sz[MAX_FNAME_LEN];
- int item;
- PSZ lpsz, lpszFile;
- BOOL fDir;
-
- /* get currently selected list entry */
- item = (int) SHORT1FROMMR(WinSendDlgItemMsg(hwnd, idListBox, LM_QUERYSELE
- if (item == LIT_NONE)
- return FALSE;
- WinSendDlgItemMsg(hwnd, idListBox, LM_QUERYITEMTEXT,
- MPFROM2SHORT(item, MAX_FNAME_LEN), (MPARAM)(PSZ)sz);
- lpszFile = sz;
-
- /* extract name */
- if (fDir = (*sz == '['))
- {
- lpszFile = NextChar(lpszFile);
- if (*lpszFile == '-')
- {
- /* drive selection */
- lpszFile = NextChar(lpszFile);
- *(lpszFile+1) = ':';
- *(lpszFile+2) = '\0';
- }
- else
- {
- /* directory selection */
- lpsz = lpszFile;
- while (*lpsz != ']')
- lpsz = NextChar(lpsz);
- *lpsz = '\\';
- }
- }
-
- lstrcpy(lpszIn, lpszFile);
- return (fDir);
- }
-
-
-
-
- /****************************************************************************
- * This function tries to open pdlf=>szFileName. If the file does not
- * exist, the function asks to create it.
- *
- * Returns:
- * TDF_NOOPEN - Illegal Filename or user didn't want to create
- * TDF_OLDOPEN - Existing file
- * TDF_NEWOPEN - File was created
- \****************************************************************************
-
- USHORT PASCAL DlgOpenFile(pdlf, hwnd)
- PDLF pdlf;
- HWND hwnd;
- {
- /* check for legal dos name */
- if (!DlgParseFile((PSZ)pdlf->szFileName, (PSZ)pdlf->szOpenFile,
- FALSE, FALSE))
- {
- DlgAlertBox(hwnd, IDS_IFN, pdlf, MB_OK | MB_ICONEXCLAMATION);
- return (TDF_NOOPEN);
- }
- /* see if file already exists */
- if (DlgParseFile((PSZ)pdlf->szFileName, (PSZ)pdlf->szOpenFile,
- TRUE, FALSE))
- {
- if (OpenFile((PSZ)pdlf->szFileName, pdlf->phFile,
- (PSZ)pdlf->szOpenFile, OF_READ))
- return (TDF_OLDOPEN);
- else
- {
- DlgAlertBox(hwnd, IDS_EOF, pdlf, MB_OK | MB_ICONEXCLAMATION);
- return (TDF_NOOPEN);
- }
- }
- /* file doesn't exist: create new one? */
- else if (DlgAlertBox(hwnd, IDS_FNF, pdlf, MB_YESNO | MB_ICONQUESTION) ==
- {
- if (OpenFile((PSZ)pdlf->szFileName, pdlf->phFile,
- (PSZ)pdlf->szOpenFile, OF_CREATE))
- return (TDF_NEWOPEN);
- else
- DlgAlertBox(hwnd, IDS_ECF, pdlf, MB_OK | MB_ICONEXCLAMATION);
- }
- return(TDF_NOOPEN);
- }
-
-
-
-
- /****************************************************************************
- * This function returns the OS/2 file handle if operation is successful,
- * 0 otherwise.
- *
- * Effects: Depend on wMode:
- * OF_READ: open file for reading only
- * OF_WRITE: open file for writing only
- * OF_READWRITE: open file for reading and writing
- * OF_CREATE: create the file if it does not exist
- * OF_REOPEN: open file using info in the reopen buffer
- * OF_EXIST: test file existence
- * OF_PARSE: fill reopen buffer, with no other action
- \****************************************************************************
-
-
- BOOL EXPENTRY OpenFile(lpszFile, lpHandle, lpszOpenFile, wMode)
- PSZ lpszFile;
- PHFILE lpHandle;
- PSZ lpszOpenFile;
- USHORT wMode;
- {
- HFILE hFile = NULL;
- USHORT wAction = NULL;
- USHORT wAttrs = NULL;
- USHORT wOpenFlag, wOpenMode;
- CHAR sz[MAX_FNAME_LEN];
-
- /* if reopen specified, use earlier pathname */
- if (wMode & OF_REOPEN)
- {
- lstrcpy((PSZ)sz, lpszOpenFile);
- lpszFile = (PSZ)sz;
- }
-
- /* parse file */
- if (!DlgParseFile(lpszFile, lpszOpenFile, wMode&OF_EXIST, FALSE))
- {
- *lpszOpenFile = '\0';
- return FALSE;
- }
- /* return if implementing boolean test OF_PARSE or OF_EXIST */
- if (wMode & (OF_PARSE | OF_EXIST))
- {
- return TRUE;
- }
-
- if (wMode & OF_READ)
- {
- wOpenFlag = 0x01; /* fail if it doesn't exist */
- wOpenMode = 0x20; /* read only */
- }
- else if (wMode & OF_WRITE)
- {
- wOpenFlag = 0x11; /* create if necessary */
- wOpenMode = 0x11; /* write only */
- }
- else if (wMode & OF_READWRITE)
- {
- wOpenFlag = 0x11; /* create if necessary */
- wOpenMode = 0x12; /* read-write */
- }
- else if (wMode & OF_CREATE)
- {
- /* create and close file */
- wOpenFlag = 0x10; /* fail if exists */
- wOpenMode = 0x10; /* read only */
- }
- else
- {
- return FALSE;
- }
-
- if (DosOpen(lpszFile, (PHFILE)&hFile, &wAction,
- (ULONG) 0, 0, wOpenFlag, wOpenMode, (ULONG) 0))
- return FALSE;
-
- if (wMode & OF_CREATE)
- {
- if (DosClose(hFile))
- return FALSE;
- }
- else
- *lpHandle = hFile;
-
- return TRUE;
- }
-
-
-
-
- /****************************************************************************
- * This function puts a path string into a static box.
- \****************************************************************************
-
- PSZ PASCAL DlgFitPathToBox(hwnd, idStatic, lpch)
- HWND hwnd;
- int idStatic;
- PSZ lpch;
- {
- WRECT rc;
- int cxField;
- char chDrive;
- HPS hps;
-
- /* get length of static field */
- WinQueryWindowRect(WinWindowFromID(hwnd, idStatic), (PRECTL)&rc);
- cxField = rc.xRight - rc.xLeft;
-
- hps = WinGetPS(hwnd);
- if (cxField < (int) LOUSHORT(GetTextExtent(hps, lpch,
- lstrlen(lpch))))
- {
- chDrive = *lpch;
- /* chop characters off front of string until text is short enough */
- do
- do
- lpch = NextChar(lpch);
- while (*(lpch+6) != '\\' &&
- *(lpch+6) != '\0');
- while (cxField < (int) LOUSHORT(GetTextExtent(hps, lpch,
- lstrlen(lpch))));
- /* insert header */
- *lpch++ = chDrive;
- *lpch++ = ':';
- *lpch++ = '\\';
- *lpch++ = '.';
- *lpch++ = '.';
- *lpch++ = '.';
- lpch -= 6;
- }
- WinReleasePS(hps);
- return (lpch);
- }
-
-
-
-
- /****************************************************************************
- * This function fills a list box with appropriate file names from the
- * current directory.
- \****************************************************************************
-
- int PASCAL DlgFillListBoxes(hwnd, idDirList, idFileList, attr, lpszFileSpec)
- HWND hwnd;
- int idDirList;
- int idFileList;
- USHORT attr;
- PSZ lpszFileSpec;
- {
- USHORT usFiles, usDrive;
- int i;
- PSZ lpsz;
- HDIR hDir;
- ULONG lrgfDrives;
- FILEFINDBUF ffb;
- CHAR sz[20];
- int cDrives;
- int result = -1;
- HWND hwndFiles, hwndDirs;
-
- /* get listbox window handles */
- hwndFiles = WinWindowFromID(hwnd, idFileList);
- hwndDirs = WinWindowFromID(hwnd, idDirList);
-
- /* disable updates to listboxes */
- WinEnableWindowUpdate(hwndFiles, FALSE);
- WinEnableWindowUpdate(hwndDirs, FALSE);
-
- /* empty list boxes of any old entries */
- WinSendMsg(hwndFiles, LM_DELETEALL, 0L, 0L);
- WinSendMsg(hwndDirs, LM_DELETEALL, 0L, 0L);
-
- /* put files that lMatch search spec in file listbox */
- usFiles = 1;
- hDir = 0xFFFF;
- if (!DosFindFirst(lpszFileSpec, (PHDIR)&hDir,
- attr&~(BITATTRDIR|BITATTRDRIVE), (PFILEFINDBUF)&ffb, sizeof(FILEFINDB
- &usFiles, 0L))
- {
- do
- {
- /* add string to list box */
- result = (int) SHORT1FROMMR(WinSendMsg(hwndFiles, LM_INSERTITEM,
- MPFROM2SHORT(LIT_SORTASCENDING, 0),
- (MPARAM)(PSZ)&(ffb.achName[0])));
- usFiles = 1;
- }
- while (result >= 0 && !DosFindNext(hDir,
- (PFILEFINDBUF)&ffb,
- sizeof(FILEFINDBUF),
- &usFiles));
- DosFindClose(hDir);
- }
-
- if (result != LIT_MEMERROR && (attr & BITATTRDIR))
- {
- /* get directories */
- usFiles = 1;
- hDir = 0xFFFF;
- if (!DosFindFirst((PSZ)szStarStar, (PHDIR)&hDir, BITATTRDIR,
- (PFILEFINDBUF)&ffb, sizeof(FILEFINDBUF), &usFiles, 0l))
- {
- do
- {
- /* extract file name */
- if (ffb.attrFile & BITATTRDIR)
- {
- /* put brackets around directory */
- lpsz = (PSZ)&(ffb.achName[0]);
- if (*lpsz == '.' && *(lpsz+1) == '\0')
- /* forget about current directory name '.' */
- continue;
- sz[0] = '[';
- lstrcpy((PSZ)&sz[1], lpsz);
- sz[ffb.cchName + 1] = ']';
- sz[ffb.cchName + 2] = '\0';
- lpsz = (PSZ)sz;
- /* add string to list box */
- result = (int) SHORT1FROMMR(WinSendMsg(hwndDirs, LM_INSER
- MPFROM2SHORT(LIT_SORTASCENDING,
- (MPARAM)lpsz));
- }
- usFiles = 1;
- }
- while (result >= -1 && !DosFindNext(hDir,
- (PFILEFINDBUF)&ffb,
- sizeof(FILEFINDBUF),
- &usFiles));
- DosFindClose(hDir);
- }
- }
-
- if (result != LIT_MEMERROR && (attr & BITATTRDRIVE))
- /* get drives */
- {
- sz[0] = '[';
- sz[1] = sz[3] = '-';
- sz[4] = ']';
- sz[5] = '\0';
-
- DosQCurDisk(&usDrive, (unsigned long far *)&lrgfDrives);
- cDrives = 0;
- for (i=0; 'A' + i <= 'Z'; i++)
- {
- if (lrgfDrives & 1L)
- {
- sz[2] = (char)('A' + i);
- /* add drive to list */
- result = (int) SHORT1FROMMR(WinSendMsg(hwndDirs, LM_INSERTITE
- MPFROM2SHORT(LIT_END, 0),
- (MPARAM)(PSZ)sz));
- cDrives++;
- }
- lrgfDrives >>= 1;
- }
- }
-
- /* enable and show updated listboxes */
- WinShowWindow(hwndFiles, TRUE);
- WinShowWindow(hwndDirs, TRUE);
-
- return result;
- }
-
-
-
-
- /****************************************************************************
- * This function parses a string into an fully expanded file name or search
- * path. If fExist is true then the file must exist or the search path must
- * correspond to at least one existing file. In all cases, the corresponding
- * directory must exist. The string must be a file name, ie. no wildcards,
- * unless fWildOkay is true. Returns TRUE if string is parsed correctly.
- \****************************************************************************
-
- BOOL PASCAL DlgParseFile(lpszIn, lpszExp, fExist, fWildOkay)
- PSZ lpszIn, lpszExp;
- BOOL fExist, fWildOkay;
- {
- CHAR szPath[MAX_FNAME_LEN];
- PSZ lpszFile, lpsz;
-
- /* go past any path spec to first char in file name */
- lpszFile = FileInPath(lpszIn);
-
- /* check validity of file name */
- if (!fExist && !DlgValidName(lpszFile, fWildOkay))
- {
- *lpszExp = '\0';
- return FALSE;
- }
-
- /* copy path part to path string */
- lpsz = (PSZ)szPath;
- if (lpszIn == lpszFile)
- *lpsz++ = '.';
- else
- {
- while (lpszIn < lpszFile && lpsz < ((PSZ)szPath + MAX_FNAME_LEN - 1))
- *lpsz++ = *lpszIn++;
- }
- *lpsz = '\0';
-
- /* let DOS do the dirty work */
- if (fExist)
- {
- /* test existence of file while parsing path */
- if (DosSearchPath(0, (PSZ)szPath, lpszFile, lpszExp, MAX_FNAME_LEN))
- {
- *lpszExp = '\0';
- return FALSE;
- }
- }
- else
- {
- /* use dummy wild card while parsing path */
- if (DosSearchPath(0, (PSZ)szPath, (PSZ)szStarStar, lpszExp, MAX_FNAME
- {
- *lpszExp = '\0';
- return FALSE;
- }
- /* replace wild card part with true file name converted to CAPS */
- lpsz = lpszExp;
- while (*lpsz != '?' && *lpsz != '*' && *lpsz != '\0')
- lpsz++;
- while (*lpszFile != '\0')
- {
- *lpsz++ = *lpszFile++;
- }
- *lpsz = '\0';
- Upper(lpszExp);
- }
- return TRUE;
- }
-
-
-
-
- /****************************************************************************
- * This function determines if a string forms a legal file name or search
- * path. Wildcard characters are acceptable if fWildOkay is true. Returns
- * TRUE if string is legal.
- \****************************************************************************
-
- BOOL PASCAL DlgValidName(lpszName, fWildOkay)
- PSZ lpszName;
- BOOL fWildOkay;
- {
- int cLen;
- PSZ lpsz;
-
- /* check file name */
- if (*lpszName == '\0')
- return FALSE;
- cLen = 0;
- lpsz = lpszName;
- while (*lpsz != '\0' && *lpsz != '.')
- {
- if (++cLen > 8 || *lpsz < 0x20)
- return FALSE;
- switch (*lpsz++)
- {
- case '*':
- case '?':
- if (fWildOkay)
- break;
- case '\"':
- case '\\':
- case '/':
- case '[':
- case ']':
- case ':':
- case '|':
- case '<':
- case '>':
- case '+':
- case '=':
- case ';':
- case ',':
- return FALSE;
- }
- }
-
- /* check extension */
- if (*lpsz++ == '\0')
- return TRUE;
- cLen = 0;
- while (*lpsz != '\0')
- {
- if (++cLen > 3 || *lpsz < 0x20)
- return FALSE;
- switch (*lpsz++)
- {
- case '*':
- case '?':
- if (fWildOkay)
- break;
- case '.':
- case '\"':
- case '\\':
- case '/':
- case '[':
- case ']':
- case ':':
- case '|':
- case '<':
- case '>':
- case '+':
- case '=':
- case ';':
- case ',':
- return FALSE;
- }
- }
- return TRUE;
- }
-
-
- GPI.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\OPENDLG\GPI.C
-
- /***************************************************************************\
- * GPI.C -- GPI Helper routines
- * Created by Microsoft Corporation, 1989
- \***************************************************************************/
-
-
- #define INCL_GPI
- #include "tool.h"
-
- /***************************************************************************\
- * GetTextExtent helper function
- \***************************************************************************/
-
- ULONG EXPENTRY GetTextExtent(HPS hps, PCH lpstr, int cch) {
- POINTL rgptl[TXTBOX_COUNT];
-
- if (cch) {
- GpiQueryTextBox(hps, (LONG)cch, lpstr, 5L, rgptl);
- return(MAKEULONG((SHORT)(rgptl[TXTBOX_CONCAT].x - rgptl[TXTBOX_BOTTOM
- (SHORT)(rgptl[TXTBOX_TOPLEFT].y - rgptl[TXTBOX_BOTTOMLEF
- } else
- return(0L);
- }
-
-
- HANOI.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\HANOI\HANOI.C
-
- /*************************************************************
-
- This program implements a tower of hanoi program. This
- sample app was written to demonstrate the use of a multi-
- threaded program. The main thread handles the PM interface,
- the second thread is started to do the recursive execution
- of the hanoi algorithm.
-
- This program was written by Jeff Johnson, 7/89.
-
- Procedures in this file:
- main() Sets up the PM environment and heap and
- calls the main window procedure ClientWndProc
- ClientWndProc() Handles the main window messages
- CalcThread() Sets up and terminates the secondary thread
- DrawDisk() Draws or erases a disk on one of the poles
- MoveDisk() Moves a disk from one pole to another
- Hanoi() Recursive alogrithm for tower of hanoi prog
- EnableMenuItem() Activates/deactivates a menu choice
- EntryFldDlgProc() Handles the set number of disks dialog box
- SetupTowers() Sets up the global tower data
-
- **************************************************************/
-
- #include "hanoi.h"
-
-
- /********************* GLOBALS *******************************/
-
- CHAR szClientClass[] = "Hanoi";
-
- /* Note that this use of global data precludes multiple windows
- of hanoi running at the same time. Thus, from an object-
- oriented perspective, this is less than desireable and the
- data should be passed into the window, rather than used
- explicitly. */
-
- BYTE abTowers[3][MAXDISKCNT]; /* Used to hold disk numbers on each post *
- BYTE abTowersNdx[3]; /* Current number of disks on each post *
- BYTE cTowerSize = DEFAULTSIZE; /* Holds the total number of disks */
- USHORT ausPolePos[3]= { POSTOFFSET, /* Holds offset drawing information *
- POSTOFFSET + POSTSPACE,
- POSTOFFSET + 2*POSTSPACE };
- ULONG ulIterations;
-
- /*************************************************************/
-
-
- /*
- * Function name: main()
- *
- * Parameters: argc, argv. If the user places a number (1 thru MAXDISKCNT)
- * on the command line, that number will become the default
- * number of disks on the stack. Otherwise there will be
- * DEFUALTSIZE disks initially.
- *
- * Returns: Always returns 0
- *
- * Purpose: Parses the command line, sets up the PM environment, prepares
- * the Tower arrays, calls the main window proc, handles the
- * window's messages then cleans up and exits.
- *
- * Usage/Warnings:
- *
- * Calls: ClientWndProc() (thru PM)
- */
-
- int main(int argc, char *argv[])
- {
- HAB hab;
- HMQ hmq;
- HWND hwndFrame, hwndClient;
- QMSG qmsg;
-
- ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU | FCF_MINBUTTON |
- FCF_SHELLPOSITION | FCF_MENU | FCF_TASKLIST |
- FCF_ICON | FCF_BORDER | FCF_ACCELTABLE;
-
- SHORT sHold;
-
- if(argc > 1) /* If command line arg, use as the initial number of disks *
- {
- sHold = atoi(argv[1]);
- if(sHold>0 && sHold<=MAXDISKCNT)
- cTowerSize = (BYTE) sHold;
- }
- SetupTowers();
-
- /* These PM calls should be error checked */
- hab = WinInitialize(0);
- hmq = WinCreateMsgQueue(hab, 0);
-
- if(!WinRegisterClass(hab, szClientClass,ClientWndProc,0L,0))
- {
- WinAlarm(HWND_DESKTOP, WA_ERROR); /* Register failed */
- DosExit(EXIT_PROCESS,1);
- }
-
- hwndFrame = WinCreateStdWindow(HWND_DESKTOP, WS_VISIBLE,
- &flFrameFlags, szClientClass, NULL,
- 0L, (HMODULE) NULL, ID_MAINMENU, &hwndClien
- if(!hwndFrame)
- {
- WinAlarm(HWND_DESKTOP, WA_ERROR); /* Window create failed */
- DosExit(EXIT_PROCESS,1);
- }
-
- while(WinGetMsg(hab,&qmsg,NULL,0,0)) /* Message loop */
- WinDispatchMsg(hab,&qmsg);
-
- WinDestroyWindow(hwndFrame); /* Clean up */
- WinDestroyMsgQueue(hmq);
- WinTerminate(hab);
- return 0;
- }
-
-
- /*
- * Function name: ClientWndProc()
- *
- * Parameters: hwnd, msg, mp1, mp2. Standard PM Window Proc params.
- * No user data is expected in the WM_CREATE.
- *
- * Returns:
- *
- * Purpose: Handles all the messages associated with the main window
- * and calls the appropriate handling procedures.
- *
- * Usage/Warnings: Called only by main(). Note that when WM_PAINT executes,
- * the secondary thread may change data during the update
- * which may cause a problem. However, this is NOT a write
- * conflict, as only 1 thread does the writing.
- *
- * Calls: DrawDisk(), CalcThread() (thru Thread), EntryFldDlgProc() (thru PM
- */
-
- MRESULT EXPENTRY ClientWndProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- HPS hps; /* Handle for painting */
- RECTL rcl; /* Rectangle struct for painting */
- POINTL ptl; /* Point struct for painting */
- BYTE cPole,bCnt,bHeight,cnt; /* Utility variables */
- CHAR szMsg[MSGBUFSIZE]; /* sprintf buffer */
- static CALCPARAM cp; /* Struct used to notify thread */
- static TID tidCalc; /* Secondary thread ID */
- static VOID *pThreadStack; /* Pointer to secondary stack */
-
- switch(msg)
- {
- case WM_PAINT:
- hps = WinBeginPaint(hwnd,NULL,NULL); /* Get paint handle */
- WinQueryWindowRect(hwnd,&rcl);
-
- DrawRect(rcl.xLeft,rcl.yBottom, /* White out the screen */
- rcl.xRight,rcl.yTop,CLR_WHITE);
-
- /* Draw the base */
- DrawRect(BASEXOFFSET, BASEYOFFSET,
- BASEXOFFSET+BASELEN-1, BASEYOFFSET+BASETHICK-1,
- CLR_DARKGREEN);
-
- /* Draw the 3 posts */
- bHeight = (BYTE) (cTowerSize*DISKSPACE + POSTEXTRAHT);
- for(cnt=0;cnt<3;cnt++)
- {
- DrawRect(ausPolePos[cnt]-POSTHALF, BASEYOFFSET,
- ausPolePos[cnt]-POSTHALF+POSTWIDTH,bHeight,
- CLR_DARKGREEN);
- }
-
- /* Place the appropriate disks on each pole */
- for(cPole=0;cPole<3;cPole++)
- {
- for(bCnt=0;bCnt<abTowersNdx[cPole];bCnt++)
- {
- DrawDisk(hps,cPole,bCnt,fDRAW);
- }
- }
-
- WinEndPaint(hps);
- return 0L;
-
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd)
- {
- case IDM_START:
- /* Try to get stack space */
- if((pThreadStack = malloc(STACKSIZE)) == NULL)
- {
- WinAlarm(HWND_DESKTOP, WA_ERROR); /* Couldn't get memory *
- return 0L;
- }
- cp.hwnd = hwnd; /* Set the static struct */
- cp.fContinueCalc = TRUE;
- ulIterations = 0; /* Zero iteration counter */
-
- /* Try to start the thread */
- if((tidCalc = _beginthread(CalcThread,pThreadStack,
- STACKSIZE, &cp)) == -1)
- {
- free(pThreadStack); /* Thread wouldn't start */
- WinAlarm(HWND_DESKTOP, WA_ERROR);
- return 0L;
- }
- /* Disallow menu items that could change data while the second
- thread is running */
- EnableMenuItem(hwnd,IDM_START,FALSE); /* Disable Start & set *
- EnableMenuItem(hwnd,IDM_SET,FALSE);
- EnableMenuItem(hwnd,IDM_STOP,TRUE); /* Enable Stop item *
- return 0L;
-
- case IDM_STOP:
- cp.fContinueCalc = FALSE; /* Notify thread to quit *
- return 0L;
-
- case IDM_SET:
- if(WinDlgBox(HWND_DESKTOP, hwnd, /* Pop up the query/set box *
- EntryFldDlgProc,(HMODULE) NULL,ID_SETCOUNT,NULL))
- {
- SetupTowers(); /* Reset towers *
- WinInvalidateRect(hwnd,NULL,FALSE); /* Force a redraw *
- }
- return 0L;
-
- default:
- return WinDefWindowProc(hwnd, msg, mp1, mp2);
- }
-
- case UM_CALC_DONE:
- EnableMenuItem(hwnd,IDM_START,TRUE); /* Reenable Start & set *
- EnableMenuItem(hwnd,IDM_SET,TRUE);
- EnableMenuItem(hwnd,IDM_STOP,FALSE); /* Disable stop *
- free(pThreadStack); /* Free thread's stack space *
-
- sprintf(szMsg,"%lu disks were moved.",ulIterations); /* Print msg *
- WinMessageBox(HWND_DESKTOP, hwnd, szMsg, "Done!", 0, MB_OK);
-
- SetupTowers(); /* Reset towers *
- WinInvalidateRect(hwnd,NULL,FALSE); /* Force a screen redraw *
- return 0L;
-
- default:
- return WinDefWindowProc(hwnd, msg, mp1, mp2);
- }
- }
-
-
- /*
- * Function name: CalcThread()
- *
- * Parameters: pcp is a struct which contains the hwnd handle and the
- * continue flag which is initially set to TRUE.
- *
- * Returns: VOID
- *
- * Purpose: Calls the recursive Hanoi with initial setting of 0,2,1 meaning
- * from pole 0, to pole 2, using pole 1 as a temporary. Hanoi
- * returns when finished, or the user says stop. This proc then
- * sets a critical section so the posted message won't be handled
- * until the thread is terminated.
- *
- * Usage/Warnings: No DosExitCritSec() is called since _endthread() supposedl
- * clears the critical section when the thread is
- * terminated.
- *
- * Calls: Hanoi()
- */
-
- VOID _cdecl FAR CalcThread(PCALCPARAM pcp)
- {
- HAB hab;
-
- hab = WinInitialize(0); /* Called to increase Ring 2 stack size */
- Hanoi(pcp,cTowerSize,0,2,1); /* Execute the recursive routine */
- WinTerminate(hab);
-
- DosEnterCritSec(); /* Set Crit so the UM_CALC_DONE isn't processed */
- /* until this thread has completely terminated */
- WinPostMsg(pcp->hwnd,UM_CALC_DONE,NULL,NULL); /* Post done */
-
- _endthread(); /* Terminate thread */
- }
-
-
- /*
- * Function name: DrawDisk()
- *
- * Parameters: hps is a handle to the main PS space.
- * cPole is the pole (0-2) to draw the disk on.
- * bLevel is the number of spaces from the bottom to draw disk.
- * fDraw if =0, erase disk, if =1 draw disk.
- *
- * Returns: VOID
- *
- * Purpose: This routine takes a PS handle, the hanoi spindle and disk level
- * and draws an appropriately sized disk.
- *
- * Usage/Warnings: Does not grab exclusive access to the screen before
- * drawing which may cause a problem.
- *
- * Calls:
- */
-
- VOID DrawDisk(HPS hps,BYTE cPole, BYTE bLevel,BYTE fDraw)
- {
- USHORT usXstart,usYstart,usWidth;
- POINTL ptl;
-
- usYstart = BOTDISKYPOS + DISKSPACE*bLevel; /* Calculate Bottom of disk
-
- usWidth = (MAXDISKWIDTH-MINDISKWIDTH)*abTowers[cPole][bLevel]/cTowerSize
- + MINDISKWIDTH; /* Calculate the disk's width
-
- usXstart = ausPolePos[cPole] - usWidth/2; /* Center disk on pole
-
- if(fDraw == fDRAW) /* If we are to draw the disk */
- {
- DrawRect(usXstart,usYstart,usXstart+usWidth,
- usYstart+DISKTHICK-1,CLR_RED);
- }
- else /* We are to erase the disk, then redraw the pole */
- {
- DrawRect(usXstart,usYstart,usXstart+usWidth,
- usYstart+DISKTHICK-1,CLR_WHITE);
- DrawRect(ausPolePos[cPole]-POSTHALF,usYstart,
- ausPolePos[cPole]-POSTHALF+POSTWIDTH,usYstart+DISKTHICK-1,
- CLR_DARKGREEN);
- }
- }
-
-
- /*
- * Function name: MoveDisk()
- *
- * Parameters: hps is a handle to the main PS space.
- * bFrom is the spindle to take the top disk from.
- * bTo is the spindle to place the disk on.
- *
- * Returns: VOID
- *
- * Purpose: This routine moves the top disk from the bFrom spindle to the top
- * of the bTo spindle.
- *
- * Usage/Warnings: Does error checking for trying to move a disk from a
- * spindle that does not have any disks on it.
- *
- * Calls: MoveDisk()
- */
-
- VOID MoveDisk(HPS hps,BYTE bFrom,BYTE bTo)
- {
- CHAR bTOSndx; /* Top of stack index */
- BYTE bDiskNum; /* Disk number to move */
-
- bTOSndx = (CHAR) (abTowersNdx[bFrom]-1);
- if(bTOSndx < 0)
- return;
-
- DrawDisk(hps,bFrom,bTOSndx,fERASE); /* Remove disk off from stack */
-
- bDiskNum = abTowers[bFrom][bTOSndx]; /* Get move disk number */
- abTowersNdx[bFrom]--; /* Decrease count on from spindle */
-
- bTOSndx = abTowersNdx[bTo]++; /* Offset to place the disk at */
- abTowers[bTo][bTOSndx] = bDiskNum; /* Place on stack in memory */
-
- DrawDisk(hps,bTo,bTOSndx,fDRAW); /* Draw disk on the to stack */
- }
-
-
- /*
- * Function name: Hanoi()
- *
- * Parameters: pcp is a struct which contains the hwnd handle and the
- * continue flag which is initially set to TRUE.
- * bHeight is the number of disks in the from stack to move.
- * bFrom is the from spindle number, 0-2.
- * bTo is the to spindle number.
- * bTemp is the temporary spindle number.
- *
- * Returns: VOID
- *
- * Purpose: This routine implements a recursive hanoi program that works as
- * follows: By recursion, move all the disks, except for the
- * bottom disk to the temporary stack. Then move the bottom
- * disk to the target spindle. Now recursively move the stack
- * on the temporary spindle to the target spindle. The limiting
- * case is when Hanoi() is called with a bHeight of 0 in which
- * case the depth recursion is terminated.
- *
- * Usage/Warnings: This routine checks the ->fContinueCalc flag, which is set
- * by the main thread when the user selects stop, to see if
- * the user wishes to abort the algorithm. If so, it backs
- * out and exits.
- *
- * Calls: MoveDisk()
- */
-
- VOID Hanoi(PCALCPARAM pcp, BYTE bHeight, BYTE bFrom, BYTE bTo, BYTE bTemp)
- {
- HPS hps;
-
- if(bHeight<=0 || !pcp->fContinueCalc) /* Exit up if no more disks or */
- return; /* the user said Stop */
-
- Hanoi(pcp,(BYTE)(bHeight-1),bFrom,bTemp,bTo); /* Move all but bottom disk
-
- if(!pcp->fContinueCalc) /* If user said to stop */
- return;
-
- /* Display bFrom -> bTo */
- hps = WinGetPS(pcp->hwnd);
- MoveDisk(hps,bFrom,bTo); /* Move the bottom disk */
- WinReleasePS(hps);
- ulIterations++;
-
- Hanoi(pcp,(BYTE)(bHeight-1),bTemp,bTo,bFrom); /* Move disks over
- }
-
-
- /*
- * Function name: EnableMenuItem()
- *
- * Parameters: hwnd is a handle of the current window.
- * sMenuItem is the ID of the item to Enable/Disable.
- * fEnable will enable item if TRUE, otherwise disables it.
- *
- * Returns: VOID
- *
- * Purpose: This routine handles enabling/disabling of menu items. This
- * is done by getting Parent and Menu hwnd handles then sending
- * the appropriate message.
- *
- * Usage/Warnings:
- *
- * Calls:
- */
-
- VOID EnableMenuItem(HWND hwnd, SHORT sMenuItem, BOOL fEnable)
- {
- HWND hwndParent = WinQueryWindow(hwnd, QW_PARENT, FALSE);
- HWND hwndMenu = WinWindowFromID(hwndParent, FID_MENU);
-
- WinSendMsg(hwndMenu, MM_SETITEMATTR,
- MPFROM2SHORT(sMenuItem, TRUE),
- MPFROM2SHORT(MIA_DISABLED, fEnable ? 0 : MIA_DISABLED));
- }
-
-
- /*
- * Function name: EntryFldDlgProc()
- *
- * Parameters: hwnd, msg, mp1, mp2. Standard PM Dialog Proc params.
- * No user data is expected in the WM_CREATE.
- *
- * Returns: Terminates with a TRUE iff a new valid Tower Size has been entere
- *
- * Purpose: Handles all the messages associated with the set entry field
- * and calls the appropriate handling procedures. The purpose
- * of this dialog box is to get a new number of disks for the
- * hanoi routine.
- *
- *
- * Usage/Warnings: If the value entered is valid, global cTowerSize is
- * changed to the new value, and TRUE is returned.
- *
- * Calls:
- */
-
- MRESULT EXPENTRY EntryFldDlgProc(HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp
- {
- SHORT sNewSize; /* Holds new number of disks */
-
- switch(msg)
- {
- case WM_INITDLG:
- WinSendDlgItemMsg(hwnd, ID_ENTRYFLD,EM_SETTEXTLIMIT, /* Limit len *
- MPFROM2SHORT(2,0),NULL);
- WinSetDlgItemShort(hwnd, ID_ENTRYFLD,(SHORT) cTowerSize,TRUE);
- return 0L; /* Allow normal focus setting *
-
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd)
- {
- case DID_OK:
- WinQueryDlgItemShort(hwnd, ID_ENTRYFLD,
- &sNewSize, TRUE); /* Get the short *
- if(sNewSize>0 && sNewSize<=MAXDISKCNT) /* Set new Tower size *
- {
- cTowerSize = (BYTE) sNewSize;
- WinDismissDlg(hwnd,TRUE);
- }
- else /* Invalid value *
- WinDismissDlg(hwnd,FALSE);
- return 0L;
-
- case DID_CANCEL:
- WinDismissDlg(hwnd,FALSE);
- return 0L;
-
- default:
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- }
-
- default:
- return WinDefDlgProc(hwnd, msg, mp1, mp2);
- }
- }
-
- /*
- * Function name: SetupTowers()
- *
- * Parameters: None
- *
- * Returns: VOID
- *
- * Purpose: This routine initializes the global arrays that represent the
- * hanoi stacks. This involves placing all the disks on the
- * first peg, emptying the other 2 pegs and setting the associated
- * counts.
- *
- * Usage/Warnings: Calling uses the global variable cTowerSize to determine
- * how many disks there are.
- *
- * Calls:
- */
-
- VOID SetupTowers()
- {
- USHORT cnt;
-
- for(cnt=0;cnt<cTowerSize;cnt++) /* Setup the intial post with disks
- abTowers[0][cnt] = (BYTE)(cTowerSize-cnt-1);
-
- abTowersNdx[0] = cTowerSize; /* Set disk count for initial post
- abTowersNdx[1] = abTowersNdx[2] = 0; /* Zero other post counts
- }
-
-
-
- HELLO.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\OPENDLG\HELLO\HELLO.C
-
- /*
- * HELLO.C -- A simple program which calls the OpenDlg library
- * Created by Microsoft Corporation, 1989
- */
- #define INCL_PM
- #include <os2.h>
- #include <opendlg.h>
- #include "hello.h"
- /*
- * Globals
- */
- HAB hAB;
- HMQ hMqHello;
- HWND hWndHello;
- HWND hWndHelloFrame;
- CHAR szClassName[] = "Hello World";
- CHAR szMessage[] = " - File Dialog Sample";
- CHAR szExtension[] = "\\*.*";
- CHAR szHelp[] = "Help would go here.";
- DLF vdlf;
- HFILE vhFile;
- /*
- * Main routine...initializes window and message queue
- */
- int cdecl main( ) {
- QMSG qmsg;
- ULONG ctldata;
-
- hAB = WinInitialize(0);
-
- hMqHello = WinCreateMsgQueue(hAB, 0);
-
- if (!WinRegisterClass( hAB, (PCH)szClassName, (PFNWP)HelloWndProc,
- CS_SIZEREDRAW, 0))
- return( 0 );
-
- /* Create the window */
- ctldata = FCF_STANDARD & ~(FCF_ACCELTABLE);
- hWndHelloFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE, &ctldata,
- szClassName, szMessage,
- WS_VISIBLE, (HMODULE) NULL, ID_RESOU
- (HWND FAR *)&hWndHello );
-
- WinShowWindow( hWndHelloFrame, TRUE );
-
- /* Poll messages from event queue */
- while( WinGetMsg( hAB, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
- WinDispatchMsg( hAB, (PQMSG)&qmsg );
-
- /* Clean up */
- WinDestroyWindow( hWndHelloFrame );
- WinDestroyMsgQueue( hMqHello );
- WinTerminate( hAB );
- }
-
- MRESULT CALLBACK HelloWndProc(hWnd, msg, mp1, mp2)
- /*
- * This routine processes WM_COMMAND, WM_PAINT. It passes
- * everything else to the Default Window Procedure.
- */
- HWND hWnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- HPS hPS;
- POINTL pt;
- CHARBUNDLE cb;
- RECTL rcl;
-
- switch (msg) {
-
- case WM_COMMAND:
- switch (COMMANDMSG(&msg)->cmd) {
-
- case IDM_OPEN: /* Demonstrate Open... dialog call */
- SetupDLF( &vdlf
- , DLG_OPENDLG
- , &vhFile
- , szExtension
- , NULL
- , "Open Title"
- , szHelp );
- DlgFile(hWndHelloFrame, &vdlf);
- break;
-
- case IDM_SAVE: /* Demonstrate Save As... dialog call */
- SetupDLF( &vdlf
- , DLG_SAVEDLG
- , &vhFile
- , szExtension
- , NULL
- , "Save Title"
- , szHelp);
- lstrcpy( (PSZ)vdlf.szOpenFile, (PSZ)"foo.bar");
- DlgFile(hWndHelloFrame, &vdlf);
- break;
-
- case IDM_ABOUT:
- WinDlgBox(HWND_DESKTOP, hWnd, AboutDlgProc,
- (HMODULE) NULL, IDD_ABOUT, NULL);
- return 0;
-
- default: break;
- }
- break;
-
- case WM_PAINT:
- /* Open the presentation space */
- hPS = WinBeginPaint(hWnd, NULL, &rcl);
-
- /* Fill the background with Dark Blue */
- WinFillRect(hPS, &rcl, CLR_DARKBLUE);
-
- /* Write "Hello World" in Red */
- pt.x = pt.y = 0L;
- cb.lColor = CLR_RED;
- GpiSetAttrs(hPS, PRIM_CHAR, CBB_COLOR, 0L, &cb);
- GpiCharStringAt(hPS, &pt, (LONG)sizeof(szClassName)-1, szClassNam
-
- /* Finish painting */
- WinEndPaint(hPS);
- break;
-
- default: return WinDefWindowProc(hWnd, msg, mp1, mp2); break;
- }
- return 0L;
- }
-
- MRESULT CALLBACK AboutDlgProc(hDlg, msg, mp1, mp2)
- /*
- About... dialog procedure
- */
- HWND hDlg;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- switch(msg) {
- case WM_COMMAND:
- switch(COMMANDMSG(&msg)->cmd) {
- case DID_OK: WinDismissDlg(hDlg, TRUE); break;
- default: break;
- }
- default: return WinDefDlgProc(hDlg, msg, mp1, mp2);
- }
- return FALSE;
- }
-
-
- INIEDIT.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\INIEDIT\INIEDIT.C
-
- /******************************* Module Header ******************************
- * Module Name: IniEdit.c
- *
- *
- * PM OS2.ini Editor
- *
- * Allows adding, deleting and modifying of os2.ini entries through PM
- * interface
- *
- *
- \***************************************************************************/
-
-
- #define LINT_ARGS // Include needed parts of PM
- #define INCL_WININPUT // definitions
- #define INCL_WINSYS
- #define INCL_WINMESSAGEMGR
- #define INCL_WINBUTTONS
- #define INCL_WINPOINTERS
- #define INCL_WINHEAP
- #define INCL_WINSHELLDATA
- #define INCL_WINMENUS
- #define INCL_WINFRAMEMGR
- #define INCL_WINDIALOGS
- #define INCL_WINLISTBOXES
- #define INCL_WINENTRYFIELDS
- #define INCL_DOSMEMMGR
- #define INCL_WINSWITCHLIST
- #define INCL_DOSPROCESS
- #define INCL_GPIBITMAPS
- #define INCL_GPIREGIONS
- #define INCL_GPILCIDS
- #define INCL_GPIPRIMITIVES
- #define INCL_DEV
-
- #include <string.h>
- #include <stdio.h>
-
- #include <os2.h>
-
- #include "IniEdit.h"
-
-
- /******************************* Constants **********************************
-
- #define STACK_SIZE 0x2000 // Stack size for second thread
- #define UPPER_SEGMENT_LIMIT 0xFD00 // Amount of Segment used
-
- /******************************** Globals **********************************/
-
- char szIniEdit[] = "IniEdit"; // App String Name
-
- HAB habIniEdit; // Handle Anchor Block
- HMQ hmqIniEdit; // Handle Message Queue
- HWND hwndIniEdit; // Main Client Window
- HWND hwndIniEditFrame; // Frame Window
- HDC hdcScreen; // DC for Client Window
- HPS hpsScreen; // PS for Client Window
-
-
- USHORT cAppNames = 0; // Count of App names in os2.ini
- USHORT usShift = 0; // DosHugeAlloc segment offsets
- HWND FocusWindow = (HWND)NULL; // Focus of Dialog Box
- USHORT cxBorder; // System border width
- USHORT cyBorder; // System border height
-
- USHORT usFormat = APP_FORM; // Current Display format
- USHORT usPrintFormat = APP_FORM; // Format for Printing
- USHORT usLineHeight = 12; // Current font Height
- HWND hwndList = (HWND)NULL; // Handle of Main ListBox
- HWND hwndMenu = (HWND)NULL; // Handle of Main Menu
-
- PGROUPSTRUCT pGroups; // Pointer to String Groups
- PPAIRSTRUCT pPairsBase; // Pointer to Key-Value Pairs
- PPAIRSTRUCT pPairsAlloc; // Pointer to next Avail Memory
- PBYTE pPrintStack; // Pointer to Print Thread Stack
-
- #define HOLD_LEN 4096
- CHAR achNames[HOLD_LEN]; // Array of Character from Query
- CHAR szBuf[2 * MAX_STRING_LEN]; // Character buffer for Pairs
-
-
- /***************************** Function Decls ******************************/
-
- VOID ProcessMenuItem( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 );
- VOID cdecl main( VOID );
- VOID IniEditPaint( VOID );
- VOID ReadIni( VOID );
- VOID OldProfilePrint( VOID );
- VOID UpdateListBox( BOOL fRead, USHORT usForm );
-
- MRESULT _loadds EXPENTRY IniEditWndProc(HWND, USHORT, MPARAM, MPARAM);
-
-
- /***************************** Function Header *****************************\
- *
- * main
- *
- *
- * Do initialization then do a message loop
- *
- \***************************************************************************/
-
- VOID cdecl main()
- {
-
- QMSG qmsg; // Current Queue Message
- ULONG fcf; // Frame Control Flags
- SIZEL sizel; // Size of PS
- RECTL rclWindow; // Size Rect for ListBox Window
- SEL sel; // Selector of allocated segments
- SWCNTRL swcntrl; // Switch Control Block
- FONTMETRICS fmetrics; // FontMetrics of current font
-
-
- /*** Set up and Initialization ***/
-
- /* Initialize the anchor block handle */
- habIniEdit = WinInitialize(0);
-
- /* Create the message queue */
- hmqIniEdit = WinCreateMsgQueue(habIniEdit, 0);
-
- /* Register the window class for the IniEdit window */
- WinRegisterClass(habIniEdit, (PCH)szIniEdit, IniEditWndProc,
- CS_SIZEREDRAW, 0);
-
- /* Create the window for IniEdit */
- fcf = FCF_TITLEBAR | FCF_MINMAX | FCF_SYSMENU | FCF_SIZEBORDER | FCF_MENU
- | FCF_SHELLPOSITION | FCF_ACCELTABLE | FCF_ICON;
-
- hwndIniEditFrame = WinCreateStdWindow( HWND_DESKTOP, WS_VISIBLE,
- (PVOID)&fcf, (PSZ)szIniEdit, (PSZ)szIniEdit, WS_VISIBLE,
- (HMODULE)NULL, IDI_INIEDIT, (PHWND)&hwndIniEdit);
-
- /* Create a DC for the IniEdit window */
- hdcScreen = WinOpenWindowDC(hwndIniEdit);
-
- /* also create a screen PS */
-
- sizel.cx= 0L; // To use the default screen page size.
- sizel.cy= 0L;
-
- if( (hpsScreen = GpiCreatePS( habIniEdit, hdcScreen, &sizel,
- (PU_PELS | GPIF_DEFAULT | GPIT_MICRO | GPIA_ASSOC ))) == (HPS)NUL
- {
- ;
- }
-
-
- /* Initially set the keyboard focus to us */
- WinSetFocus(HWND_DESKTOP, hwndIniEdit);
-
- /* get the font size */
- GpiQueryFontMetrics( hpsScreen, (LONG)sizeof( FONTMETRICS ), &fmetrics );
- usLineHeight = (USHORT)(fmetrics.lMaxDescender + fmetrics.lMaxBaselineExt
-
- /* get the system widths of a border */
- cxBorder = (USHORT) WinQuerySysValue(HWND_DESKTOP, SV_CXBORDER);
- cyBorder = (USHORT) WinQuerySysValue(HWND_DESKTOP, SV_CYBORDER);
-
- /* this menu handle is often used */
- hwndMenu = WinWindowFromID( hwndIniEditFrame, FID_MENU );
-
- /* add program to switch list */
- swcntrl.hwnd = hwndIniEditFrame;
- swcntrl.hwndIcon = NULL;
- swcntrl.hprog = NULL;
- swcntrl.idProcess = 0;
- swcntrl.idSession = 0;
- swcntrl.uchVisibility = 0;
- swcntrl.fbJump = 0;
- strcpy( swcntrl.szSwtitle, szIniEdit);
- swcntrl.fReserved = 0;
-
- WinAddSwitchEntry( &swcntrl );
-
- /* Create main list box in main window */
- WinQueryWindowRect( hwndIniEdit, &rclWindow);
- rclWindow.yTop -= usLineHeight;
- rclWindow.yTop += cyBorder;
- rclWindow.xRight += 2*cxBorder;
- hwndList = WinCreateWindow( hwndIniEdit, // parent
- WC_LISTBOX, // class
- (PSZ)"Scroll", // name
- LS_NOADJUSTPOS, // style
- -cxBorder, -cyBorder, // position
- (USHORT)rclWindow.xRight,
- (USHORT)rclWindow.yTop,
- hwndIniEditFrame, // Owner
- HWND_TOP, // InsertBehind
- IDI_LIST, // ID
- (PVOID)NULL, // pCtlData,
- (PVOID)NULL);
-
-
- /*** Memory Allocation ***/
-
- /* Alloc the needed space for the groups */
- if( DosAllocSeg( 32000, &sel, 0) )
- ErrMessage( "main: DosAlloc for pGroup failed" );
- pGroups = MAKEP( sel, 0);
-
- if( DosAllocHuge( 4, 0, &sel, 0, 0) )
- ErrMessage( "main: DosAlloc for pPairs failed" );
- pPairsAlloc = pPairsBase = MAKEP( sel, 0);
-
- /* create a stack for second thread */
- if( DosAllocSeg( STACK_SIZE, &sel, 0) )
- ErrMessage( "main: DosAlloc for Stack failed" );
- pPrintStack = MAKEP( sel, 0);
-
- DosGetHugeShift( &usShift );
-
- /* read in os2.ini and fill in list box */
- UpdateListBox( TRUE, APP_FORM );
-
- WinShowWindow( hwndList, TRUE );
-
- /* Process messages for the window */
- while ( WinGetMsg(habIniEdit, (PQMSG)&qmsg, (HWND)NULL, 0, 0 ) )
- {
-
- /* Dispatch the message */
- WinDispatchMsg(habIniEdit, (PQMSG)&qmsg);
- }
-
-
- /*** CleanUp ***/
-
- /* Destroy the IniEdit window and message queue */
- GpiDestroyPS( hpsScreen );
- WinDestroyWindow(hwndIniEditFrame);
- WinDestroyMsgQueue(hmqIniEdit);
-
- /* Exit PM */
- WinTerminate( habIniEdit );
- DosExit( EXIT_PROCESS, 0 );
-
- } /* main */
-
-
- /****************************** Function Header ****************************\
- *
- * ReadIni
- *
- *
- * Reads in OS2.ini
- *
- \***************************************************************************/
-
- VOID ReadIni()
- {
- USHORT cchNames; // Count of Character from Query
- USHORT Index[MAX_APP_NAMES]; // Index of Names into achNames
- USHORT cPairs; // Count of pairs in current AppN
- ULONG ul;
- USHORT i,j; // Loop Counters
-
-
- /* Reset Count of App Names */
- cAppNames = 0;
-
- /* Reset memory available pointer to Base */
- pPairsAlloc = pPairsBase;
-
- /* Determine number of characters in app Names Strings */
- WinQueryProfileSize( habIniEdit, NULL, NULL, &cchNames );
-
- /* Read in the App Name strings */
- WinQueryProfileString( habIniEdit, NULL, NULL, " ", achNames, cchNames );
-
- /*** Find the starting index of each App ***/
-
- /* step through each string in set of app characters
- * adding length of current string to find begining of next string
- * also store each App Name into szAppName element of Group
- */
- for( i=0; i<cchNames; i += (strlen(pGroups[cAppNames-1].szAppName)+1) )
- {
- if( achNames[i] != (char)0 )
- {
- strcpy( pGroups[cAppNames++].szAppName, &achNames[i]);
- } /* if */
- else
- if( achNames[i+1] == (char)0 )
- break;
- } /* for */
-
-
- /*** Read elements of each App Name ***/
- for( i=0; i<cAppNames; i++ )
- {
- /* Get number of Character Associated with App Name */
- WinQueryProfileSize( habIniEdit, pGroups[i].szAppName, NULL, &cchName
-
- /* Enumerate all KeyNames for this app name */
- WinQueryProfileString( habIniEdit, pGroups[i].szAppName, NULL, " ", a
-
- /* Count the number of key Names */
- cPairs = 0;
- for( j=0; j<cchNames; j++)
- if( achNames[j] != (CHAR)0 )
- {
- Index[cPairs++] = j;
- j += strlen( &achNames[j] );
- }
-
- pGroups[i].cKeys = cPairs;
-
- /*
- * Make sure we can fit the entire structure into our current
- * segment, if not, lets jump to the next segment
- */
- ul = sizeof(PAIRSTRUCT) * cPairs;
- if ((ul + (ULONG)OFFSETOF(pPairsAlloc)) >= 0x10000L)
- pPairsAlloc = MAKEP( (HIUSHORT(pPairsAlloc)+(1<<usShift)), 0);
-
-
-
- /* Allocate the number of pair structures for the current group */
- pGroups[i].pPairs = pPairsAlloc;
-
- // pPairsAlloc += sizeof(PAIRSTRUCT)*cPairs;
- // Remember that incrementing a pointer automatically mult by size of
- pPairsAlloc += cPairs;
-
- /* Step to next segment if near end of current segment */
- if( LOUSHORT(pPairsAlloc) > UPPER_SEGMENT_LIMIT)
- {
- pPairsAlloc = MAKEP( (HIUSHORT(pPairsAlloc)+(1<<usShift)), 0);
- }
-
- /* Store the KeyName into the pair structure */
- for( j=0; j<cPairs; j++ )
- {
- strcpy( pGroups[i].pPairs[j].szKey, &achNames[Index[j]] );
-
- /* store the key value */
- WinQueryProfileString( habIniEdit, pGroups[i].szAppName,
- pGroups[i].pPairs[j].szKey, " ",
- pGroups[i].pPairs[j].szValue, MAX_STRING_LEN );
-
- }
- } /* each App Name */
-
- } /* ReadIni */
-
-
- /****************************** Function Header ****************************\
- *
- * ProcessMenuItem
- *
- *
- * Act on the corresponding Menu Item Choosen
- *
- \***************************************************************************/
-
- VOID ProcessMenuItem( HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2 )
- {
- TID Tid; // ID of new thread; Not used
-
-
- /* Switch on the Menu Item choosen */
- switch( LOUSHORT( mp1 ) )
- {
- case IDMI_SHOW_ALL:
- case IDMI_SHOW_APPNAMES:
- usFormat = (LOUSHORT(mp1) == IDMI_SHOW_ALL);
- UpdateListBox( FALSE, usFormat ? ALL_FORM : APP_FORM );
- break;
-
- case IDM_SEARCH:
- WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)SearchWndProc,
- (HMODULE)NULL, IDD_SEARCH, (PVOID)NULL);
- break;
-
- case IDMI_EDIT_DELETE_KEY:
- WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)DelKeyWndProc,
- (HMODULE)NULL, IDD_DEL_KEY, (PVOID)NULL);
- UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
- break;
-
- case IDMI_EDIT_DELETE_APP:
- WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)DelAppWndProc,
- (HMODULE)NULL, IDD_DEL_APP, (PVOID)NULL);
- UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
- break;
-
- case IDMI_EDIT_ADD_KEY:
- WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)AddKeyWndProc,
- (HMODULE)NULL, IDD_ADD_KEY, (PVOID)NULL);
- UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
- break;
-
- case IDMI_EDIT_CHANGE:
- WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)ChangeKeyWndProc
- (HMODULE)NULL, IDD_CHANGE_KEY, (PVOID)NULL);
- UpdateListBox( TRUE, usFormat ? ALL_FORM : APP_FORM );
- break;
-
- case IDMI_PRINT_ALL:
- case IDMI_PRINT_APP:
- usPrintFormat = LOUSHORT(mp1) == IDMI_PRINT_ALL ? ALL_FORM : APP_
- if( DosCreateThread( PrintThread, &Tid, ((PBYTE)(pPrintStack)+STA
- ErrMessage("StartThread2: DosCreateThread Failed");
- break;
-
- case IDMI_REFRESH:
- UpdateListBox( TRUE, usFormat );
- break;
-
- case IDMI_ABOUT:
- WinDlgBox(HWND_DESKTOP, hwndIniEditFrame, (PFNWP)DelAppWndProc,
- (HMODULE)NULL, IDD_ABOUT, (PVOID)NULL);
- break;
-
- default:
- WinDefWindowProc(hwnd, msg, mp1, mp2);
-
- break;
-
- } /* switch */
-
- } /* ProcessMenuItem */
-
-
- /****************************** Function Header ****************************\
- *
- * UpdateListBox
- *
- *
- * Update Main List Box to correct state
- * May Also:
- * - Check correct menu item
- * - Repaint title of List Box
- * - ReRead os2.ini file
- *
- \***************************************************************************/
-
- VOID UpdateListBox( BOOL fReadIni, USHORT usNewFormat )
- {
- USHORT i,j; // Loop Counters
- USHORT Index; // Index into ListBox
- static USHORT usLastFormat = -1; // Last displayed format
-
-
- /* Check the correct item if format changed */
- if( usLastFormat != usNewFormat )
- {
- WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDMI_SHOW_ALL, TRU
- MPFROM2SHORT(MIA_CHECKED, usFormat ? MIA_CHECKED:FALSE));
-
- WinSendMsg( hwndMenu, MM_SETITEMATTR, MPFROM2SHORT(IDMI_SHOW_APPNAMES
- MPFROM2SHORT(MIA_CHECKED, (!usFormat) ? MIA_CHECKED:FALSE));
- usLastFormat = usNewFormat;
-
- WinSendMsg( hwndIniEdit, WM_PAINT, (MPARAM)NULL, (MPARAM)NULL );
- }
-
-
- /* Turn off list box updates */
- WinEnableWindowUpdate( hwndList, FALSE );
-
- /* Remove all items from list box */
- WinSendMsg( hwndList, LM_DELETEALL, (MPARAM)0, (MPARAM)0 );
-
- /* ReRead os2.ini if needed */
- if( fReadIni )
- ReadIni();
-
- /* Add elements to listbox */
- if( usNewFormat == ALL_FORM )
- {
-
- /* Insert all app Names */
- for( i=0; i<cAppNames; i++ )
- {
- Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_INSERTITEM,
- MPFROM2SHORT(LIT_END, NULL),
- MPFROMP(pGroups[i].szAppName) ));
-
- WinSendMsg( hwndList, LM_SETITEMHANDLE,
- MPFROMSHORT(Index),
- MPFROMSHORT(i) );
-
- /* Insert Key Value Pairs for App Name */
- for( j=0; j<pGroups[i].cKeys; j++ )
- {
- sprintf( szBuf, " %s: %s", pGroups[i].pPairs[j].szKey,
- pGroups[i].pPairs[j].szValue );
- Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_INSERTITEM,
- MPFROM2SHORT(LIT_END, NULL),
- MPFROMP(szBuf) ));
-
- WinSendMsg( hwndList, LM_SETITEMHANDLE,
- MPFROMSHORT(Index),
- MPFROM2SHORT(i,j) );
-
- }
- }
- } /* if */
- else
- {
- /* Insert all app Names */
- for( i=0; i<cAppNames; i++ )
- {
- WinSendMsg( hwndList, LM_INSERTITEM,
- MPFROM2SHORT(LIT_SORTASCENDING, NULL),
- MPFROMP(pGroups[i].szAppName) );
- }
- } /* else */
-
- /* Do All repainting of ListBox */
- WinEnableWindowUpdate( hwndList, TRUE );
-
- } /* UpdateListBox */
-
-
- /****************************** Function Header ****************************\
- *
- * IniEditPaint
- *
- *
- * Window Paint Routine
- *
- \***************************************************************************/
-
- VOID IniEditPaint()
- {
- RECTL rclWindow; // Current size of Main Window
- RECTL rclBlit; // Size of Area to Blank for Titl
- CHAR szShowMode[MAX_STRING_LEN]; // String Description of mode
-
-
- /* Get the size of the whole window */
- WinQueryWindowRect( hwndIniEdit, &rclWindow );
-
- /* Paint the window Title Area */
- rclBlit = rclWindow;
- rclBlit.yBottom = rclBlit.yTop - usLineHeight;
-
- GpiBitBlt( hpsScreen, (HPS)NULL, 2L, (PPOINTL)&rclBlit, ROP_ONE, (LONG)NU
-
- /* Write the Title */
- strcpy( szShowMode, usFormat == APP_FORM ? SZAPP : SZALL );
- WinDrawText( hpsScreen, strlen(szShowMode), szShowMode, &rclWindow,
- CLR_BLUE, CLR_WHITE, DT_CENTER|DT_TOP);
-
- } /* IniEditPaint */
-
-
- /****************************** Function Header ****************************\
- *
- * IniEditWndProc
- *
- *
- * Window Proc for IniEdit
- *
- \***************************************************************************/
-
- MRESULT _loadds EXPENTRY IniEditWndProc(HWND hwnd, USHORT msg,
- MPARAM mp1, MPARAM mp2)
- {
-
- CHAR szBuf[MAX_STRING_LEN]; // Input character Buffer
- CHAR szBuf2[MAX_STRING_LEN]; // Second Input Character Buffer
- USHORT Index; // Index of Current ListBox Item
- USHORT TopIndex; // Current Top Item in ListBox
- ULONG Handle; // ListBox Item Handle Info
- HWND hwndDialog; // Window handle of Dailog Box
- HWND hwndText; // Handle of current text window
- HPS hpsPaint; // PS to Paint
- RECTL rclPaint; // Rect in hpsPaint to Paint
- BOOL fScroll = FALSE; // Scroll List Box Flag
-
-
- /* Switch on message being processed */
- switch( msg )
- {
- case WM_PAINT:
- /* Paint the IniEdit window portion not covered by List Box */
- hpsPaint = WinBeginPaint(hwnd, (HPS)NULL, &rclPaint);
- IniEditPaint();
- WinEndPaint(hpsPaint);
- break;
-
- case WM_COMMAND:
- /* If menu item call Processing Routine */
- if( LOUSHORT( mp2 ) == CMDSRC_MENU )
- ProcessMenuItem( hwnd, msg, mp1, mp2 );
-
- /* If accelorator call appropriate routine */
- if( LOUSHORT( mp2 ) == CMDSRC_ACCELERATOR )
- {
- switch( LOUSHORT( mp1 ) )
- {
- case IDDI_SEARCH_NEXT:
- FindNext();
- break;
- }
- }
- break;
-
- case WM_SIZE:
- /* Put the list box in the correct location of the window */
- if( hwndList != (HWND)NULL )
- /* The position is set to fill the client, except for the */
- /* area at the top for some text. In addition, the */
- /* rectangle is outset by a border width on all dimensions*/
- /* except for the top so that the list box border is */
- /* "tucked" under the clients border and doesn't cause */
- /* there to be a double thick border around it. */
- WinSetWindowPos( hwndList, HWND_TOP, -cxBorder, -cyBorder,
- SHORT1FROMMP(mp2)+(2*cxBorder),
- SHORT2FROMMP(mp2)-usLineHeight + cyBorder,
- SWP_SIZE | SWP_MOVE );
- break;
-
- case WM_CONTROL:
- /* Switch on Control activated */
- switch( SHORT1FROMMP(mp1) )
- {
-
- /*** Process List Box Activity ***/
- case IDI_LIST:
- /* was it a double click? */
- if( SHORT2FROMMP(mp1) == LN_ENTER )
- {
- /* get the item clicked on */
- Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_QUERYSE
- (MPARAM)0, (MPARAM)0 ));
-
- /* grab its text */
- WinSendMsg( hwndList, LM_QUERYITEMTEXT,
- MPFROM2SHORT(Index, MAX_STRING_LEN), MPFROMP(
-
- /* if in APP form toggle to ALL form */
- if( usFormat == APP_FORM )
- {
- usFormat = ALL_FORM;
- fScroll = TRUE;
- }
- else
- {
- /* if an App name was choosen then go to APP form
- if( szBuf[0] != ' ')
- {
- usFormat = APP_FORM;
- fScroll = TRUE;
- }
- else
- /* A Key Value Pair was double clicked
- * allow editing of key Value
- */
- {
-
- FocusWindow = (HWND)1;
-
- hwndDialog = WinLoadDlg( HWND_DESKTOP,
- hwndIniEditFrame, ChangeKeyWndProc,
- (HMODULE)NULL, IDD_CHANGE_KEY, NULL);
-
- Handle = (ULONG)WinSendMsg( hwndList, LM_QUER
- MPFROMSHORT(Index), (MPARAM)NULL );
-
- hwndText = WinWindowFromID( hwndDialog, IDDI_
- WinSendMsg(hwndText, EM_SETTEXTLIMIT,
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- WinSetWindowText( hwndText, pGroups[LOUSHORT(
-
- /* note bug in PMWin GPs if full segment */
- hwndText = WinWindowFromID( hwndDialog, IDDI_
- WinSendMsg(hwndText, EM_SETTEXTLIMIT,
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- strcpy( szBuf2, pGroups[LOUSHORT(Handle)].pPa
- WinSetWindowText( hwndText, szBuf2 );
-
- hwndText = WinWindowFromID( hwndDialog, IDDI_
- WinSendMsg(hwndText, EM_SETTEXTLIMIT,
- MPFROMSHORT(MAX_STRING_LEN), 0L);
- strcpy( szBuf2, pGroups[LOUSHORT(Handle)].pPa
- WinSetWindowText( hwndText, szBuf2 );
-
- WinPostMsg( hwndText, EM_SETSEL,
- MPFROM2SHORT(0, strlen(szBuf2)), (MPA
-
- if( WinProcessDlg( hwndDialog ) == IDDI_CHANG
- {
- TopIndex = SHORT1FROMMR(WinSendMsg( hwndL
- (MPARAM)NULL, (MPARAM)NULL ));
-
- UpdateListBox( TRUE, usFormat );
-
- /* scroll to top */
- WinSendMsg( hwndList, LM_SETTOPINDEX,
- MPFROMSHORT(TopIndex), (MPARAM)NULL
-
- /* make the item selected */
- WinSendMsg( hwndList, LM_SELECTITEM,
- MPFROMSHORT(Index), MPFROMSHORT(T
-
- /* make selected */
- }
-
- WinDestroyWindow( hwndDialog );
- }
- }
-
- /* Make the double clicked item selected in new form
- if( fScroll )
- {
- /* put in correct form */
- UpdateListBox( FALSE, usFormat );
-
- /* get the index of the item clicked on */
- Index = SHORT1FROMMR(WinSendMsg( hwndList, LM_SEA
- MPFROM2SHORT(LSS_SUBSTRING, LIT_FIRST),
- MPFROMP(szBuf) ));
-
- /* scroll that item to the top */
- WinSendMsg( hwndList, LM_SETTOPINDEX,
- MPFROMSHORT(Index), (MPARAM)NULL );
-
- /* make the item selected */
- WinSendMsg( hwndList, LM_SELECTITEM,
- MPFROMSHORT(Index), MPFROMSHORT(TRUE) );
- }
- } /* if ENTER */
- }
- break;
-
- default:
- return WinDefWindowProc(hwnd, msg, mp1, mp2);
- break;
- }
-
- return 0L;
-
- } /* IniEditWndProc */
-
-
- INIT.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\OPENDLG\INIT.C
-
- /***************************************************************************\
- * INIT.C -- Library initialization funcitons
- * Created by Microsoft Corporation, 1989
- \***************************************************************************/
-
- #include "tool.h"
- /****************************************************************************
- * This function initializes the file dialog library (by loading strings).
- *
- * Note: Initialization will fail if CCHSTRINGSMAX is smaller than the
- * space taken up by all strings in the .rc file. Fix by increasing
- * CCHSTRINGSMAX in wintool.h and maybe also the initial heap size
- * in wintool.def.
- *
- * Returns:
- * TRUE if initialization successful
- * FALSE otherwise
- \***************************************************************************/
-
- BOOL PASCAL InitLibrary()
- {
- int i;
- int cch;
- PSTR pch;
- PSTR pmem;
- int cchRemaining;
-
- /* allocate memory for strings */
- if (!(pch = (pmem = WinAllocMem(vhheap, cchRemaining = CCHSTRINGSMAX))))
- return FALSE;
-
- /* load strings from resource file */
- for (i = 0; i < CSTRINGS; i++) {
- cch = 1 + WinLoadString(HABX, vhModule, i, cchRemaining, (PSZ)pch);
- if (cch < 2)
- /* loadstring failed */
- return FALSE;
- vrgsz[i] = pch;
- pch += cch;
-
- if ((cchRemaining -= cch) <= 0)
- /* ran out of space */
- return FALSE;
- }
-
- /* reallocate string space to size actually needed */
- WinReallocMem(vhheap, pmem, CCHSTRINGSMAX, CCHSTRINGSMAX - cchRemaining);
-
- return TRUE;
- }
-
-
- JIGSAW.C
- CD-ROM Disc Path: \SAMPCODE\OS2SDK\OS2SDK12\JIGSAW\JIGSAW.C
-
- /********************************** Jigsaw *********************************
- /*
- /* Created 1988, Microsoft Corporation.
- /*
- /* Purpose: To illustrate the use of Gpi retained segments.
- /*
- /* Summary: This program provides a jigsaw puzzle, based on a decomposition
- /* of an arbitrary bitmap loaded from a file. The user can jumble the
- /* pieces, then drag them individually by means of the mouse. The image
- /* can be zoomed in and out and scrolled up/down and left/right.
- /*
- /* Each piece of the puzzle is a retained segment. When a piece is
- /* selected for dragging, it is made dynamic. A menu option allows the
- /* selected piece to be dragged as an outline or as a normal-looking piece.
- /*
- /* Individual pieces are made to "move" by changing their model transforms.
- /* Scrolling and zooming of the whole picture is done by changing the
- /* default viewing transform.
- /*
- /* Optimizations: While it is possible to implement this puzzle using a very
- /* naive approach, this is liable to lead to a rather slowly-operating
- /* program. The following optimizations dramatically improve program
- /* performance:
- /*
- /* 1> BitBlt only as much of the bitmap through a clip path as necessary.
- /* Each piece of the puzzle is drawn by defining a clip path, blitting
- /* through the path, and drawing an outline on the same path. The naive
- /* approach is to blit the whole bitmap through the clip path. A more
- /* clever approach is to compute the piece's bounding box and only use
- /* the source and destination rectangles which correspond to this box.
- /* This leads to an order-of-magnitude speedup in the time to draw one
- /* piece.
- /*
- /* 2> Make the source and target rectangles for BitBlt the same size
- /* in device coordinates. A BitBlt in a retained segment must be done
- /* with GpiWCBitBlt and the target rectangle must be specified in world
- /* coordinates, so you must use GpiConvert (taking into account that in
- /* world space rectangles are inclusive-inclusive while in device space
- /* rectangles are inclusive-exclusive) to compute what target world space
- /* rectangle will be converted to the desired device space rectangle.
- /* Making the sizes of the source and converted target rectangles differ
- /* by even one pel will cause strectching or compression to occur, with
- /* a dramatic loss in speed. Unfortunately, due to rounding effects,
- /* not always possible to guarantee that adding an offset to the
- /* transformation applied to a segment will leave the size of the
- /* rectangle defined by the orders in the segment unchanged.
- /*
- /* 3> Use auxiliary information to reduce the number of segments which
- /* must be checked for correlation. The naive approach to hit-testing is
- /* to test the whole chain, even though generally only a small fraction of
- /* the segments in the chain could possibly get a hit. A more clever
- /* approach is to take the bounding box for each segment and only include
- /* the segment in the correlation check if the box contains the correlation
- /* point. eg.
- /* a> Edit the chain by adjusting the ATTR_CHAINED attribute of each
- /* segment to reflect candidacy for being hit. Afterwards, fix up by
- /* adding back removed segments to the chain.
- /* b> Even faster is to keep an auxiliary data structure which records
- /* the priority of the segments (placed in the SEGLIST chain). Run
- /* through the priority list from high-priority to low-priority and do a
- /* correlation test on each segment which passes the bounding-box test.
- /*
- /* 4> When repainting through a clip region, only draw those segments which
- /* overlap the clip region. The naive approach is to set up the clip
- /* region and do a GpiDrawChain on the whole chain. The drawback to this
- /* is that much time will be spent running through the orders in segments
- /* which are not visible through the clip region. Very often, most of the
- /* segments in the picture can be eliminated from needing to be drawn by
- /* recognizing that there is no overlap between the bounding boxes of the
- /* segment and the clip region.
- /*
- /* 5> Do WinScrollWindow horizontally in multiples of 8 pels when possible.
- /* For example, horizontal scrolls by 7 or 9 pels are much slower than a
- /* a horizontal scroll by 8 pels.
- /*
- /****************************************************************************
-
- #define INCL_BITMAPFILEFORMAT
-
- #define INCL_DOSPROCESS
- #define INCL_DOSSEMAPHORES
- #define INCL_DOSMEMMGR
-
- #define INCL_DEV
-
- #define INCL_WINWINDOWMGR
- #define INCL_WINMESSAGEMGR
- #define INCL_WININPUT
- #define INCL_WINRECTANGLES
- #define INCL_WINPOINTERS
- #define INCL_WINMENUS
- #define INCL_WINSCROLLBARS
- #define INCL_WINFRAMEMGR
- #define INCL_WINSWITCHLIST
- #define INCL_WINSYS
-
- #define INCL_GPIBITMAPS
- #define INCL_GPICONTROL
- #define INCL_GPITRANSFORMS
- #define INCL_GPIPRIMITIVES
- #define INCL_GPIMETAFILES
- #define INCL_GPIPATHS
- #define INCL_GPIREGIONS
- #define INCL_GPISEGMENTS
- #define INCL_GPISEGEDITING
- #define INCL_GPICORRELATION
- #define INCL_GPILCIDS
-
- #define INCL_ERRORS
-
- #include <os2.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <string.h>
- #include <opendlg.h>
- #include "noncomm.h"
- #include "jigsaw.h"
-
-
-
- /*----------------------- inter-thread messages -----------------------------
-
- UM_DIE WM_USER+1 /* instruct async thread to terminate *
- UM_DRAW WM_USER+2 /* draw the current picture */
- UM_VSCROLL WM_USER+3 /* perform scroll by recalculating the */
- /* default viewing transform
- UM_HSCROLL WM_USER+4 /* perform scroll by recalculating the */
- /* default viewing transform
- UM_SIZING WM_USER+5 /* perform sizing by recalculating the */
- /* default viewing transform
- UM_ZOOM_IN WM_USER+6 /* zoom the picture by recalculating */
- /* the default viewing transform
- UM_ZOOM_OUT WM_USER+7 /* zoom the picture by recalculating */
- /* the default viewing transform
- #define UM_REDRAW WM_USER+8
- #define UM_JUMBLE WM_USER+9
- #define UM_LOAD WM_USER+10
- UM_DUMMY WM_USER+11 /* all commands not forcing redraw */
- /* must come after this one
-
- UM_LEFTDOWN WM_USER+12 /* mouse button down in the client area*/
- /* perform a correlation on the curren
- /* picture, setting any picked segment
- /* to dynamic
- UM_MOUSEMOVE WM_USER+13 /* mousemove command, remove, repositon*/
- /* and redraw any dynamic sements
- UM_LEFTUP WM_USER+14 /* mouse button up in the client area */
- /* set any dynamic segment to normal
- UM_FASTDRAG WM_USER+15 /* toggle fast-drag (outline) mode */
- UM_DRAWDONE WM_USER+16 /* Async DrawChain has completed */
- #define UM_FLUSH WM_USER+17
-
-
- /*------------------------ element label values ----------------------------
-
- #define FILLPATH 222L
- #define BITBLT_TOP 232L
- #define BITBLT_BOTTOM 233L
-
-
- /*------------------------- correlation parameters --------------------------
-
- HITS 1L /* maximum number of hits to return *
- DEPTH 2L /* max depth of seg calls to return
-
-
- /*-------------------------- general definitions ----------------------------
-
-
- HAB habMain=NULL; /* main thread anchor block ha
- HMQ hmqMain=NULL; /* main thread queue handle
- HWND hwndFrame=NULL; /* frame control handle
- HWND hwndClient=NULL; /* client area handle
- HDC hdcClient=NULL; /* window dc handle
- HPS hpsClient=NULL; /* client area Gpi ps handle
- SIZEL sizlMaxClient; /* max client area size
- HPS hpsPaint=NULL; /* ps for use in Main Thread
- HRGN hrgnInvalid = NULL; /* handle to the invalid region
-
- HAB habAsync=NULL; /* async thread anchor block
- HMQ hmqAsync=NULL; /* async thread queue handle
- TID tidAsync; /* async thread id
- SEL selStack; /* async thread stack selector
- STACKSIZE 4096 /* async thread stack size */
- SHORT sPrty = -1; /* async thread priority
-
- HWND hwndHorzScroll=NULL; /* horizontal scroll bar windo
- HWND hwndVertScroll=NULL; /* vertical scroll bar window
- POINTS ptsScrollPos, ptsOldScrollPos;
- POINTS ptsScrollMax, ptsHalfScrollMax;
- POINTS ptsScrollLine = { 8, 8};
- POINTS ptsScrollPage = { 64, 64};
-
- #define UNITY 65536L
- MATRIXLF matlfIdentity = { UNITY, 0, 0, 0, UNITY, 0, 0, 0, 1 };
- LONG lScale = 0; /* current zoom level
- #define ZOOM_MAX 8
- #define ZOOM_IN_ARG 1
- #define ZOOM_OUT_ARG -1
-
- #define CALLSEG_BASE 1000
- POINTL ptlOffset;
- POINTL ptlBotLeft = { 0, 0};
- POINTL ptlTopRight = { 300, 300};
- LONG lLastSegId; /* last segment id assigned to
- LONG lPickedSeg; /* seg id of piece selected for
- RECTL rclBounds; /* pict bounding box in model c
- POINTL ptlOldMouse = {0L, 0L}; /* current mouse posn
- BOOL fButtonDown = FALSE; /* only drag if mouse down
- BOOL fFastDrag = FALSE; /* show only outline of dragging
-
-
- /*-------------------------- segment list -----------------------------------
-
- typedef struct _SEGLIST { /* sl
- LONG lSegId;
- struct _SEGLIST FAR * pslPrev;
- struct _SEGLIST FAR * pslNext;
- POINTL ptlLocation; /* piece location, world coordinates
- RECTL rclCurrent; /* segment bounding box, model coords
- RECTL rclBitBlt; /* segment bounding box, world coords
- } SEGLIST ;
- typedef SEGLIST FAR *PSEGLIST; /* psl
- typedef PSEGLIST FAR *PPSEGLIST; /* ppsl
- PSEGLIST pslHead = NULL; /* head of the list
- PSEGLIST pslTail = NULL; /* tail of the list
- PSEGLIST pslPicked = NULL; /* picked segment's list member
- #define ADD_HEAD_SEG 1
- #define ADD_TAIL_SEG 2
- #define DEL_SEG 3
-
- /*-------------------------- bitmap-related data ----------------------------
-
- typedef struct _LOADINFO { /* li
- HFILE hf;
- CHAR szFileName[MAX_FNAME_LEN];
- } LOADINFO ;
- typedef LOADINFO FAR *PLOADINFO; /* pli
-
- HPS hpsBitmapFile=NULL, hpsBitmapTemp=NULL, hpsBitmapDrag=N
- HDC hdcBitmapFile=NULL, hdcBitmapTemp=NULL, hdcBitmapDrag=N
- HBITMAP hbmBitmapFile=NULL, hbmBitmapTemp=NULL, hbmBitmapDrag=NULL
- BITMAPINFOHEADER bmpBitmapFile = {12L, 0, 0, 0, 0};
- BITMAPINFOHEADER bmpBitmapTemp = {12L, 0, 0, 0, 0};
- BITMAPINFOHEADER bmpBitmapDrag = {12L, 0, 0, 0, 0};
- BITMAPINFO bmiBitmap = {12L, 0, 0, 0, 0, {{0, 0, 0}}};
- static DEVOPENSTRUC dop = { NULL
- , "DISPLAY"
- , NULL
- , NULL
- , NULL
- , NULL
- , NULL
- , NULL
- , NULL };
-
-
- /*-------------------------- old-style bitmap header ------------------------
-
- typedef struct {
- USHORT wType;
- ULONG dwSize;
- int xHotspot;
- int yHotspot;
- ULONG dwBitsOffset;
- USHORT bmWidth;
- USHORT bmHeight;
- USHORT bmPlanes;
- USHORT bmBitcount;
- } RCBITMAP;
- typedef RCBITMAP FAR *PRCBITMAP;
-
-
- /*--------------------------- Miscellaneous ---------------------------------
-
- ULONG ulTerminateSem = 0; /* main thread blocks while as
- HSEM hsemTerminate = &ulTerminateSem;
-
- ULONG ulSzFmt = 0; /* serializes access to spr
- HSEM hsemSzFmt = &ulSzFmt;
- CHAR szFmt[50]; /* buffer used by sprintf()
-
- SWCNTRL swctl = { 0, 0, 0, 0, 0, SWL_VISIBLE, SWL_JUMPABLE, 0, 0 };
- HSWITCH hsw; /* handle to a switch list entry
- char szTitle[80]; /* Title bar text
-
- BOOL fErrMem = FALSE; /* set if alloc async stack fails
-
-
- /*------------------------- Function Prototypes -----------------------------
-
- VOID CalcBounds( VOID);
- VOID CalcTransform( HWND);
- MRESULT CALLBACK ClientWndProc( HWND, USHORT, MPARAM, MPARAM);
- BOOL CreateBitmapHdcHps( HDC, HPS);
- BOOL CreateThread( VOID);
- BOOL CreatePicture( VOID);
- VOID DestroyThread( VOID);
- BOOL DoDraw( HRGN);
- VOID DoHorzScroll( VOID);
- VOID DoVertScroll( VOID);
- BOOL DumpPicture( VOID);
- VOID Finalize( VOID);
- BOOL Initialize( VOID);
- VOID Jumble( VOID);
- VOID LeftDown( MPARAM);
- VOID LeftUp( VOID);
- VOID Load( PLOADINFO);
- VOID cdecl main( VOID);
- VOID MessageInt( HWND, INT, PCH);
- VOID MouseMove( MPARAM);
- VOID MyMessageBox( HWND, PSZ);
- VOID FAR NewThread( VOID);
- BOOL PrepareBitmap( VOID);
- BOOL ReadBitmap( HFILE);
- VOID Redraw( VOID);
- VOID ReportError( HAB);
- BOOL SegListCheck( INT);
- PSEGLIST SegListGet( LONG);
- BOOL SegListUpdate( USHORT, PSEGLIST);
- BOOL SendCommand( USHORT, ULONG);
- VOID SetDVTransform( FIXED, FIXED, FIXED, FIXED, LONG, LONG, LONG);
- VOID SetRect( PSEGLIST);
- VOID ToggleFastDrag( VOID);
- VOID Translate( PSEGLIST, PPOINTL);
- MRESULT WndProcCommand( HWND, USHORT, MPARAM, MPARAM);
- MRESULT WndProcCreate( HWND);
- MRESULT WndProcPaint( VOID);
- MRESULT WndProcSize( MPARAM, MPARAM);
- VOID Zoom( SHORT);
- VOID ZoomMenuItems( VOID);
-
-
- /****************************************************************************
- /*
- /* MyMessageBox
- /*
- /* Displays a message box with the given string. To simplify matters,
- /* the box will always have the same title ("Jigsaw"), will always
- /* have a single button ("Ok"), will always have an exclamation point
- /* icon, and will always be application modal.
- /*
- /****************************************************************************
- VOID
- MyMessageBox( hWnd, psz)
-
- HWND hWnd;
- PSZ psz;
- {
- WinMessageBox( HWND_DESKTOP
- , hWnd
- , psz
- , szTitle
- , 0
- , MB_OK | MB_ICONEXCLAMATION | MB_APPLMODAL );
- }
-
- /****************************************************************************
- /*
- /* Main thread will initialize the process for PM services and process
- /* the application message queue until a WM_QUIT message is received. It will
- /* then destroy all PM resources and terminate. Any error during
- /* initialization will be reported and the process terminated.
- /*
- /****************************************************************************
- VOID cdecl
- main()
- {
- QMSG qmsg;
-
- if( Initialize())
- while( WinGetMsg( habMain, &qmsg, NULL, 0, 0))
- WinDispatchMsg( habMain, &qmsg);
- else
- ReportError( habMain);
- Finalize();
- }
-
-
- /****************************************************************************
- /*
- /* The Initialize function will initialize the PM interface,
- /* create an application message queue, a standard frame window and a new
- /* thread to control drawing operations. It will also initialize static
- /* strings.
- /*
- /****************************************************************************
- BOOL
- Initialize()
- {
- ULONG flCreate;
- PID pid;
- TID tid;
-
- WinShowPointer( HWND_DESKTOP, TRUE);
- habMain = WinInitialize( 0);
- if( !habMain)
- return( FALSE);
-
- hmqMain = WinCreateMsgQueue( habMain,0);
- if( !hmqMain)
- return( FALSE);
-
- WinLoadString( habMain, (HMODULE) NULL, TITLEBAR, sizeof(szTitle), szTitle)
- if( !WinRegisterClass( habMain
- , (PCH)szTitle
- , (PFNWP)ClientWndProc
- , CS_SIZEREDRAW
- , 0 ))
- return( FALSE);
-
- flCreate = (FCF_STANDARD | FCF_VERTSCROLL | FCF_HORZSCROLL)
- & ~(ULONG)FCF_TASKLIST;
- hwndFrame = WinCreateStdWindow( HWND_DESKTOP
- , WS_VISIBLE
- , &flCreate
- , szTitle
- , szTitle
- , WS_VISIBLE
- , (HMODULE) NULL
- , APPMENU
- , &hwndClient);
- if( !hwndFrame)
- return( FALSE);
-
- WinQueryWindowProcess( hwndFrame, &pid, &tid);
- swctl.hwnd = hwndFrame;
- swctl.idProcess = pid;
- lstrcpy( swctl.szSwtitle, szTitle);
- hsw = WinAddSwitchEntry( &swctl);
-
- if( !CreateThread()) /* create async thread
- return ( FALSE);
- if( !CreateBitmapHdcHps( &hdcBitmapFile, &hpsBitmapFile))
- return( FALSE);
- if( !CreateBitmapHdcHps( &hdcBitmapTemp, &hpsBitmapTemp))
- return( FALSE);
- if( !CreateBitmapHdcHps( &hdcBitmapDrag, &hpsBitmapDrag))
- return( FALSE);
-
- return( TRUE);
- }
-
- /****************************************************************************
- /*
- /* Finalize will destroy the asynchronous drawing thread, all Presentation
- /* Manager resources, and terminate the process.
- /*
- /****************************************************************************
- VOID
- Finalize()
- {
- DestroyThread();
-
- while( pslHead != NULL )
- SegListUpdate( DEL_SEG, pslHead);
- if( hrgnInvalid)
- GpiDestroyRegion( hpsClient, hrgnInvalid);
- if( hpsClient)
- GpiAssociate( hpsClient, NULL);
- if( hpsPaint)
- GpiAssociate( hpsPaint, NULL);
- if( hpsBitmapFile)
- GpiAssociate( hpsBitmapFile, NULL);
- if( hpsBitmapTemp)
- GpiAssociate( hpsBitmapTemp, NULL);
- if( hpsBitmapDrag)
- GpiAssociate( hpsBitmapDrag, NULL);
- if( hwndFrame)
- WinDestroyWindow( hwndFrame);
- if( hmqMain)
- WinDestroyMsgQueue( hmqMain);
- if( habMain)
- WinTerminate( habMain);
-
- DosExit( EXIT_PROCESS, 0);
- }
-
-
- /****************************************************************************
- /*
- /* ReportError will display the latest error information for the requi
- /* thread. No resources to be loaded if out of memory error.
- /*
- /****************************************************************************
- VOID
- ReportError( hab)
-
- HAB hab;
- {
- PERRINFO perriBlk;
- PSZ pszErrMsg;
- USHORT * TempPtr;
-
- if( !hwndFrame)
- return;
- if( !fErrMem)
- {
- perriBlk = WinGetErrorInfo(hab);
- if( !perriBlk)
- return;
- SELECTOROF( pszErrMsg) = SELECTOROF(perriBlk);
- SELECTOROF( TempPtr) = SELECTOROF(perriBlk);
- OFFSETOF( TempPtr) = perriBlk->offaoffszMsg;
- OFFSETOF( pszErrMsg) = *TempPtr;
- WinMessageBox( HWND_DESKTOP
- , hwndFrame
- , pszErrMsg
- , szTitle
- , 0
- , MB_CUACRITICAL | MB_ENTER);
- WinFreeErrorInfo( perriBlk);
- } else
- WinMessageBox( HWND_DESKTOP
- , hwndFrame
- , "ERROR - Out Of Memory"
- , szTitle
- , 0
- , MB_CUACRITICAL | MB_ENTER);
- }
-
-
- /****************************************************************************
- /*
- /* CreateThread creates the asynchronous drawing thread. It will allocate
- /* stack space and create the thread.
- /*
- /****************************************************************************
- BOOL
- CreateThread()
- {
- PBYTE pbAsyncStack; /* long pointer to stack for new t
-
-
- if( DosAllocSeg( STACKSIZE, (PSEL)&selStack, 0 ))
- {
- fErrMem = TRUE;
- return( FALSE);
- }
- OFFSETOF(pbAsyncStack) = STACKSIZE-2;
- SELECTOROF(pbAsyncStack) = selStack;
- if( DosCreateThread( (PFNTHREAD)NewThread, &tidAsync, pbAsyncStack ))
- return( FALSE);
- return( TRUE);
- }
-
-
- /****************************************************************************
- /*
- /* DestroyThread will send a message to the asynchronous drawing thread
- /* commanding it to terminate itself. If the send is successful it will wait
- /* until the async thread has terminated. It will then release any stack spac
- /* used by that thread.
- /*
- /****************************************************************************
- VOID
- DestroyThread()
- {
- if( tidAsync)
- {
- DosSemSet( hsemTerminate);
- if( SendCommand( (USHORT)UM_DIE, (ULONG)NULL))
- DosSemWait( hsemTerminate, SEM_INDEFINITE_WAIT);
- }
- if( selStack)
- DosFreeSeg( selStack);
- }
-
-
- /****************************************************************************
- /*
- /* SendCommand will attempt to post the required command and parameter
- /* the asynchronous drawing thread's message queue. The command will only
- /* be posted if the queue exists.
- /*
- /****************************************************************************
- BOOL
- SendCommand( usCommand, ulInfo)
-
- USHORT usCommand;
- ULONG ulInfo;
- {
- if( !hmqAsync)
- return( FALSE);
-
- switch( usCommand)
- {
- case UM_DIE:
- case UM_LEFTDOWN:
- case UM_LEFTUP:
- case UM_MOUSEMOVE:
- case UM_DRAW:
- case UM_HSCROLL:
- case UM_VSCROLL:
- case UM_ZOOM_IN:
- case UM_ZOOM_OUT:
- case UM_REDRAW:
- case UM_SIZING:
- case UM_FASTDRAG:
- case UM_JUMBLE:
- case UM_LOAD:
-
- return( WinPostQueueMsg( hmqAsync
- , usCommand
- , MPFROMLONG( ulInfo)
- , MPFROMLONG( NULL ) ) );
- break;
-
- default:
- return( TRUE);
- }
- }
-
-
- /****************************************************************************
- /*
- /* ClientWndProd is the window procedure associated with the client window.
- /*
- /****************************************************************************
- MRESULT CALLBACK
- ClientWndProc( hwnd, msg, mp1, mp2)
-
- HWND hwnd;
- USHORT msg;
- MPARAM mp1;
- MPARAM mp2;
- {
- CHAR szTemp[128];
-
- switch( msg)
- {
- case WM_CREATE:
- return( WndProcCreate( hwnd));
- break;
-
- case WM_CLOSE:
- WinLoadString( habMain, (HMODULE) NULL, TERMINATE, sizeof(szTemp), (PSZ
- if( WinMessageBox( HWND_DESKTOP
- , hwndFrame
- , szTemp
- , szTitle
- , 0
- , MB_CUAWARNING | MB_YESNO | MB_DEFBUTTON2)
- == MBID_YES)
- WinPostMsg( hwnd, WM_QUIT, NULL, NULL);
- break;
-
- case WM_PAINT:
- return( WndProcPaint());
- break;
-
- /************************************************************************
- /*
- /************************************************************************
- case WM_ERASEBACKGROUND:
- WinFillRect( (HPS)mp1, (PRECTL)mp2, CLR_BACKGROUND);
- return( FALSE);
- break;
-
- /************************************************************************
- /*
- /************************************************************************
- case WM_MINMAXFRAME:
- if( (((PSWP)mp1)->fs & SWP_RESTORE) ||
- (((PSWP)mp1)->fs & SWP_MAXIMIZE) )
- SendCommand( (USHORT)UM_SIZING, 0L);
- break;
-
- /************************************************************************
- /* Process menu item commands, and commands generated from the keyboard
- /* via the accelerator table. Most are handled by the async thread
- /************************************************************************
- case WM_COMMAND:
- return( WndProcCommand( hwnd, msg, mp1, mp2));
- break;
-
- /************************************************************************
- /* Scrolling is handled by the async drawing thread. Simply pass on the
- /* command and parameters
- /************************************************************************
- case WM_HSCROLL:
- SendCommand( (USHORT)UM_HSCROLL, LONGFROMMP(mp2));
- break;
-
- case WM_VSCROLL:
- SendCommand( (USHORT)UM_VSCROLL, LONGFROMMP(mp2));
- break;
-
- /************************************************************************
- /* The client area is being resized. *
- /************************************************************************
- case WM_SIZE:
- return( WndProcSize( mp1, mp2));
- break;
-
- /************************************************************************
- /* Mouse commands are handled by the async thread. Simply send on the
- /* command and parameters.
- /************************************************************************
- case WM_BUTTON1DBLCLK:
- case WM_BUTTON1DOWN:
- if( hwnd != WinQueryFocus( HWND_DESKTOP, FALSE))
- WinSetFocus( HWND_DESKTOP, hwnd);
- if( !fButtonDown)
- {
- fButtonDown = TRUE;
- SendCommand( (USHORT)UM_LEFTDOWN, LONGFROMMP(mp1));
- }
- return((MRESULT) TRUE);
- break;
-
- case WM_BUTTON1UP:
- if( !fButtonDown)
- return((MRESULT) TRUE);
- if( SendCommand( (USHORT)UM_LEFTUP, LONGFROMMP(mp1)))
- fButtonDown = FALSE;
- else
- WinAlarm( HWND_DESKTOP, WA_WARNING);
- return((MRESULT) TRUE);
- break;
-
- case WM_MOUSEMOVE:
- if( fButtonDown && (pslPicked != NULL))
- SendCommand( (USHORT)UM_MOUSEMOVE, LONGFROMMP(mp1));
- return( WinDefWindowProc( hwnd, msg, mp1, mp2));
- break;
-
- /************************************************************************
- /* Default for the rest
- /************************************************************************
- default:
- return( WinDefWindowProc( hwnd, msg, mp1, mp2));
- }
-
- return( FALSE);
- }
-
- /****************************************************************************
- /*
- /* Get the maximum client area size. Create a window DC for the client
- /* area and a normal GPI Presentation Space and associate the two. The GPI
- /* PS will be the maximum client area size and be in pels.
- /*
- /****************************************************************************
- MRESULT
- WndProcCreate( hwnd)
-
- HWND hwnd;
- {
- SIZEL sizlPickApp; /* pick aperture size
-
- sizlMaxClient.cx = WinQuerySysValue( HWND_DESKTOP, SV_CXFULLSCREEN);
- sizlMaxClient.cy = WinQuerySysValue( HWND_DESKTOP, SV_CYFULLSCREEN);
-
- hdcClient = WinOpenWindowDC( hwnd);
- hpsClient = GpiCreatePS( habMain
- , hdcClient
- , &sizlMaxClient
- , GPIA_ASSOC | PU_PELS );
- if( !hpsClient)
- return((MRESULT) TRUE);
- GpiSetAttrMode( hpsClient, AM_PRESERVE);
-
- hwndHorzScroll = WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT, FALSE)
- , FID_HORZSCROLL);
-
- hwndVertScroll = WinWindowFromID( WinQueryWindow( hwnd, QW_PARENT, FALSE)
- , FID_VERTSCROLL);
-
- hpsPaint = GpiCreatePS( habMain, NULL, &sizlMaxClient, PU_PELS);
-
- hrgnInvalid = GpiCreateRegion( hpsClient, 0L, NULL);
-
- sizlPickApp.cx = sizlPickApp.cy = 1;
- GpiSetPickApertureSize( hpsClient, PICKAP_REC, &sizlPickApp);
- return( FALSE);
- }
-
-
- /****************************************************************************
- /*
- /* WM_PAINT message
- /*
- /****************************************************************************
- MRESULT
- WndProcPaint()
-
- {
- HRGN hrgnUpdt;
- SHORT sRgnType;
-
- hrgnUpdt = GpiCreateRegion( hpsPaint, 0L, NULL);
- sRgnType = WinQueryUpdateRegion( hwndClient, hrgnUpdt);
- WinValidateRegion( hwndClient, hrgnUpdt, FALSE);
- SendCommand( UM_DRAW, (ULONG)hrgnUpdt);
- return( FALSE);
- }
-
- /****************************************************************************
- /* Process menu item commands, and commands generated from the keyboard via
- /* the accelerator table. Most are handled by the async thread
- /****************************************************************************
- MRESULT
- WndProcCommand( hwnd, msg, mp1, mp2)
-
- HWND hwnd;
- USHORT msg;
- MPARAM mp1, mp2;
- {
- CHAR szTemp[128];
- DLF dlf;
- SEL sel;
- PLOADINFO pli;
- PSZ pszError, psz1, psz2;
-
- switch( SHORT1FROMMP(mp1))
- {
- case MENU_JUMBLE:
- SendCommand( UM_JUMBLE, 0L);
- break;
-
- case MENU_LOAD:
- DosAllocSeg( sizeof( LOADINFO), &sel, 0);
- pli = MAKEP( sel, 0);
-
- dlf.rgbAction = DLG_OPENDLG;
- dlf.rgbFlags = ATTRDIRLIST;
- dlf.phFile = &(pli->hf);
- dlf.pszExt = (PSZ)"\\*.bmp";
- dlf.pszAppName = szTitle;
- dlf.pszTitle = "Load Bitmap";
- dlf.pszInstructions = NULL;
- dlf.szFileName[0] = '\0';
- dlf.szOpenFile[0] = '\0';
- pszError = "Error reading file.";
-
- switch( DlgFile( hwnd, &dlf))
- {
- case TDF_ERRMEM:
- case TDF_INVALID:
- MyMessageBox( hwnd, pszError);
- break;
-
- case TDF_NOOPEN:
- break;
-
- default:
- for( psz1 = dlf.szFileName, psz2 = pli->szFileName
- ; *psz2++ = *psz1++
- ; )
- ;
- SendCommand( UM_LOAD, (LONG)pli);
- break;
- }
- break;
- /**********************************************************************/
- /* EXIT command, menu item or F3 key pressed. Give the operator a
- /* second chance, if confirmed post a WM_QUIT msg to the application */
- /* msg queue. This will force the MAIN thread to terminate. */
- /**********************************************************************/
- case MENU_EXIT:
- WinLoadString( habMain, (HMODULE) NULL, TERMINATE, sizeof(szTemp), szTe
- if( WinMessageBox( HWND_DESKTOP
- , hwndFrame
- , szTemp
- , szTitle
- , 0
- , MB_CUAWARNING | MB_YESNO | MB_DEFBUTTON2)
- == MBID_YES)
- WinPostMsg( hwnd, WM_QUIT, NULL, NULL);
- break;
-
- /**********************************************************************/
- /* Pass on the rest to the async thread.
- /**********************************************************************/
- case MENU_ZOOMIN:
- SendCommand( UM_ZOOM_IN, 0L);
- break;
-
- case MENU_ZOOMOUT:
- SendCommand( UM_ZOOM_OUT, 0L);
- break;
-
- case MENU_FASTDRAG:
- SendCommand( UM_FASTDRAG, 0L);
- break;
-
- /**********************************************************************/
- /* Unrecognised => default
- /**********************************************************************/
- default:
- return( WinDefWindowProc(hwnd, msg, mp1, mp2));
- }
- return( FALSE);
- }
-
- /****************************************************************************
- /* Load a bitmap
- /****************************************************************************
- VOID
- Load( pli)
-
- PLOADINFO pli;
- {
- PSZ pszError;
- RECTL rclClient;
-
- pszError = (PSZ)"Error reading file.";
-
- DumpPicture();
- if( !ReadBitmap( pli->hf) )
- {
- MyMessageBox( hwndClient, pszError);
- return;
- }
- if( !PrepareBitmap() )
- {
- MyMessageBox( hwndClient, pszError);
- return;
- }
-
- lstrcpy( swctl.szSwtitle, szTitle);
- lstrcat( swctl.szSwtitle, ": ");
- lstrcat( swctl.szSwtitle, pli->szFileName);
- WinChangeSwitchEntry( hsw, &swctl);
- WinSetWindowText( hwndFrame, swctl.szSwtitle);
-
- CreatePicture();
- lScale = 0;
-
- WinQueryWindowRect( hwndClient, &rclClient);
- ptsScrollMax.x = (SHORT)(rclClient.xRight - rclClient.xLeft);
- ptsHalfScrollMax.x = ptsScrollMax.x >> 1;
- ptsScrollPos.x = ptsHalfScrollMax.x;
- ptsOldScrollPos.x = ptsHalfScrollMax.x;
- WinSendMsg( hwndHorzScroll
- , SBM_SETSCROLLBAR
- , MPFROMSHORT( ptsScrollPos.x)
- , MPFROM2SHORT( 1, ptsScrollMax.x) );
- ptsScrollMax.y = (SHORT)(rclClient.yTop - rclClient.yBottom);
- ptsHalfScrollMax.y = ptsScrollMax.y >> 1;
- ptsScrollPos.y = ptsHalfScrollMax.y;
- ptsOldScrollPos.y = ptsHalfScrollMax.y;
- WinSendMsg( hwndVertScroll
- , SBM_SETSCROLLBAR
- , MPFROMSHORT( ptsScrollPos.y)
- , MPFROM2SHORT( 1, ptsScrollMax.y) );
-
- CalcBounds();
- CalcTransform( hwndClient);
- DosFreeSeg( SELECTOROF( pli));
- }
- /****************************************************************************
- /* Throw the pieces around the screen.
- /****************************************************************************
- VOID
- Jumble()
- {
- LONG lWidth, lHeight;
- DATETIME date;
- POINTL ptl;
- RECTL rclClient;
- PSEGLIST psl;
-
- if( WinQueryWindowRect( hwndClient, &rclClient) )
- {
- lWidth = rclClient.xRight - rclClient.xLeft;
- lHeight = rclClient.yTop - rclClient.yBottom;
- if( (lWidth > 0) && (lHeight > 0) )
- {
- DosGetDateTime( &date);
- srand( (USHORT)date.hundredths);
- for( psl = pslHead; psl != NULL; psl = psl->pslNext)
- {
- ptl.x = rclClient.xLeft + (rand() % lWidth);
- ptl.y = rclClient.yBottom + (rand() % lHeight);
- Translate( psl, &ptl);
- SetRect( psl);
- }
- }
- }
- }
-
- /****************************************************************************
- /* The client area is being resized. The current scroll bar thumb position
- /* and scroll bar range must be recalculated prior to recalculating the
- /* default viewing transform for the picture. Wait for subsequent WM_PAINT
- /* to do any drawing.
- /****************************************************************************
- MRESULT
- WndProcSize( mp1, mp2)
-
- MPARAM mp1, mp2;
- {
- HWND hwndFrameTemp;
-
- if( hwndFrame)
- hwndFrameTemp = hwndFrame;
- else
- hwndFrameTemp = WinQueryWindow( hwndClient, QW_PARENT, FALSE);
-
- ptsScrollMax.y = SHORT2FROMMP( mp2);
- ptsHalfScrollMax.y = ptsScrollMax.y >> 1;
- if( mp1)
- {
- ptsScrollPos.y = (SHORT)(((LONG)ptsScrollPos.y * (LONG)SHORT2FROMMP(mp2
- ptsOldScrollPos.y = (SHORT)(((LONG)ptsOldScrollPos.y * (LONG)SHORT2FROM
- } else
- {
- ptsScrollPos.y = ptsHalfScrollMax.y; /* first sizing after window c
- ptsOldScrollPos.y = ptsHalfScrollMax.y;
- }
- WinSendMsg( hwndVertScroll
- , SBM_SETSCROLLBAR
- , MPFROMSHORT( ptsScrollPos.y)
- , MPFROM2SHORT( 1, ptsScrollMax.y) );
-
-
- ptsScrollMax.x = SHORT1FROMMP( mp2);
- ptsHalfScrollMax.x = ptsScrollMax.x >> 1;
- if( mp1)
- {
- ptsScrollPos.x = (SHORT)(((LONG)ptsScrollPos.x * (LONG)SHORT1FROMMP(mp2
- ptsOldScrollPos.x = (SHORT)(((LONG)ptsOldScrollPos.x * (LONG)SHORT1FROM
- } else
- {
- ptsScrollPos.x = ptsHalfScrollMax.x; /* first sizing after window c
- ptsOldScrollPos.x = ptsHalfScrollMax.x;
- }
- WinSendMsg( hwndHorzScroll
- , SBM_SETSCROLLBAR
- , MPFROMSHORT( ptsScrollPos.x)
- , MPFROM2SHORT( 1, ptsScrollMax.x) );
-
-
- SendCommand( UM_SIZING, 0L);
- return( FALSE);
- }
-
- /****************************************************************************
- /*
- /* NewThread is the asynchronous drawing thread. It is responsible for all
- /* drawing. It will initialize its PM interface and create an application
- /* message queue. It will then monitor its message queue and process any
- /* commands received.
- /*
- /****************************************************************************
- VOID FAR
- NewThread()
- {
- QMSG qmsgAsync, qmsgPeek;
- BOOL fDone;
-
- /**************************************************************************
- /* Initialize the PM interface. If it fails, terminate both threads.
- /**************************************************************************
- habAsync = WinInitialize( 0);
- if( !habAsync)
- {
- WinPostMsg( hwndClient, WM_QUIT, NULL, NULL);
- DosExit( EXIT_THREAD, 0);
- }
-
- /**************************************************************************
- /* Create a message queue. If it fails, terminate both threads.
- /**************************************************************************
- hmqAsync = WinCreateMsgQueue( habAsync, 80);
- if( !hmqAsync)
- {
- WinPostMsg( hwndClient, WM_QUIT, NULL, NULL);
- WinTerminate( habAsync);
- DosExit( EXIT_THREAD, 0);
- }
-
- DosSetPrty( PRTYS_THREAD, PRTYC_NOCHANGE, sPrty, (TID)NULL);
-
-
- while( TRUE)
- {
- WinGetMsg( habAsync, &qmsgAsync, NULL, 0, 0);
-
- /************************************************************************
- /* process the commands
- /************************************************************************
- switch( qmsgAsync.msg)
- {
-
- /**********************************************************************
- /**********************************************************************
- case UM_LOAD:
- Load( (PLOADINFO)qmsgAsync.mp1);
- Redraw();
- break;
-
- /**********************************************************************
- case UM_JUMBLE:
- Jumble();
- Redraw();
- break;
-
- /**********************************************************************
- case UM_REDRAW:
- Redraw();
- break;
-
- /**********************************************************************
- /* DRAW will use the passed region containing the invalidated area of
- /* the screen, repaint it and then destroy the region.
- /**********************************************************************
- case UM_DRAW:
- DoDraw( (HRGN)qmsgAsync.mp1);
- if( qmsgAsync.mp1)
- GpiDestroyRegion( hpsClient, (HRGN)qmsgAsync.mp1);
- break;
-
-
- /**********************************************************************
- /* Get new scroll posn from command ( i.e. +/-1 +/-page) or new
- /* absolute position from parameter, update scroll posn, change the
- /* transform and update the thumb posn. Finally update the window.
- /**********************************************************************
- case UM_HSCROLL:
- switch( SHORT2FROMMP( qmsgAsync.mp1) )
- {
- case SB_LINEUP:
- ptsScrollPos.x -= ptsScrollLine.x;
- break;
- case SB_LINEDOWN:
- ptsScrollPos.x += ptsScrollLine.x;
- break;
- case SB_SLIDERTRACK:
- case SB_SLIDERPOSITION:
- for( fDone = FALSE; !fDone ;)
- {
- if( WinPeekMsg( habAsync
- , &qmsgPeek
- , NULL
- , UM_HSCROLL
- , UM_HSCROLL
- , PM_NOREMOVE))
- if( (SHORT2FROMMP( qmsgPeek.mp1) == SB_SLIDERTRACK)
- ||(SHORT2FROMMP( qmsgPeek.mp1) == SB_SLIDERPOSITION
- WinPeekMsg( habAsync
- , &qmsgAsync
- , NULL
- , UM_HSCROLL
- , UM_HSCROLL
- , PM_REMOVE);
- else
- fDone = TRUE;
- else
- fDone = TRUE;
- }
- ptsScrollPos.x = SHORT1FROMMP( qmsgAsync.mp1);
- break;
- case SB_PAGEUP:
- ptsScrollPos.x -= ptsScrollPage.x;
- break;
- case SB_PAGEDOWN:
- ptsScrollPos.x += ptsScrollPage.x;
- break;
- case SB_ENDSCROLL:
- break;
- default:
- break;
- }
- DoHorzScroll();
- break;
-
- case UM_VSCROLL:
- switch( SHORT2FROMMP( qmsgAsync.mp1) )
- {
- case SB_LINEUP:
- ptsScrollPos.y -= ptsScrollLine.y;
- break;
- case SB_LINEDOWN:
- ptsScrollPos.y += ptsScrollLine.y;
- break;
- case SB_SLIDERTRACK:
- case SB_SLIDERPOSITION:
- for( fDone = FALSE; !fDone ;)
- {
- if( WinPeekMsg( habAsync
- , &qmsgPeek
- , NULL
- , UM_VSCROLL
- , UM_VSCROLL
- , PM_NOREMOVE))
- if( (SHORT2FROMMP( qmsgPeek.mp1) == SB_SLIDERTRACK)
- ||(SHORT2FROMMP( qmsgPeek.mp1) == SB_SLIDERPOSITION
- WinPeekMsg( habAsync
- , &qmsgAsync
- , NULL
- , UM_VSCROLL
- , UM_VSCROLL
- , PM_REMOVE);
- else
- fDone = TRUE;
- else
- fDone = TRUE;
- }
- ptsScrollPos.y = SHORT1FROMMP( qmsgAsync.mp1);
- break;
- case SB_PAGEUP:
- ptsScrollPos.y -= ptsScrollPage.y;
- break;
- case SB_PAGEDOWN:
- ptsScrollPos.y += ptsScrollPage.y;
- break;
- case SB_ENDSCROLL:
- break;
- default:
- break;
- }
- DoVertScroll();
- break;
-
- /**********************************************************************
- /* recalc the picture transform
- /**********************************************************************
- case UM_SIZING:
- CalcBounds();
- CalcTransform( hwndClient);
- break;
-
- /**********************************************************************
- /* adjust zoom factor
- /**********************************************************************
- case UM_ZOOM_IN:
- Zoom( ZOOM_IN_ARG);
- break;
-
- case UM_ZOOM_OUT:
- Zoom( ZOOM_OUT_ARG);
- break;
-
- /**********************************************************************
- /* toggle fast-drag
- /**********************************************************************
- case UM_FASTDRAG:
- ToggleFastDrag();
- break;
-
- /**********************************************************************
- /* Button down will cause a correlate on the picture to test for a hit.
- /* Any selected segment will be highlighted and redrawn as dynamic.
- /**********************************************************************
- case UM_LEFTDOWN:
- LeftDown( qmsgAsync.mp1);
- break;
-
- /**********************************************************************
- /* if a segment is being dragged it will be redrawn in a new posn
- /**********************************************************************
- case UM_MOUSEMOVE:
- for( fDone = FALSE; !fDone ;)
- {
- if( WinPeekMsg( habAsync
- , &qmsgPeek
- , NULL
- , UM_MOUSEMOVE
- , UM_LEFTUP
- , PM_NOREMOVE))
- if( qmsgPeek.msg == UM_MOUSEMOVE)
- WinPeekMsg( habAsync
- , &qmsgAsync
- , NULL
- , UM_MOUSEMOVE
- , UM_MOUSEMOVE
- , PM_REMOVE);
- else
- fDone = TRUE;
- else
- fDone = TRUE;
- }
- MouseMove( qmsgAsync.mp1);
- break;
-
- /**********************************************************************
- /* if a segment is being dragged it will be redrawn as normal
- /**********************************************************************
- case UM_LEFTUP:
- LeftUp();
- break;
-
- /**********************************************************************
- /* destroy resources and terminate
- /**********************************************************************
- case UM_DIE:
- WinDestroyMsgQueue( hmqAsync);
- WinTerminate( habAsync);
- DosEnterCritSec();
- DosSemClear( hsemTerminate);
- DosExit( EXIT_THREAD, 0);
- break;
-
- /**********************************************************************
- /* finish flush of commands from queue
- /**********************************************************************
- case UM_FLUSH:
- break;
-
- default:
- break;
- }
- }
- }
-
- /****************************************************************************
- /* button down will cause one segment to be indicated and made dynamic
- /****************************************************************************
- VOID
- LeftDown( mp)
-
- MPARAM mp;
- {
- HRGN hrgnUpdt;
- LONG alSegTag[HITS][DEPTH][2];
- POINTL ptl, aptl[4];
- RECTL rcl;
- MATRIXLF matlf;
- LONG lOffset;
- BYTE bBuff[128];
- CHAR pszMsg[40];
- PSZ psz1, psz2;
-
- ptl.x = (LONG)(SHORT)SHORT1FROMMP( mp);
- ptl.y = (LONG)(SHORT)SHORT2FROMMP( mp);
-
- /**************************************************************************
- /**************************************************************************
- for( pslPicked = pslTail; pslPicked != NULL; pslPicked = pslPicked->pslPrev
- {
- rcl = pslPicked->rclCurrent;
- GpiConvert( hpsClient, CVTC_MODEL, CVTC_DEVICE, 2L, (PPOINTL)&rcl);
- rcl.xRight++;
- rcl.yTop++;
- if( WinPtInRect( habAsync, &rcl, &ptl))
- {
- LONG lRet;
-
- GpiSetEditMode( hpsClient, SEGEM_INSERT);
- GpiOpenSegment( hpsClient, pslPicked->lSegId);
- GpiSetElementPointerAtLabel( hpsClient, FILLPATH);
- GpiFillPath( hpsClient, 1L, 0L);
- GpiCloseSegment( hpsClient);
- lRet = GpiCorrelateSegment( hpsClient
- , pslPicked->lSegId
- , PICKSEL_VISIBLE
- , &ptl
- , HITS
- , DEPTH
- , (PLONG)alSegTag );
- GpiOpenSegment( hpsClient, pslPicked->lSegId);
- GpiSetElementPointerAtLabel( hpsClient, FILLPATH);
- GpiOffsetElementPointer( hpsClient, 1L);
- GpiDeleteElement( hpsClient);
- GpiCloseSegment( hpsClient);
-
- if( lRet > 0)
- break;
- }
- }
- if( pslPicked)
- lPickedSeg = pslPicked->lSegId;
- else
- {
- fButtonDown = FALSE;
- return;
- }
- if( (lPickedSeg < 1) || (lPickedSeg > lLastSegId) )
- {
- DosSemRequest( hsemSzFmt, SEM_INDEFINITE_WAIT);
- sprintf( szFmt, "Segment id out of range: %x", lPickedSeg);
- for( psz1 = szFmt, psz2 = pszMsg; *psz2++ = *psz1++; )
- ;
- DosSemClear( hsemSzFmt);
- MyMessageBox( hwndClient, pszMsg);
- fButtonDown = FALSE;
- return;
- }
-
- /**************************************************************************
- hrgnUpdt = GpiCreateRegion( hpsClient, 1L, &rcl);
- GpiSetSegmentAttrs( hpsClient, lPickedSeg, ATTR_VISIBLE, ATTR_OFF);
-
- GpiQuerySegmentTransformMatrix( hpsClient
- , lPickedSeg
- , 9L
- , &matlf );
- GpiBeginPath( hpsClient, 1L);
- GpiCallSegmentMatrix( hpsClient
- , lPickedSeg + CALLSEG_BASE
- , 9L
- , &matlf
- , TRANSFORM_REPLACE );
- GpiEndPath( hpsClient);
- GpiSetClipPath( hpsClient, 1L, SCP_AND);
- DoDraw( hrgnUpdt);
- GpiSetClipPath( hpsClient, 0L, SCP_RESET);
- GpiDestroyRegion( hpsClient, hrgnUpdt);
-
- /**************************************************************************
- ptlOffset = ptlBotLeft;
- GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 1L, &ptlOffset);
-
- aptl[0].x = pslPicked->rclBitBlt.xLeft;
- aptl[0].y = pslPicked->rclBitBlt.yBottom;
- aptl[1].x = pslPicked->rclBitBlt.xRight;
- aptl[1].y = pslPicked->rclBitBlt.yTop;
- aptl[2] = aptl[0];
- aptl[3] = aptl[1];
- GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 2L, &aptl[2]);
- aptl[2].x -= ptlOffset.x;
- aptl[2].y -= ptlOffset.y;
- aptl[3].x -= ptlOffset.x - 1;
- aptl[3].y -= ptlOffset.y - 1;
- GpiSetEditMode( hpsClient, SEGEM_INSERT);
-
- for( lOffset = 0L; GpiGetData( hpsClient
- , lPickedSeg
- , &lOffset
- , DFORM_NOCONV
- , (LONG)sizeof( bBuff)
- , bBuff) > 0; )
- ;
-
- GpiOpenSegment( hpsClient, lPickedSeg);
- GpiDeleteElementsBetweenLabels( hpsClient, BITBLT_TOP, BITBLT_BOTTOM);
- if( !fFastDrag)
- GpiWCBitBlt( hpsClient
- , hbmBitmapDrag
- , 4L
- , aptl
- , ROP_SRCCOPY
- , BBO_IGNORE );
- GpiCloseSegment( hpsClient);
-
- for( lOffset = 0L; GpiGetData( hpsClient
- , lPickedSeg
- , &lOffset
- , DFORM_NOCONV
- , (LONG)sizeof( bBuff)
- , bBuff) > 0; )
- ;
-
- /**************************************************************************
- GpiSetSegmentAttrs( hpsClient, lPickedSeg, ATTR_VISIBLE, ATTR_ON);
- GpiSetSegmentAttrs( hpsClient, lPickedSeg, ATTR_DYNAMIC, ATTR_ON);
- GpiSetDrawControl( hpsClient, DCTL_DYNAMIC, DCTL_ON);
- GpiDrawSegment( hpsClient, lPickedSeg);
-
- WinSetCapture( HWND_DESKTOP, hwndClient);
- }
-
-
-
-
- /****************************************************************************
- /*
- /* move the segment
- /*
- /****************************************************************************
- VOID
- MouseMove( mp)
-
- MPARAM mp;
- {
- RECTL rcl;
- POINTL ptl, ptlModel;
-
- ptl.x = (LONG)(SHORT)SHORT1FROMMP( mp);
- ptl.y = (LONG)(SHORT)SHORT2FROMMP( mp);
-
- ptlModel = ptl;
- GpiConvert( hpsClient, CVTC_DEVICE, CVTC_MODEL, 1L, &ptlModel);
- ptlModel.x = 5 * (ptlModel.x / 5);
- ptlModel.y = 5 * (ptlModel.y / 5);
- if( (ptlModel.x == ptlOldMouse.x) && (ptlModel.y == ptlOldMouse.y))
- return;
- ptlOldMouse.x = ptlModel.x;
- ptlOldMouse.y = ptlModel.y;
-
- /**************************************************************************
- /* clip mouse coords to client window
- /**************************************************************************
- WinQueryWindowRect(hwndClient, &rcl);
- if (rcl.xLeft > ptl.x)
- ptl.x = rcl.xLeft;
- if (rcl.xRight <= ptl.x)
- ptl.x = rcl.xRight;
- if (rcl.yBottom > ptl.y)
- ptl.y = rcl.yBottom;
- if (rcl.yTop <= ptl.y)
- ptl.y = rcl.yTop;
-
- GpiRemoveDynamics( hpsClient, lPickedSeg, lPickedSeg);
- Translate( pslPicked, &ptl);
- GpiDrawDynamics( hpsClient);
- }
-
-
- /****************************************************************************
- /*
- /* The dragged segment is being unselected. Return it to its normal state.
- /*
- /****************************************************************************
- VOID
- LeftUp()
- {
- SEGLIST sl;
- POINTL aptl[4];
-
- if( !lPickedSeg)
- return;
- GpiRemoveDynamics( hpsClient, lPickedSeg, lPickedSeg);
- GpiSetSegmentAttrs( hpsClient, lPickedSeg, ATTR_DYNAMIC, ATTR_OFF);
-
- /**************************************************************************
- ptlOffset = ptlBotLeft;
- GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 1L, &ptlOffset);
-
- aptl[0].x = pslPicked->rclBitBlt.xLeft;
- aptl[0].y = pslPicked->rclBitBlt.yBottom;
- aptl[1].x = pslPicked->rclBitBlt.xRight;
- aptl[1].y = pslPicked->rclBitBlt.yTop;
- aptl[2] = aptl[0];
- aptl[3] = aptl[1];
- GpiConvert( hpsClient, CVTC_WORLD, CVTC_DEVICE, 2L, &aptl[2]);
- aptl[2].x -= ptlOffset.x;
- aptl[2].y -= ptlOffset.y;
- aptl[3].x -= ptlOffset.x - 1;
- aptl[3].y -= ptlOffset.y - 1;
- GpiSetEditMode( hpsClient, SEGEM_INSERT);
- GpiOpenSegment( hpsClient, lPickedSeg);
- GpiDeleteElementsBetweenLabels( hpsClient, BITBLT_TOP, BITBLT_BOTTOM);
- GpiWCBitBlt( hpsClient
- , hbmBitmapTemp
- , 4L
- , aptl
- , ROP_SRCCOPY
- , BBO_IGNORE );
- GpiCloseSegment( hpsClient);
-
- /**************************************************************************
- GpiDrawSegment( hpsClient, lPickedSeg);
- GpiSetSegmentPriority( hpsClient, lPickedSeg, 0L, LOWER_PRI); /* highest
- SetRect( pslPicked);
-
- sl = *pslPicked;
- SegListUpdate( DEL_SEG, pslPicked);
- SegListUpdate( ADD_TAIL_SEG, &sl); /* at tail => highest priorit
- pslPicked = NULL;
-
- WinSetCapture( HWND_DESKTOP, (HWND)NULL);
- }
-
-
- /****************************************************************************
- /*
- /* DoHorzScroll will horizontally scroll the current contents of
- /* the client area and redraw the invalidated area
- /*
- /****************************************************************************
- VOID
- DoHorzScroll()
- {
- RECTL rcl;
- HRGN hrgn;
- MATRIXLF matlf;
-
- if( ptsScrollPos.x > ptsScrollMax.x)
- ptsScrollPos.x = ptsScrollMax.x;
- if( ptsScrollPos.x < 0)
- ptsScrollPos.x = 0;
-
- if( ptsOldScrollPos.x != ptsScrollPos.x)
- WinSendMsg( hwndHorzScroll
- , SBM_SETPOS
- , MPFROM2SHORT( ptsScrollPos.x, 0)
- , MPFROMLONG( NULL));
-
- /**************************************************************************
- /* Scroll the window the reqd amount, using bitblt'ing (ScrollWindow)
- /* if any of the screen still in view, and paint into uncovered region;
- /* else repaint the whole client area.
- /**************************************************************************
- hrgn = GpiCreateRegion( hpsClient, 0L, NULL);
- if( abs( ptsScrollPos.x - ptsOldScrollPos.x) <= ptsScrollMax.x)
- {
- WinScrollWindow( hwndClient
- , ptsOldScrollPos.x - ptsScrollPos.x
- , 0
- , NULL
- , NULL
- , hrgn
- , &rcl
- , 0);
- } else
- {
- WinQueryWindowRect( hwndClient, &rcl);
- GpiSetRegion( hpsClient, hrgn, 1L, &rcl);
- }
- GpiQueryDefaultViewMatrix( hpsClient, 9L, &matlf );
- matlf.lM31 -= ptsScrollPos.x - ptsOldScrollPos.x;
- GpiSetDefaultViewMatrix( hpsClient, 9L, &matlf, TRANSFORM_REPLACE);
-
- DoDraw( hrgn);
- ptsOldScrollPos.x = ptsScrollPos.x;
- GpiDestroyRegion( hpsClient, hrgn);
- }
-
- /****************************************************************************
- /*
- /* DoVertScroll will vertically scroll the current contents of
- /* the client area and redraw the invalidated area
- /*
- /****************************************************************************
- VOID
- DoVertScroll()
- {
- RECTL rcl;
- HRGN hrgn;
- MATRIXLF matlf;
-
- if( ptsScrollPos.y > ptsScrollMax.y)
- ptsScrollPos.y = ptsScrollMax.y;
- if( ptsScrollPos.y < 0)
- ptsScrollPos.y = 0;
-
- if( ptsOldScrollPos.y != ptsScrollPos.y)
- WinSendMsg( hwndVertScroll
- , SBM_SETPOS
- , MPFROM2SHORT( ptsScrollPos.y, 0)
- , MPFROMLONG( NULL));
-
- /**************************************************************************
- /* Scroll the window the reqd amount, using bitblt'ing (ScrollWindow)
- /* if any of the screen still in view, and paint into uncovered region;
- /* else repaint the whole client area.
- /**************************************************************************
- hrgn = GpiCreateRegion( hpsClient, 0L, NULL);
- if( abs( ptsScrollPos.y - ptsOldScrollPos.y) <= ptsScrollMax.y)
- {
- WinScrollWindow( hwndClient
- , 0
- , ptsScrollPos.y - ptsOldScrollPos.y
- , NULL
- , NULL
- , hrgn
- , &rcl
- , 0);
- } else
- {
- WinQueryWindowRect( hwndClient, &rcl);
- GpiSetRegion( hpsClient, hrgn, 1L, &rcl);
- }
- GpiQueryDefaultViewMatrix( hpsClient, 9L, &matlf );
- matlf.lM32 += ptsScrollPos.y - ptsOldScrollPos.y;
- GpiSetDefaultViewMatrix( hpsClient, 9L, &matlf, TRANSFORM_REPLACE);
-
- DoDraw( hrgn);
- ptsOldScrollPos.y = ptsScrollPos.y;
- GpiDestroyRegion( hpsClient, hrgn);
- }
-
- /****************************************************************************
- /*
- /* Redraw the entire client window.
- /*
- /****************************************************************************
- VOID
- Redraw()
- {
- RECTL rclInvalid;
- HRGN hrgnUpdt;
-
- WinQueryWindowRect( hwndClient, &rclInvalid);
- hrgnUpdt = GpiCreateRegion( hpsClient, 1L, &rclInvalid);
- DoDraw( hrgnUpdt);
- GpiDestroyRegion( hpsClient, hrgnUpdt);
- }
-
-
- /****************************************************************************
- /*
- /* toggle the fast-drag flag and update the menu check-box
- /*
- /****************************************************************************
- VOID
- ToggleFastDrag()
- {
- MENUITEM mi;
- HWND hwndMenu, hwndOptions;
-
- hwndMenu = WinWindowFromID( hwndFrame, FID_MENU);
- WinSendMsg( hwndMenu
- , MM_QUERYITEM
- , MPFROM2SHORT( SM_OPTIONS, FALSE)
- , MPFROMP( (PMENUITEM)&mi));
- hwndOptions = mi.hwndSubMenu;
-
- if( fFastDrag)
- {
- fFastDrag = FALSE;
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_FASTDRAG, TRUE)
- , MPFROM2SHORT( MIA_CHECKED, ~MIA_CHECKED) );
- }
- else
- {
- fFastDrag = TRUE;
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_FASTDRAG, TRUE)
- , MPFROM2SHORT( MIA_CHECKED, MIA_CHECKED) );
- }
- }
-
- /****************************************************************************
- /*
- /* adjust zoom factor and recalc the picture transform, then do a redraw of
- /* whole screen
- /*
- /****************************************************************************
- VOID
- Zoom( sInOrOut)
-
- SHORT sInOrOut;
- {
- LONG lScaleOld;
-
- lScaleOld = lScale;
- lScale += sInOrOut;
- if( lScale > ZOOM_MAX)
- lScale = ZOOM_MAX;
- else
- if( lScale < -ZOOM_MAX)
- lScale = -ZOOM_MAX;
- if( lScale != lScaleOld)
- {
- ZoomMenuItems();
- CalcBounds();
- CalcTransform( hwndClient);
- Redraw();
- }
- }
-
- /****************************************************************************
- /*
- /* enable/disable zoom menu items depending on scaling
- /*
- /****************************************************************************
- VOID
- ZoomMenuItems()
- {
- MENUITEM mi;
- HWND hwndMenu, hwndOptions;
-
- hwndMenu = WinWindowFromID( hwndFrame, FID_MENU);
- WinSendMsg( hwndMenu
- , MM_QUERYITEM
- , MPFROM2SHORT( SM_OPTIONS, FALSE)
- , MPFROMP( (PMENUITEM)&mi));
- hwndOptions = mi.hwndSubMenu;
-
- if( lScale >= ZOOM_MAX)
- {
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_ZOOMIN, TRUE)
- , MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED));
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_ZOOMOUT, TRUE)
- , MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED));
- } else
- {
- if( lScale <= - ZOOM_MAX)
- {
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_ZOOMOUT, TRUE)
- , MPFROM2SHORT( MIA_DISABLED, MIA_DISABLED));
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_ZOOMIN, TRUE)
- , MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED));
- } else
- {
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_ZOOMOUT, TRUE)
- , MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED));
- WinSendMsg( hwndOptions
- , MM_SETITEMATTR
- , MPFROM2SHORT( MENU_ZOOMIN, TRUE)
- , MPFROM2SHORT( MIA_DISABLED, ~MIA_DISABLED));
- }
- }
- }
-
- /****************************************************************************
- /*
- /* Determine the bounding rect of a segment.
- /*
- /****************************************************************************
- VOID
- SetRect( psl)
-
- PSEGLIST psl;
- {
- GpiResetBoundaryData( hpsClient);
- GpiSetDrawControl( hpsClient, DCTL_DISPLAY, DCTL_OFF);
- GpiSetDrawControl( hpsClient, DCTL_BOUNDARY, DCTL_ON);
- GpiDrawSegment( hpsClient, psl->lSegId);
- GpiSetDrawControl( hpsClient, DCTL_DISPLAY, DCTL_ON);
- GpiSetDrawControl( hpsClient, DCTL_BOUNDARY, DCTL_OFF);
- GpiQueryBoundaryData( hpsClient, &(psl->rclCurrent));
- }
-
- /****************************************************************************
- /*
- /* Translate a segment
- /*
- /****************************************************************************
- VOID
- Translate( psl, pptlNew)
-
- PSEGLIST psl;
- PPOINTL pptlNew;
- {
- POINTL ptl;
- MATRIXLF matlf;
-
- ptl = *pptlNew;
- GpiConvert( hpsClient, CVTC_DEVICE, CVTC_MODEL, 1L, &ptl);
- ptl.x = (ptl.x / 5) * 5;
- ptl.y = (ptl.y / 5) * 5;
- ptl.x -= 25;
- ptl.y -= 25;
-
- GpiQuerySegmentTransformMatrix( hpsClient
- , psl->lSegId
- , 9L
- , &matlf);
- matlf.lM31 = ptl.x - (psl->ptlLocation).x;
- matlf.lM32 = ptl.y - (psl->ptlLocation).y;
- GpiSetSegmentTransformMatrix( hpsClient
- , psl->lSegId
- , 9L
- , &matlf
- , TRANSFORM_REPLACE);
- }
-
-
- /****************************************************************************
- /*
- /* set the default viewing transform
- /*
- /****************************************************************************
- VOID
- SetDVTransform( fx11, fx12, fx21, fx22, l31, l32, lType)
-
- FIXED fx11, fx12, fx21, fx22;
- LONG l31, l32, lType;
- {
- MATRIXLF matlf;
-
- matlf.fxM11 = fx11;
- matlf.fxM12 = fx12;
- matlf.lM13 = 0L;
- matlf.fxM21 = fx21;
- matlf.fxM22 = fx22;
- matlf.lM23 = 0L;
- matlf.lM31 = l31;
- matlf.lM32 = l32;
- matlf.lM33 = 1L;
- GpiSetDefaultViewMatrix( hpsClient, 9L, &matlf, lType);
- }
-
- /****************************************************************************
- /*
- /* get bounding rect of whole picture in model coordinates
- /*
- /****************************************************************************
- VOID
- CalcBounds()
- {
- PSEGLIST psl;
- RECTL rcl;
-
- if( !pslHead)
- return;
- rclBounds = pslHead->rclCurrent;
- for( psl = pslHead->pslNext; psl != NULL; psl = psl->pslNext)
- {
- rcl = psl->rclCurrent;
- if( rcl.xLeft < rclBounds.xLeft)
- rclBounds.xLeft = rcl.xLeft;
- if( rcl.xRight > rclBounds.xRight)
- rclBounds.xRight = rcl.xRight;
- if( rcl.yTop > rclBounds.yTop)
- rclBounds.yTop = rcl.yTop;
- if( rcl.yBottom < rclBounds.yBottom)
- rclBounds.yBottom = rcl.yBottom;
- }
- }
-
- /****************************************************************************
- /*
- /* Calculate and set the default viewing transform based on zoom and scroll
- /*
- /****************************************************************************
- VOID
- CalcTransform( hwnd)
-
- HWND hwnd;
- {
- RECTL rclClient;
- POINTL ptlCenter, ptlTrans, ptlScale, aptl[4];
- HRGN hrgn;
- PSEGLIST psl;
-
- /**************************************************************************
- /* from bounding rect of picture get center of picture
- /**************************************************************************
- ptlCenter.x = (rclBounds.xLeft + rclBounds.xRight) / 2;
- ptlCenter.y = (rclBounds.yBottom + rclBounds.yTop ) / 2;
-
- /**************************************************************************
- /* translate center of picture to origin
- /**************************************************************************
- SetDVTransform( (FIXED)UNITY
- , (FIXED)0
- , (FIXED)0
- , (FIXED)UNITY
- , -ptlCenter.x
- , -ptlCenter.y
- , TRANSFORM_REPLACE);
-
- /**************************************************************************
- /* scale down to 60% of max client area
- /**************************************************************************
- ptlScale.x = (6 * UNITY * sizlMaxClient.cx) /
- (10 * (ptlTopRight.x - ptlBotLeft.x));
- ptlScale.y = (6 * UNITY * sizlMaxClient.cy) /
- (10 * (ptlTopRight.y - ptlBotLeft.y));
-
- /******************