From: vtailor AT gte DOT net Subject: Example of adding features to a GNU-style GUI console library 28 Jun 1998 15:00:15 -0700 Message-ID: <199806281557.KAA10102.cygnus.gnu-win32@smtp2.mailsrvcs.net> Mime-Version: 1.0 Content-Type: text/plain; charset=windows-1252 Content-Transfer-Encoding: 8bit To: gnu-win32 AT cygnus DOT com Cc: vtailor AT gte DOT net 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 file on my system to include 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 #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 "gnu-win32-request AT cygnus DOT com" with one line of text: "help".