home *** CD-ROM | disk | FTP | other *** search
- // Borland C++ - (C) Copyright 1991 by Borland International
-
- //*******************************************************************
- //
- // program - Msgwnd.c
- // purpose - A windows program to recieve and display messages.
- // This illustrates how DDE messages can be sent from
- // one application and received by another.
- //
- // To use this program, build MSGWND and TSTAPP. There
- // are project files for this. When you run TSTAPP, MSGWND
- // will be started automatically.
- //
- //*******************************************************************
-
- #include <windows.h>
- #include <dde.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <time.h>
- #include <bios.h>
- #include <ctype.h>
- #include <io.h>
- #include <dos.h>
-
- #include "msgwnd.h"
- #include "msgproc.h"
- #include "ddesrvr.h"
-
- #define MAX_QRT_LEN 100
-
- typedef struct scrollkeys
- {
- WORD wVirtkey;
- int iMessage;
- WORD wRequest;
- } SCROLLKEYS;
-
- SCROLLKEYS key2scroll [] =
- {
- VK_HOME, WM_COMMAND, IDM_HOME,
- VK_END, WM_VSCROLL, SB_BOTTOM,
- VK_PRIOR, WM_VSCROLL, SB_PAGEUP,
- VK_NEXT, WM_VSCROLL, SB_PAGEDOWN,
- VK_UP, WM_VSCROLL, SB_LINEUP,
- VK_DOWN, WM_VSCROLL, SB_LINEDOWN,
- VK_LEFT, WM_HSCROLL, SB_PAGEUP,
- VK_RIGHT, WM_HSCROLL, SB_PAGEDOWN
- };
-
- # define NUMKEYS (sizeof key2scroll / sizeof key2scroll[0])
-
- // data initialized by first instance
- typedef struct tagSETUPDATA
- {
- char szAppName[10]; // name of application
- } SETUPDATA;
-
- SETUPDATA SetUpData;
-
- // Data that can be referenced throughout the
- // program but not passed to other instances
-
- HANDLE hInst; // hInstance of application
- HWND hWndMain; // hWnd of main window
- //char szAppName[10]; // name of application
-
- int xChar, yChar, yCharnl;
- int xClient, yClient;
-
- LOGFONT cursfont;
- HANDLE holdsfont;
- HANDLE hnewsfont;
-
- RECT wrect;
-
- // window scroll/paint stuff
- int nVscrollMax, nHscrollMax;
- int nVscrollPos, nHscrollPos;
- int numlines;
- int maxwidth;
- int nVscrollInc, nHscrollInc;
- int nPaintBeg, nPaintEnd;
- int nPageMaxLines;
- int plines;
-
- // for scroll print
- RECT rect;
- int blanklen;
- char blanks[256];
-
- // to keep lines
- # define MAX_KEEP 50
- HANDLE hkeep[MAX_KEEP + 1];
- int hwm_keep;
-
- // function prototypes
-
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow);
-
- BOOL InitMsgwnd(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow);
- BOOL InitMsgwndFirst(HANDLE hInstance);
- BOOL InitMsgwndAdded(HANDLE hPrevInstance);
- BOOL InitMsgwndEvery(HANDLE hInstance, int cmdShow);
- void CloseMsgwnd(HWND hWnd);
- BOOL FAR PASCAL About(HWND hDlg, WORD message, WORD wParam, LONG lParam);
-
- long FAR PASCAL MsgwndWndProc(HWND hWnd, WORD message,
- WORD wParam, LONG lParam);
-
- void SetupScroll(HWND hWnd);
- void MsgwndPaint(HWND hWnd);
- void ScrollPrint(HWND hWnd, char *str);
- void ClearKeep(void);
-
- //*******************************************************************
- // WinMain - Msgwnd main
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- // hPrevInstance - The instance of the previous instance
- // of this application. This will be 0
- // if this is the first instance.
- // lpszCmdLine - A long pointer to the command line that
- // started this application.
- // cmdShow - Indicates how the window is to be shown
- // initially. ie. SW_SHOWNORMAL, SW_HIDE,
- // SW_MIMIMIZE.
- //
- // returns:
- // wParam from last message.
- //
- //*******************************************************************
- int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow)
- {
- MSG msg;
- BOOL brc;
-
- brc = InitMsgwnd(hInstance, hPrevInstance, lpszCmdLine, cmdShow);
- if (brc == FALSE)
- return(0);
-
- while (GetMessage(&msg, NULL, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
-
- return(msg.wParam);
- }
-
- //*******************************************************************
-
- //*******************************************************************
- // InitMsgwnd - init the Msgwnd application
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- // hPrevInstance - The instance of the previous instance
- // of this application. This will be 0
- // if this is the first instance.
- // lpszCmdLine - A long pointer to the command line that
- // started this application.
- // cmdShow - Indicates how the window is to be shown
- // initially. ie. SW_SHOWNORMAL, SW_HIDE,
- // SW_MIMIMIZE.
- //
- // returns:
- // TRUE if successful.
- // or
- // FALSE if failure.
- //
- //*******************************************************************
- # pragma argsused
- BOOL InitMsgwnd(HANDLE hInstance, HANDLE hPrevInstance,
- LPSTR lpszCmdLine, int cmdShow)
- {
- BOOL brc;
-
- if (! hPrevInstance)
- brc = InitMsgwndFirst(hInstance);
- else
- brc = InitMsgwndAdded(hPrevInstance);
-
- if (brc == TRUE)
- brc = InitMsgwndEvery(hInstance, cmdShow);
-
- return(brc);
- }
-
- //*******************************************************************
- // InitMsgwndFirst - done only for first instance of Msgwnd
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- //
- // returns:
- // TRUE if successful.
- // or
- // FALSE if failure.
- //
- //*******************************************************************
- BOOL InitMsgwndFirst(HANDLE hInstance)
- {
- WNDCLASS wcMsgwndClass;
-
- LoadString(hInstance, IDS_NAME, (LPSTR) SetUpData.szAppName, 10);
-
- // fill in window class information
-
- wcMsgwndClass.lpszClassName = SetUpData.szAppName;
- wcMsgwndClass.hInstance = hInstance;
- wcMsgwndClass.lpfnWndProc = MsgwndWndProc;
- wcMsgwndClass.hCursor = LoadCursor(NULL, IDC_ARROW);
- wcMsgwndClass.hIcon = LoadIcon(hInstance, SetUpData.szAppName);
- wcMsgwndClass.lpszMenuName = (LPSTR) SetUpData.szAppName;
- wcMsgwndClass.hbrBackground = GetStockObject(WHITE_BRUSH);
- wcMsgwndClass.style = CS_HREDRAW | CS_VREDRAW;
- wcMsgwndClass.cbClsExtra = 0;
- wcMsgwndClass.cbWndExtra = 0;
-
- // register the class
-
- if (!RegisterClass(&wcMsgwndClass))
- return(FALSE);
-
- return(TRUE);
- }
-
- //*******************************************************************
- // InitMsgwndAdded - done only for added instances of Msgwnd
- //
- // paramaters:
- // hPrevInstance - The instance of the previous instance
- // of this application.
- //
- // returns:
- // FALSE to indicate multiple instances are not allowed.
- //
- //*******************************************************************
- BOOL InitMsgwndAdded(HANDLE hPrevInstance)
- {
- // get the results of the initialization of first instance
- GetInstanceData(hPrevInstance, (PSTR) &SetUpData, sizeof(SETUPDATA));
-
- return(FALSE); // We are not allowing multiple MsgWnd apps.
- }
-
- //*******************************************************************
- // InitMsgwndEvery - done for every instance of Msgwnd
- //
- // paramaters:
- // hInstance - The instance of this instance of this
- // application.
- // cmdShow - Indicates how the window is to be shown
- // initially. ie. SW_SHOWNORMAL, SW_HIDE,
- // SW_MIMIMIZE.
- //
- // returns:
- // TRUE if successful.
- //
- //*******************************************************************
- BOOL InitMsgwndEvery(HANDLE hInstance, int cmdShow)
- {
- TEXTMETRIC tm;
- HDC hDC;
- char *cp;
- char szWinLocStr[40];
- int x, y, w, h;
-
- hInst = hInstance; // save for use by window procs
-
- // Get last location and size of Msgwnd from WIN.INI file.
- GetProfileString("Msgwnd",
- "Window",
- "0,160,500,150",
- szWinLocStr,
- sizeof(szWinLocStr));
-
- // Decode location and size of window from profile string.
- cp = szWinLocStr;
- x = (int) strtol(cp, &cp, 10);
- cp++;
- y = (int) strtol(cp, &cp, 10);
- cp++;
- w = (int) strtol(cp, &cp, 10);
- cp++;
- h = (int) strtol(cp, &cp, 10);
-
- // Create our window.
- hWndMain = CreateWindow(
- SetUpData.szAppName, // window class name
- SetUpData.szAppName, // window title
- WS_OVERLAPPEDWINDOW | // type of window
- WS_HSCROLL |
- WS_VSCROLL,
- x, // x window location
- y, // y
- w, // cx and size
- h, // cy
- NULL, // no parent for this window
- NULL, // use the class menu
- hInstance, // who created this window
- NULL // no parms to pass on
- );
-
- // Get window display context.
- hDC = GetDC(hWndMain);
-
- // Build fixed screen font.
- cursfont.lfHeight = 6;
- cursfont.lfWidth = 6;
- cursfont.lfEscapement = 0;
- cursfont.lfOrientation = 0;
- cursfont.lfWeight = FW_NORMAL;
- cursfont.lfItalic = FALSE;
- cursfont.lfUnderline = FALSE;
- cursfont.lfStrikeOut = FALSE;
- cursfont.lfCharSet = ANSI_CHARSET;
- cursfont.lfOutPrecision = OUT_DEFAULT_PRECIS;
- cursfont.lfClipPrecision = CLIP_DEFAULT_PRECIS;
- cursfont.lfQuality = DEFAULT_QUALITY;
- cursfont.lfPitchAndFamily = FIXED_PITCH | FF_DONTCARE;
- strcpy(cursfont.lfFaceName, "System");
-
- hnewsfont = CreateFontIndirect((LPLOGFONT) &cursfont);
-
- // Install fixed font in display context so text metrics will reflect
- // that font.
- holdsfont = SelectObject(hDC, hnewsfont);
-
- // Get text metrics to be used when painting the window.
- GetTextMetrics(hDC, &tm);
- xChar = tm.tmAveCharWidth;
- yChar = tm.tmHeight + tm.tmExternalLeading;
- yCharnl = tm.tmHeight;
-
- // Init a blank line.
- blanklen = 255;
- memset(blanks, ' ', blanklen);
-
- // Release the display context.
- ReleaseDC(hWndMain, hDC);
-
- ShowWindow(hWndMain, cmdShow);
- UpdateWindow(hWndMain);
-
- return(TRUE);
- }
-
- //*******************************************************************
- // CloseMsgwnd - done at termination of every instance of Msgwnd
- //
- // paramaters:
- // hWnd - The callers window handle.
- //
- //*******************************************************************
- void CloseMsgwnd(HWND hWnd)
- {
- RECT wrect;
- char szWinLocStr[40];
- int w, h;
-
- // Clear out kept strings.
- ClearKeep();
-
- // Get location and size of our window on the screen so we can
- // come back up in the same spot next time we are invoked.
-
- GetWindowRect(hWnd, (LPRECT) &wrect);
- w = wrect.right - wrect.left;
- h = wrect.bottom - wrect.top;
-
- // Make a string with our window location and size.
- sprintf(szWinLocStr, "%d,%d,%d,%d", wrect.left, wrect.top, w, h);
-
- // Save in WIN.INI file.
- WriteProfileString("Msgwnd",
- "Window",
- szWinLocStr);
- }
-
- //*******************************************************************
- // About - handle about dialog messages
- //
- // paramaters:
- // hDlg - The window handle for this dialog box
- // message - The message number
- // wParam - The WORD parmater for this message
- // lParam - The LONG parmater for this message
- //
- // returns:
- // Depends on message.
- //
- //*******************************************************************
- # pragma argsused
- BOOL FAR PASCAL About(HWND hDlg, WORD message, WORD wParam, LONG lParam)
- {
- if (message == WM_INITDIALOG)
- return(TRUE);
-
- else if (message == WM_COMMAND)
- {
- switch (wParam)
- {
- case IDOK:
- EndDialog(hDlg, TRUE);
- return(TRUE);
-
- default:
- return(TRUE);
- }
- }
-
- return(FALSE);
- }
-
- //*******************************************************************
-
- //*******************************************************************
- // MsgwndWndProc - every message for this instance will come here
- //
- // Handle the messages for this application.
- //
- // paramaters:
- // hWnd - The window handle for this message
- // message - The message number
- // wParam - The WORD parmater for this message
- // lParam - The LONG parmater for this message
- //
- // returns:
- // Depends on message.
- //
- //*******************************************************************
- long FAR PASCAL MsgwndWndProc(HWND hWnd, WORD message,
- WORD wParam, LONG lParam)
- {
- FARPROC lpproc;
- int i;
- HWND hClientWnd;
-
- switch (message)
- {
- case WM_DDE_INITIATE:
- // If this message is recieved, it is being sent by another
- // applicaton that is looking for a server on a particular
- // application/topic combination.
-
- // Get the handle of this potential client.
- hClientWnd = (HWND) wParam;
-
- // Go see if we support the application and topic he wants.
- DDEServerInit(hWnd, hClientWnd, lParam, "msgwnd", "screen");
- break;
-
- case WM_COMMAND:
- switch (wParam)
- {
- case IDM_QUIT:
- // User selected Quit on menu
- PostMessage(hWnd, WM_CLOSE, 0, 0L);
- break;
-
- case IDM_HOME:
- // Used to implement home to topleft from keyboard.
- SendMessage(hWnd, WM_HSCROLL, SB_TOP, 0L); /* not set up */
- SendMessage(hWnd, WM_VSCROLL, SB_TOP, 0L);
- break;
-
- case IDM_ABOUT:
- // Display about box.
- lpproc = MakeProcInstance(About, hInst);
- DialogBox(hInst,
- MAKEINTRESOURCE(ABOUT),
- hWnd,
- lpproc);
- FreeProcInstance(lpproc);
- break;
-
- default:
- break;
- }
- break;
-
- case WM_SIZE:
- // Save size of window client area.
- yClient = HIWORD(lParam);
- xClient = LOWORD(lParam);
-
- // Go setup scroll ranges and file display area based upon
- // client area size.
- SetupScroll(hWnd);
- break;
-
- case WM_VSCROLL:
- // React to the various vertical scroll related actions.
- switch (wParam)
- {
- case SB_TOP:
- nVscrollInc = -nVscrollPos;
- break;
-
- case SB_BOTTOM:
- nVscrollInc = nVscrollMax - nVscrollPos;
- break;
-
- case SB_LINEUP:
- nVscrollInc = -1;
- break;
-
- case SB_LINEDOWN:
- nVscrollInc = 1;
- break;
-
- case SB_PAGEUP:
- nVscrollInc = -max(1, yClient / yChar);
- break;
-
- case SB_PAGEDOWN:
- nVscrollInc = max(1, yClient / yChar);
- break;
-
- case SB_THUMBPOSITION:
- nVscrollInc = LOWORD(lParam) - nVscrollPos;
- break;
-
- case SB_THUMBTRACK:
- nVscrollInc = LOWORD(lParam) - nVscrollPos;
- break;
-
- default:
- nVscrollInc = 0;
- }
-
- nVscrollInc = max(-nVscrollPos,
- min(nVscrollInc, nVscrollMax - nVscrollPos));
- if (nVscrollInc)
- {
- nVscrollPos += nVscrollInc;
- ScrollWindow(hWnd, 0, -yChar * nVscrollInc, NULL, NULL);
- SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
- UpdateWindow(hWnd);
- }
- break;
-
- case WM_HSCROLL:
- // React to the various horizontal scroll related actions.
- switch (wParam)
- {
- case SB_LINEUP:
- nHscrollInc = -1;
- break;
-
- case SB_LINEDOWN:
- nHscrollInc = 1;
- break;
-
- case SB_PAGEUP:
- nHscrollInc = -8;
- break;
-
- case SB_PAGEDOWN:
- nHscrollInc = 8;
- break;
-
- case SB_THUMBPOSITION:
- nHscrollInc = LOWORD(lParam) - nHscrollPos;
- break;
-
- case SB_THUMBTRACK:
- nHscrollInc = LOWORD(lParam) - nHscrollPos;
- break;
-
- default:
- nHscrollInc = 0;
- }
-
- nHscrollInc = max(-nHscrollPos,
- min(nHscrollInc, nHscrollMax - nHscrollPos));
- if (nHscrollInc)
- {
- nHscrollPos += nHscrollInc;
- ScrollWindow(hWnd, -xChar * nHscrollInc, 0, NULL, NULL);
- SetScrollPos(hWnd, SB_HORZ, nHscrollPos, TRUE);
- UpdateWindow(hWnd);
- }
- break;
-
- case WM_KEYDOWN:
- // Translate various keydown messages to appropriate horizontal
- // and vertical scroll actions.
- for (i = 0; i < NUMKEYS; i++)
- {
- if (wParam == key2scroll[i].wVirtkey)
- {
- SendMessage(hWnd, key2scroll[i].iMessage,
- key2scroll[i].wRequest, 0L);
- break;
- }
- }
- break;
-
- case WM_PAINT:
- // Go paint the client area of the window with the appropriate
- // part of the selected file.
- MsgwndPaint(hWnd);
- break;
-
- case WM_DESTROY:
- // This is the end if we were closed by a DestroyWindow call.
- CloseMsgwnd(hWnd); // take any necessary wrapup action.
- PostQuitMessage(0); // this is the end...
- break;
-
- case WM_QUERYENDSESSION:
- // If we return TRUE we are saying it's ok with us to end the
- // windows session.
- CloseMsgwnd(hWnd); // take any necessary wrapup action.
- return((long) TRUE); // we agree to end session.
-
- case WM_CLOSE:
- // Tell windows to destroy our window.
- DestroyWindow(hWnd);
- break;
-
- default:
- // Let windows handle all messages we choose to ignore.
- return(DefWindowProc(hWnd, message, wParam, lParam));
- }
-
- return(0L);
- }
-
- //*******************************************************************
- // SetupScroll - setup scroll ranges
- //
- // Setup the vertical and horizontal scroll ranges and positions
- // of the applicatons main window based on:
- //
- // numlines - The maximum number of lines to display.
- // maxwidth - The maximum width of any line to display.
- //
- // The resulting variables, nVscrollPos and nPageMaxLines, are used
- // by the function MsgwndPaint to determine what part of the selected
- // file to display in the window.
- //
- // paramaters:
- // hWnd - The callers window handle.
- //
- //*******************************************************************
- void SetupScroll(HWND hWnd)
- {
- // numlines established during open
- nVscrollMax = max(0, numlines - yClient / yChar);
- nVscrollPos = min(nVscrollPos, nVscrollMax);
-
- nHscrollMax = max(0, maxwidth - xClient / xChar);
- nHscrollPos = min(nHscrollPos, nHscrollMax);
-
- SetScrollRange (hWnd, SB_VERT, 0, nVscrollMax, FALSE);
- SetScrollPos (hWnd, SB_VERT, nVscrollPos, TRUE);
-
- SetScrollRange (hWnd, SB_HORZ, 0, nHscrollMax, FALSE);
- SetScrollPos (hWnd, SB_HORZ, nHscrollPos, TRUE);
-
- nPageMaxLines = min(numlines, yClient / yChar);
-
- rect.left = 0;
- rect.top = 0;
- rect.right = xClient;
- rect.bottom = yClient;
-
- blanklen = rect.right / xChar + 1;
- }
-
- //*******************************************************************
- // MsgwndPaint - paint the main window
- //
- // This function is responsible for redisplaying a portion of the saved
- // strings. Which strings it displays depends on the current scroll
- // position.
- //
- // paramaters:
- // hWnd - The callers window handle
- //
- //*******************************************************************
- void MsgwndPaint(HWND hWnd)
- {
- PAINTSTRUCT ps;
- HDC hDC;
- char currec[256];
- int ypos;
- LPSTR lcp;
- int i;
- int ndone;
-
- // Get display context.
- BeginPaint(hWnd, (LPPAINTSTRUCT) &ps);
- hDC = ps.hdc;
-
- // Select fixed font.
- SelectObject(hDC, hnewsfont);
-
- // Setup scroll ranges.
- SetupScroll(hWnd);
-
- // See if we have any lines to show.
- if (hwm_keep)
- {
- // Y position of bottom line in client area.
- ypos = rect.bottom - yChar;
-
- // Index into keep list of first line (from bottom) to show.
- i = nVscrollMax - nVscrollPos;
-
- ndone = 1;
- while (ndone)
- {
- lcp = GlobalLock(hkeep[i]);
- if (lcp)
- {
- // We must fill line with blanks to width of window
- // or else some previous longet text might show through.
- _fstrcpy(currec, blanks);
-
- // Line to show.
- _fstrncpy(currec, lcp, _fstrlen(lcp));
-
- // Send to window.
- TextOut(hDC,
- xChar * (-nHscrollPos + 0),
- ypos,
- currec,
- blanklen);
-
- // New Y is one character height higher.
- ypos -= yChar;
-
- GlobalUnlock(hkeep[i]);
- }
-
- // Index of next keep string to show.
- i++;
-
- // No use drawing lines beyond top of client area.
- // They would not show, so don't wast the energy.
- if (ypos < -yChar)
- ndone = 0;
-
- // Have we done all of the lines?
- if (i > (hwm_keep - 1))
- ndone = 0;
- }
- }
-
- // Release the display context.
- ReleaseDC(hWnd, hDC);
-
- EndPaint(hWnd, (LPPAINTSTRUCT) &ps);
- }
-
- //*******************************************************************
- // ScrollPrint - saves string sent to it and cause it to display
- //
- // This function gets a string and saves it in a list of strings.
- // The oldest string is deleted when the list reaches its maximum
- // size.
- //
- // Depending on the scroll position at the time the string is recieved
- // one of two methods of displaying the string will be used:
- //
- // If the scroll position was at the bottom, the window is scrolled up
- // one line, the bottom line is made invalid, and windows is told to
- // repaint. This will cause only the new string to be output, resulting
- // in minimum redraw on the screen.
- //
- // If the scroll position was not at the bottom of the window because
- // the user had been looking at previous messages, windows will be told
- // to redraw the entire window starting with the new string.
- //
- // paramaters:
- // hWnd - The window to put the message in.
- // str - the string to print in window.
- //
- //*******************************************************************
- void ScrollPrint(HWND hWnd, char *str)
- {
- HDC hDC;
- char currec[256];
- int i;
- int lstr;
- LPSTR lcp;
- RECT trect;
-
- // If our keep stack is full free oldest member.
- if (hwm_keep >= MAX_KEEP)
- GlobalFree(hkeep[hwm_keep]);
-
- // Move all handles to make room for new one.
- for (i = hwm_keep; i > 0; i--)
- hkeep[i] = hkeep[i - 1];
-
- // If keep stack not yet full add one to high watter mark.
- if (hwm_keep < MAX_KEEP)
- hwm_keep++;
-
- // Make sure we know how many saved lines there are.
- numlines = hwm_keep;
-
- // Length of new string.
- lstr = strlen(str);
-
- // Is it longer than any previous string.
- if (lstr > maxwidth)
- maxwidth = lstr;
-
- // Get storage to save it.
- hkeep[0] = GlobalAlloc(GMEM_MOVEABLE, (DWORD) (lstr + 1));
- if (hkeep[0])
- {
- // Lock it down to get address.
- lcp = GlobalLock(hkeep[0]);
- if (lcp)
- {
- // Save string.
- _fstrcpy(lcp, str);
- GlobalUnlock(hkeep[0]);
- }
- }
-
- // See what we have to do to display it efficently.
- if (!(nVscrollMax - nVscrollPos))
- {
- // We are scrolled to bottom of list.
-
- // Scroll contents of window up one character hehght.
- ScrollWindow(hWnd, 0, -yChar, &rect, &rect);
-
- // Set scroll position to last line
- nVscrollPos = numlines - yChar / yClient;
-
- // Tell windows to repaint only the bottom line of window.
- GetClientRect(hWnd, &trect);
- trect.top = trect.bottom - yChar;
- InvalidateRect(hWnd, &trect, TRUE);
- }
- else
- {
- // We are not scrolled to bottom of list.
-
- // Set scroll position to last line.
- nVscrollPos = numlines - yChar / yClient;
-
- // Tell windows to repaint the entire window.
- InvalidateRect(hWnd, NULL, TRUE);
- }
- }
-
- //*******************************************************************
- // ClearKeep - free all saved strings
- //*******************************************************************
- void ClearKeep()
- {
- int i;
-
- for (i = 0; i < hwm_keep; i++)
- {
- GlobalFree(hkeep[i]);
- hkeep[i] = 0;
- }
-
- // Reset counters.
- numlines = hwm_keep = 0;
- }
-
- //*******************************************************************
-
- //*******************************************************************
- // DDEExecuteCommand - execute a command send by client
- //
- // paramaters:
- // lpCommand - command from client to be executed.
- //
- // commands supported:
- //
- // print - print a line in window.
- // [print ("line to print")]
- //
- // clear - clear the window.
- // [clear]
- //
- // returns:
- // 1 - if command successful.
- // 0 - if not successful.
- //
- //*******************************************************************
- int DDEExecuteCommand(LPSTR lpCommand)
- {
- int nRc;
- LPSTR lcp;
- LPSTR lcp1;
- LPSTR lcp2;
- char buf[256];
-
- // Init return code.
- nRc = 0;
-
- // Find start of command.
- lcp = _fstrchr(lpCommand, '[');
- if (lcp)
- {
- // See what the command is.
- lcp++;
-
- if (!_fstrncmp(lcp, "print", 5)) // Print a line to window.
- {
- // Find string between quotes (does not support embeded quotes)
- lcp1 = _fstrchr(lcp, '\"');
- if (lcp1)
- {
- lcp1++;
- lcp2 = _fstrchr(lcp1, '\"');
- if (lcp2)
- {
- *lcp2 = 0;
- _fstrcpy(buf, lcp1);
-
- // Print the string to window.
- ScrollPrint(hWndMain, buf);
-
- // Increment line count.
- plines++;
-
- nRc = 1;
- }
- }
- }
-
- else if (!_fstrncmp(lcp, "clear", 5)) // Clear window.
- {
- // Delete saved strings.
- ClearKeep();
-
- // Clear the window.
- InvalidateRect(hWndMain, NULL, TRUE);
- UpdateWindow(hWndMain);
-
- // Reset line count.
- plines = 0;
-
- nRc = 1;
- }
- }
-
- return(nRc);
- }
-
- //*******************************************************************
- // DDEData - get data requested by client
- //
- // paramaters:
- // szItem - name of data item requested.
- //
- // items supported:
- //
- // lines - the number lines printed to window.
- //
- // returns:
- // Size of data item.
- // or
- // Zero if no data item.
- //
- //*******************************************************************
- int DDEData(char *szItem, HANDLE *hData)
- {
- int nRc;
- int len;
- char buf[30];
- LPSTR lpData;
-
- // Init return code.
- nRc = 0;
-
- // See what data item is being requested.
- if (!stricmp(szItem, "lines"))
- {
- // Format response.
- sprintf(buf, "Lines = %d", plines);
-
- // Get length of response.
- len = strlen(buf);
-
- // Get memory for response.
- *hData = GlobalAlloc(GMEM_MOVEABLE, (DWORD) (len + 1));
- if (*hData)
- {
- lpData = GlobalLock(*hData);
- if (lpData)
- {
- // Copy response to memory.
- _fstrcpy(lpData, buf);
- GlobalUnlock(*hData);
-
- // Set return code to length of data returned.
- nRc = len;
- }
- else
- {
- GlobalFree(*hData);
- *hData = 0;
- }
- }
- }
-
- return(nRc);
- }
-
- //*******************************************************************
-