Subject: Example of adding features to a GNU-style GUI console library
From: [email-masked]

28 Jun 1998 15:00:15 -0700
Message-ID: <[email-masked]>
Mime-Version: 1.0
Content-Type: text/plain; charset=windows-1252
Content-Transfer-Encoding: 8bit
To: [email-masked]
Cc: [email-masked]

The following is a crude test program that is being used to debug `select',
`copy', and `paste' in the wstdio console-window library.

It demonstrates one major advantage of having a GUI console window,
namely, that you can debug new library features without altering the
library.

Note that defining __WSTDIO__ changes the behavior of the <stdio.h>
file on my system to include <wstdio.h> in place of the mingw32 or
cygwin32 version.

The library is written in Macro-Pascal, so part of the code below may
look a little strange to C programmer.
=========================================================================
clipboard.c
===========

#define __WSTDIO__
#include <stdio.h>
#include "e:\src\wstdio\console.h"

#define ORD(x)          ((unsigned)(x))
#define LONGORD(x)      ((unsigned long)(x))
#define CHR(x)          ((unsigned char)(x))
#define ODD(x)          ((x)&0x1)
#define ABS(x)          ((x)<0?-(x):(x))
#define IN_RANGE(x,y,z) (((x)>=(y))&&((x)<=(z)))
#define IN_SET(x,y)     (_fstrchr(y,CHR(x)) != NULL)
#define READLN(f)       while(fwgetc(f)!='\n')
#define WRITELN(f)      fwputc('\n',f)
#define BEGIN           {
#define END             ;}
#define REPEAT          for(;;){
#define UNTIL(x)        ;if(x)break;}
#define FOREVER         ;}
#define IF              if (
#define THEN            )
#define ELSE            else
#define WHILE           while (
#define DO              )
#define FOR             for (
#define AS              ; (
#define TO              ; !(
#define DOWNTO          ; !(
#define BY              );
#define CASE            switch(
#define OF              ){

LRESULT CALLBACK _export SubclassProc (HWND, UINT, WPARAM, LPARAM);
void CopyText(void);
void PasteText(void);
void SelectText(void);
void SetUpButtons(void);
extern void _message_error(LPSTR,LPSTR);
extern HWND hWndCurrent;

MSG MsgBuffer;

int MAIN_ (int argc, char **argv)
{
  SetUpButtons();

  while (GetMessage((LPMSG)&MsgBuffer,(HWND)0,0,0))
   {
	TranslateMessage((LPMSG)&MsgBuffer);
	DispatchMessage((LPMSG)&MsgBuffer);
   };
 return 0;
}

#define IDB_SELECT	1
#define IDB_COPY		2
#define IDB_PASTE		3
#define IDB_PAUSE		4
#define IDB_EXIT		5
#define IDB_ES_SELECT	10

typedef struct {
	char *title; int index; HWND hwnd;} Button;

Button Buttons[6] = {
	{"", 0, (HWND)0},
	{"&Select Text", IDB_SELECT, (HWND)0},
	{"&Copy", IDB_COPY, (HWND)0},
	{"&Paste", IDB_PASTE, (HWND)0},
	{"P&ause", IDB_PAUSE, (HWND)0},
	{"E&xit", IDB_EXIT, (HWND)0}};

LRESULT CALLBACK _export
 SubclassProc (HWND h, UINT msg, WPARAM w, LPARAM l)
{
 extern LRESULT CALLBACK _export StdioWndProc (HWND, UINT, WPARAM, LPARAM);

  if ((msg == WM_COMMAND) /* && ((HWND)l != h) && (HIWORD(w) == BN_CLICKED) */)
	 switch (LOWORD(w))
	  {
		case IDB_SELECT: _message_error("IDB_SELECT", NULL);
				SelectText();
				return 0L;
		case IDB_COPY: _message_error("IDB_COPY", NULL);
				CopyText();
				return 0L;
		case IDB_PASTE: _message_error("IDB_PASTE", NULL);
				PasteText();
				return 0L;
		case IDB_PAUSE: _message_error("IDB_PAUSE", NULL);
				return 0L;
		case IDB_EXIT: _message_error("IDB_EXIT", NULL);
				PostQuitMessage(0);
				return 0L;
		default: return DefWindowProc(h, msg, w, l);
	  }
 else
	/* Method for calling subclassed window proc: */
	return CallWindowProc((WNDPROC)StdioWndProc, h, msg, w, l);
}

void SetUpButtons ()
{
 extern HINSTANCE hStdioInst;
 extern LPSTR lpClassName;
 extern int nStdioFrameHeight, nStdioFrameWidth;
 STARTUPINFO lStart = {0};
 HMENU hMenuBar;
 TEXTMETRIC tm;
 HDC hdc;
 int cx, cy, nPos, nIndex;

  /* Subclass the main window to handle button clicks or menu: */
  if (0L ==
   SetWindowLong(hWndCurrent, GWL_WNDPROC, (LONG)SubclassProc))
   {
	_message_error("Unable to subclass", NULL);
	perror("Unable to subclass");
	exit(0);
   };
#if 0
  hdc = GetDC(hWndCurrent);
  SelectObject(hdc, GetStockObject (SYSTEM_FIXED_FONT));
  GetTextMetrics(hdc, &tm);
  cx = tm.tmAveCharWidth;
  cy = ((tm.tmHeight + tm.tmExternalLeading) * 3) / 2;
  ReleaseDC (hWndCurrent, hdc);
  lStart.cb = sizeof(STARTUPINFO);
  GetStartupInfo(&lStart);

  for (nIndex = 1, nPos = (LINEWIDTH-8); nIndex < 6; nIndex++)
   nPos -= (1 + lstrlen(Buttons[nIndex].title));

  for (nIndex = 1, nPos *= cx; nIndex < 6; nIndex++)
   {
    Buttons[nIndex].hwnd = CreateWindow("button",
     Buttons[nIndex].title,
     BS_PUSHBUTTON | WS_CHILD | WS_VISIBLE,
     nPos += cx * (1+lstrlen(Buttons[nIndex-1].title)),
     0,
     cx * (1+lstrlen(Buttons[nIndex].title)), cy,
     hWndCurrent,
     (HMENU)Buttons[nIndex].index,
     hStdioInst, &lStart);
   };
#else

  hMenuBar = CreateMenu();
  for (nIndex = 1, nPos *= cx; nIndex < 6; nIndex++)
   AppendMenu(hMenuBar, MF_STRING,
		Buttons[nIndex].index, Buttons[nIndex].title);
  SetMenu(hWndCurrent, hMenuBar);
  DrawMenuBar(hWndCurrent);
#endif

MoveWindow(hWndCurrent, 0, 0, 
	nStdioFrameWidth,
	nStdioFrameHeight += GetSystemMetrics(SM_CYMENU),
	TRUE);
}

static BOOL IsEndOfLine (LPSTR sBuf, int cx)
BEGIN
 IF cx > (LINEWIDTH - 3) THEN
  return FALSE;
 ELSE
  WHILE cx < LINEWIDTH DO
   IF sBuf[cx++] != ' ' THEN
    return FALSE;
 return TRUE
END

static  HWND hWndSelect;
static char pBuf[MAXLINES * LINEWIDTH + 1];

void SelectText ()
BEGIN
typedef struct {HWND    hwindow;
        unsigned char scrBuff[MAXLINES][MLINEWIDTH];
        unsigned char color[MAXLINES][MLINEWIDTH];
	  unsigned char nlength[MAXLINES], nLine, nPos, nMode;
	  POINT origin, extra, max_size;
	  LPSTR title;}   PAGELIST;
 extern HINSTANCE hStdioInst;
 extern HFONT hStdioFont;
 extern PAGELIST FAR *sPage;
 extern int nPage;
 HDC hdc;
 STARTUPINFO lStart = {0};
 RECT rc = {0};
 POINT point = {0};
 int cx, cy, nIndex, nOffset;
 LPSTR pBuffer;

  /* Overlay console window with edit-class window using stdio font: */

  lStart.cb = sizeof(STARTUPINFO);
  GetStartupInfo(&lStart);
  GetClientRect(hWndCurrent, &rc);

  hWndSelect = CreateWindow("edit",
     NULL,
     WS_CHILD | WS_VISIBLE | WS_BORDER | ES_READONLY |
	ES_LEFT | ES_MULTILINE | ES_NOHIDESEL,
     rc.left, rc.top, rc.right, rc.bottom,
     hWndCurrent,
     (HMENU)IDB_ES_SELECT, hStdioInst, &lStart);

  SendMessage(hWndSelect, WM_SETFONT,
	(WPARAM)hStdioFont, MAKELPARAM(TRUE, 0));

  FOR cy = 0, nOffset = 0 AS cy < MAXLINES BY cy++ DO
   BEGIN
    pBuffer = sPage[nPage].scrBuff[cy];
    FOR cx = 0 AS cx < LINEWIDTH BY nOffset++, cx++ DO
     IF IsEndOfLine(pBuffer, cx) THEN
      BEGIN
	 pBuf[nOffset++] = '\r';
	 pBuf[nOffset++] = '\n';
	 break
      END
     ELSE
      pBuf[nOffset] = pBuffer[cx];
   END;
  pBuf[nOffset] = '\0';

  SendMessage(hWndSelect, WM_SETTEXT, 0, (WPARAM)pBuf);
  EnableWindow(hWndSelect, TRUE);
  ShowCaret(hWndSelect)
END

void CopyText ()
BEGIN
  SendMessage(hWndSelect, WM_COPY, 0, 0L);
  DestroyWindow(hWndSelect)
END

void PasteText ()
BEGIN
 HANDLE hClip;
 LPSTR szClipBuf = NULL, szClipText;
 int nIndex;
 UINT wFormat = 0;

  IF !OpenClipboard(hWndCurrent) THEN
   BEGIN
     printf("Unable to open the clipboard.\n");
     exit(-2);
   END;

  wFormat = (IsClipboardFormatAvailable(CF_TEXT) ?
	CF_TEXT :
	(IsClipboardFormatAvailable(CF_OEMTEXT) ?
	CF_OEMTEXT : 0));

  printf("Clipboard Format: %s\n",
	wFormat == CF_TEXT ? "CF_TEXT" :
	(wFormat == CF_OEMTEXT ? "CF_OEMTEXT" : "N/A"));

  IF !(hClip = GetClipboardData(wFormat)) THEN
   BEGIN
    printf("Unable to get text from clipboard.\n");
    exit(-3);
   END;

  szClipText = GlobalLock(hClip);
  printf("hCLip: %d\n", hClip);

  lstrcpy((szClipBuf = calloc(1,lstrlen(szClipText)+1)),
	szClipText);

  printf("szClipBuf: %Lp\n", szClipBuf);

  GlobalUnlock(hClip);

#if 0
  Delay(500);
  fprintf(stdout, szClipBuf);
#elif 1
  FOR nIndex = 0 AS szClipBuf[nIndex] != '\0' BY nIndex++ DO
   BEGIN
    if (szClipBuf[nIndex] == '\n') Delay(500);
    putch(szClipBuf[nIndex]);
   END;
#elif 0
  FOR nIndex = 0 AS szClipBuf[nIndex] != '\0' BY nIndex++ DO
   BEGIN
    SendMessage(hWndCurrent, WM_CHAR,
		(WPARAM)(szClipBuf[nIndex]), (LPARAM)0L);
    Delay(10);
    putch(getch());
   END;  
#endif

  CloseClipboard();
  DestroyWindow(hWndSelect)
END
¡Ý 
-
For help on using this list (especially unsubscribing), send a message to
"[email-masked]" with one line of text: "help".