home *** CD-ROM | disk | FTP | other *** search
- /* Status.c -- the status module of WizUnzip
- * Robert Heath. 1991.
- */
-
- #include <sys\types.h>
- #include <sys\stat.h>
- #include <time.h>
- #include <windows.h>
- #include <string.h>
- #include <ctype.h>
- #include <io.h>
- #include <stdio.h>
- #include <stdarg.h>
- #include <assert.h>
- #include "wizunzip.h"
- #include "unzip.h"
-
- #define STATUS_INCREMENT 512 /* incremental status data size */
- #define MAX_H_CHARS 160 /* max horizontal chars. */
-
- #define MAX_INDEX_ENTRIES 16 /* Message Window index max entries */
-
- #define MAX_BUFFER_SIZE 0xffffL /* max Message Buffer size. Must fit
- * within one memory segment! */
-
- #define MAX_TEXTOUT_COUNT 0x7fffL /* max no. bytes TextOut() accepts */
-
- #define STDIO_BUF_SIZE (FILNAMSIZ+LONG_FORM_FNAME_INX) /* buffer size during printf or fprintf */
-
- static short yClient; /* height of client area */
- static short yChar; /* height of typical char. */
- static short nVscrollPos = 0; /* scroll position of mesg. window */
- static short nNumLines = 0; /* number of lines in buffer */
- static short nVscrollMax; /* max scroll position of mesg. window */
- static DWORD dwStatusSize = 0L; /* status data size */
- static DWORD dwBufferSize = 0L; /* Status buffer size. Never
- exceeds MAX_BUFFER_SIZE */
- static HANDLE hGlobalStatus; /* global mesg. handle */
- static DWORD dwMsgWinIndex[MAX_INDEX_ENTRIES]; /* max index entries */
- static short nIndexEntries; /* no. active index entries, with
- MAX_INDEX_ENTRIES as its max.
- When set to 0, it's time to
- re-index.*/
-
- static short nLinesPerEntry; /* lines per index entry */
-
- /* displayed when buffer shouldn't grow or can't grow */
- static char CLEARING_MSG[] =
- "Clearing Messages window to make room for more information.";
-
-
- static struct KeyEntry {
- WORD wVirtKey;
- BOOL bCntl;
- int iMessage;
- WORD wRequest;
- } KeyTable[] = {
- /* vertical scroll control
- */
- {VK_HOME, TRUE, WM_VSCROLL, SB_TOP },
- {VK_END, TRUE, WM_VSCROLL, SB_BOTTOM },
- {VK_PRIOR, FALSE, WM_VSCROLL, SB_PAGEUP },
- {VK_NEXT, FALSE, WM_VSCROLL, SB_PAGEDOWN },
- {VK_UP, FALSE, WM_VSCROLL, SB_LINEUP },
- {VK_DOWN, FALSE, WM_VSCROLL, SB_LINEDOWN },
-
- /* horizontal scroll control
- */
- {VK_HOME, FALSE, WM_HSCROLL, SB_TOP },
- {VK_END, FALSE, WM_HSCROLL, SB_BOTTOM },
- {VK_PRIOR, TRUE, WM_HSCROLL, SB_PAGEUP },
- {VK_NEXT, TRUE, WM_HSCROLL, SB_PAGEDOWN },
- {VK_LEFT, FALSE, WM_HSCROLL, SB_LINEUP },
- {VK_RIGHT, FALSE, WM_HSCROLL, SB_LINEDOWN },
- } ;
-
- #define NUMKEYS (sizeof(KeyTable)/sizeof(struct KeyEntry))
-
- /* Forward Refs
- */
- static void FreeStatusLog(void);
-
- /* Globals
- */
- BOOL bRealTimeMsgUpdate = TRUE; /* update messages window in real-time.
- * Reset by callers when update can be
- * be deferred.
- */
-
- /* Clears status buffer. Frees buffer.
- */
- static void FreeStatusLog(void)
- {
- if (hGlobalStatus)
- {
- GlobalFree(hGlobalStatus);
- hGlobalStatus = NULL;
- }
- dwStatusSize = 0L; /* status data size */
- dwBufferSize = 0L; /* status buffer size */
- nNumLines = 0; /* number of lines in buffer */
- nVscrollMax = 1;
- SetScrollRange(hWndStatus, SB_VERT, 0, 1, FALSE);
- nVscrollPos = 0;
- SetScrollPos(hWndStatus, SB_VERT, nVscrollPos, TRUE);
- }
-
- /* Update Message Window Position is called after adding
- * a number of lines to the message window without updating it.
- * The function invalidates then updates the window.
- */
- void UpdateMsgWndPos(void)
- {
- nVscrollPos = max(0,(nNumLines-MessageWinLines+1)); /* set position to next to last line */
- SetScrollPos(hWndStatus, SB_VERT, nVscrollPos, TRUE);
- InvalidateRect(hWndStatus, NULL, TRUE);
- UpdateWindow(hWndStatus);
- }
-
- /* Add message line (or part of a line) to the global status buffer
- * that is the contents of the Message Window.
- * Assumes that global data is unlocked when called.
- */
- void WriteStringToMsgWin(PSTR String, BOOL bUpdate)
- {
- WriteBufferToMsgWin(String, strlen(String), bUpdate);
- }
-
- /* Add message buffer (maybe part of a line) to the global status buffer
- * that is the contents of the Message Window.
- * Assumes that global data is unlocked when called.
- */
- void WriteBufferToMsgWin(LPSTR buffer, int nBufferLen, BOOL bUpdate)
- {
- LPSTR lpC; /* pointer into buffer */
- HANDLE hGlobalStatusTmp;
- LPSTR lpGlobalBuffer; /* pointer into global buffer */
- DWORD dwNewSize = dwStatusSize + (DWORD)nBufferLen;
- int nIncrLines = 0; /* incremental lines in buffer */
- int nIncompleteExistingLine = 0; /* add -1 if incomplete existing last line */
- int nIncompleteAddedLine = 0; /* add +1 if incomplete added last line */
- DWORD dwRequestedSize; /* Size needed to hold all data. Can't
- practically exceeded MAX_BUFFER_SIZE.*/
-
- if (!nBufferLen) /* if no data */
- return; /* just beat it */
-
- /* count LF's in buffer to later add to total */
- for (lpC = buffer; lpC != NULL && (lpC - buffer) < nBufferLen; )
- {
- /* use memchr() for speed (?) considerations */
- if (lpC = _fmemchr(lpC, '\n', (size_t)(nBufferLen - (lpC - buffer))))
- {
- nIncrLines++; /* tally line found */
- lpC++; /* point beyond LF for next pass */
- }
- }
- if (dwNewSize > dwBufferSize) /* if won't fit or 1st time */
- {
- /* Round up if necessary to nearest whole increment
- */
- dwRequestedSize = ((dwNewSize + STATUS_INCREMENT - 1) /
- STATUS_INCREMENT) * STATUS_INCREMENT;
- if (hGlobalStatus) /* if buffer exists, realloc */
- {
- if (dwRequestedSize <= MAX_BUFFER_SIZE &&
- (hGlobalStatusTmp = GlobalReAlloc(hGlobalStatus,
- dwRequestedSize, GMEM_MOVEABLE)))
- {
- /* successful re-allocation */
- hGlobalStatus = hGlobalStatusTmp;
- dwBufferSize = dwRequestedSize;
- }
- else /* re-allocation failed, make last-ditch attempt! */
- {
- FreeStatusLog(); /* free own buffers */
- MessageBox (hMainWnd, CLEARING_MSG,
- "Note", MB_ICONINFORMATION | MB_OK);
- WriteBufferToMsgWin(buffer, nBufferLen, bUpdate);
- return;
- }
- }
- else /* 1st time */
- {
- if (hGlobalStatus = GlobalAlloc(GMEM_MOVEABLE,
- dwRequestedSize))
- {
- dwBufferSize = dwRequestedSize; /* save it */
- }
- else /* 1st allocation failed! */
- {
- WinAssert(hGlobalStatus); /* DEBUG */
- return;
- }
- }
- }
- /* should be easy copy of data from here */
- lpGlobalBuffer = GlobalLock(hGlobalStatus);
- if (lpGlobalBuffer)
- {
-
- /* Account for partial lines existing and being added.
- */
- if (dwStatusSize &&
- lpGlobalBuffer[dwStatusSize-1] != '\n')
- nIncompleteExistingLine-- ; /* subtract 1 */
-
- if (buffer[nBufferLen-1] != '\n') /* nBufferLen guaranteed >0 */
- nIncompleteAddedLine++ ; /* add 1 */
-
- /* copy data into global buffer */
- if (nBufferLen) /* map to ANSI; if 0 don't copy; 0 means 65K */
- {
- OemToAnsiBuff(buffer, &lpGlobalBuffer[dwStatusSize], nBufferLen);
- }
- /* bump no. lines accounting for incomplete lines */
- nNumLines += (nIncrLines+nIncompleteExistingLine+nIncompleteAddedLine);
- dwStatusSize = dwNewSize; /* new data size counting end null */
- GlobalUnlock(hGlobalStatus);
- nVscrollMax = max(1, nNumLines + 2 - yClient/yChar);
- SetScrollRange(hWndStatus, SB_VERT, 0, nVscrollMax, FALSE);
- nIndexEntries = 0; /* re-index whenever more data is added */
- if (bUpdate) /* if requested to update message box */
- {
- nVscrollPos = max(0,(nNumLines-MessageWinLines+1)); /* set position to next to last line */
- SetScrollPos(hWndStatus, SB_VERT, nVscrollPos, TRUE);
- InvalidateRect(hWndStatus, NULL, TRUE);
- UpdateWindow(hWndStatus);
- }
- }
- else
- {
- WinAssert(lpGlobalBuffer); /* DEBUG */
- }
- }
-
-
-
- long FAR PASCAL StatusProc (HWND hWnd, unsigned iMessage, WORD wParam, LONG lParam)
- {
- static short xClient ; /* size of client area */
- HDC hDC; /* device context */
- TEXTMETRIC tm; /* text metric structure */
- PAINTSTRUCT ps;
- #ifdef OLD_WAY
- RECT rect;
- #endif
- struct KeyEntry *pKE; /* pointer to key entry */
- LPSTR lpStatusBuffer; /* pointer to global mesg. buffer */
- int nMenuItemCount; /* no. items in System menu before deleting separators */
- BOOL bCntl; /* control shift pressed ? */
- static short xChar;
- static short nHscrollMax;
- static short nHscrollPos;
- static short nMaxWidth; /* in pixels */
- short nVscrollInc;
- short nHscrollInc;
- short i, x, y, nPaintBeg, nPaintEnd;
- HMENU hSysMenu; /* this guy's system menu */
-
- switch (iMessage) {
- case WM_CREATE:
- #ifdef NEEDME
- wStatusItem = LOWORD((LONG)(((LPCREATESTRUCT)lParam)->lpCreateParams));
- #endif
- hDC = GetDC(hWnd); /* get device context */
- hOldFont = SelectObject ( hDC, hFixedFont);
- GetTextMetrics(hDC, &tm);
- ReleaseDC(hWnd, hDC);
- xChar = tm.tmAveCharWidth;
- yChar = tm.tmHeight + tm.tmExternalLeading;
- nMaxWidth = MAX_H_CHARS * xChar;
- nVscrollPos = 0; /* reset position to 0 */
- nVscrollMax = max(1,nNumLines);
- SetScrollRange(hWnd, SB_VERT, 0, nVscrollMax, FALSE);
- SetScrollPos(hWnd, SB_VERT, 0, TRUE);
- hSysMenu = GetSystemMenu(hWnd, FALSE);
- DeleteMenu(hSysMenu, SC_SIZE, MF_BYCOMMAND); /* delete menu item */
- DeleteMenu(hSysMenu, SC_MOVE, MF_BYCOMMAND); /* delete menu item */
- DeleteMenu(hSysMenu, SC_CLOSE, MF_BYCOMMAND); /* delete menu item */
- DeleteMenu(hSysMenu, SC_TASKLIST, MF_BYCOMMAND); /* delete menu item */
- /* walk thru menu and delete all separator bars
- */
- for (nMenuItemCount = GetMenuItemCount(hMenu);
- nMenuItemCount ; nMenuItemCount--)
- {
- if (GetMenuState(hSysMenu, nMenuItemCount-1, MF_BYPOSITION) & MF_SEPARATOR)
- {
- DeleteMenu(hSysMenu, nMenuItemCount-1, MF_BYPOSITION);
- }
- }
- return 0;
-
- case WM_SIZE:
- xClient = LOWORD(lParam);/* x size of client area */
- yClient = HIWORD(lParam);/* y size of client area */
-
- nVscrollMax = max(1, nNumLines + 2 - yClient/yChar);
- nVscrollPos = min(nVscrollPos, nVscrollMax);
-
- SetScrollRange(hWnd, SB_VERT, 0, nVscrollMax, FALSE);
- SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
-
- nHscrollMax = max(0, 2 + (nMaxWidth - xClient) / xChar);
- nHscrollPos = min(nHscrollPos, nHscrollMax);
-
- SetScrollRange(hWnd, SB_HORZ, 0, nHscrollMax, FALSE);
- SetScrollPos(hWnd, SB_HORZ, nHscrollPos, TRUE);
-
- return 0;
-
- case WM_SYSCOMMAND:
- switch ((wParam & 0xFFF0)) { /* decode parameter type */
- case SC_RESTORE: /* alert parent */
- PostMessage(hMainWnd, WM_COMMAND,
- IDM_RESTORE_STATUS, 0L);
- break;
- case SC_MAXIMIZE:
- PostMessage(hMainWnd, WM_COMMAND,
- IDM_MAX_STATUS, 0L);
- break;
- default:
- return (DefWindowProc(hWnd, iMessage, wParam, lParam));
- }
- break;
- case WM_COMMAND:
- switch (wParam) { /* decode parameter type */
- case IDM_CLEAR_STATUS:
- FreeStatusLog(); /* free log contents */
- InvalidateRect(hWndStatus, NULL, TRUE);
- break;
- default:
- break;
- }
- break;
- case WM_VSCROLL: /* scroll bar action on list box */
- switch (wParam) { /* decode parameter type */
- 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 = min(-1, -yClient/yChar);
- break;
- case SB_PAGEDOWN:
- nVscrollInc = max(1, yClient/yChar);
- break;
- case SB_THUMBPOSITION:
- nVscrollInc = LOWORD(lParam) - nVscrollPos;
- break;
- default: /* END_SCROLL comes thru here */
- nVscrollInc = 0;
- } /* bottom of scroll-decoding switch */
-
- if (nVscrollInc = max(-nVscrollPos,
- min(nVscrollInc, nVscrollMax - nVscrollPos)))
- {
- nVscrollPos += nVscrollInc;
- ScrollWindow(hWnd, 0, -yChar * nVscrollInc, NULL, NULL);
- SetScrollPos(hWnd, SB_VERT, nVscrollPos, TRUE);
- UpdateWindow(hWnd);
- }
- return 0;
-
- case WM_HSCROLL: /* scroll bar action on list box */
- switch (wParam) { /* decode parameter type */
- case SB_TOP:
- nHscrollInc = -nHscrollPos;
- break;
- case SB_BOTTOM:
- nHscrollInc = nHscrollMax - nHscrollPos;
- break;
- 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;
- default:
- #ifdef CATCHING_END_SCROLL
- nHscrollInc = 0;
- #else
- return (DefWindowProc(hWnd, iMessage, wParam, lParam));
- #endif
- } /* bottom of scroll-decoding switch */
-
- if (nHscrollInc = max(-nHscrollPos,
- min(nHscrollInc, nHscrollMax - nHscrollPos)))
- {
- nHscrollPos += nHscrollInc;
- ScrollWindow(hWnd, -xChar * nHscrollInc, 0, NULL, NULL);
- SetScrollPos(hWnd, SB_HORZ, nHscrollPos, TRUE);
- }
- return 0;
-
- case WM_KEYDOWN:
- bCntl = (BOOL)(GetKeyState(VK_CONTROL) < 0 ? TRUE : FALSE);
- for (i = 0, pKE = KeyTable; i < NUMKEYS; i++, pKE++)
- {
- if (wParam == pKE->wVirtKey && bCntl == pKE->bCntl)
- {
- SendMessage(hWnd, pKE->iMessage, pKE->wRequest, 0L);
- break;
- }
- }
- break;
- case WM_PAINT:
- if (!hGlobalStatus) /* if nothing to paint */
- {
- return (DefWindowProc(hWnd, iMessage, wParam, lParam)); /* exit */
- }
- {
- REGISTER LPSTR lpC; /* current char */
- LPSTR lpCtemp; /* address of next '\n' in buffer */
- LPSTR lpStartC; /* paint starting character */
- LPSTR lpBegLine; /* beginning of current line */
- HANDLE hNewHandle;
- DWORD dwLineLen; /* length of current line */
- short nLinesSinceLastEntry; /* lines since last entry */
- DWORD dwSearchLen; /* length for _fmemchr() to search */
-
- lpStartC = NULL; /* paint starting character */
- lpStatusBuffer = GlobalLock(hGlobalStatus);
- WinAssert(lpStatusBuffer); /* DEBUG */
- hDC = BeginPaint(hWnd, &ps);
- WinAssert(hDC); /* DEBUG */
- hNewHandle = SelectObject ( hDC, hFixedFont);
- WinAssert(hNewHandle); /* DEBUG */
- nPaintBeg = max(0, nVscrollPos+ps.rcPaint.top/yChar -1);
- nPaintEnd = min(nNumLines, nVscrollPos + ps.rcPaint.bottom/yChar);
- if (nPaintBeg >= nPaintEnd) /* if no painting to do ... */
- {
- EndPaint(hWnd, &ps); /* just exit */
- GlobalUnlock(hGlobalStatus); /* unlock memory */
- return 0;
- }
- if (!nIndexEntries) /* re-index whenever more data is added */
- {
- /* Round up to make lines_per_entry encompass all
- * possible lines in buffer.
- */
- nLinesPerEntry = (nNumLines+MAX_INDEX_ENTRIES-1) / MAX_INDEX_ENTRIES;
- if (!nLinesPerEntry) /* if zero */
- nLinesPerEntry++; /* set to 1 as minimum */
-
- /* Count lines from beginning of buffer to:
- * 1) mark beginning of paint sequence (lpStartC) and
- * 2) periodically save buffer index in MsgWinIndex[] table.
- */
- for (lpC = lpStatusBuffer, i = 0, nLinesSinceLastEntry = 0;
- (DWORD)(lpC - lpStatusBuffer) < dwStatusSize ; i++)
- {
- /* We are at the 1st character position in the line */
- if (i == nPaintBeg) /* Starting point for paint ? */
- lpStartC = lpC; /* If so, mark starting point */
-
- /* Entry time ? */
- if (!nLinesSinceLastEntry++ &&
- nIndexEntries < MAX_INDEX_ENTRIES)
- {
- dwMsgWinIndex[nIndexEntries] =
- (DWORD)(lpC - lpStatusBuffer); /* save index */
- nIndexEntries++;
- }
- if (nLinesSinceLastEntry >= nLinesPerEntry)
- nLinesSinceLastEntry = 0;
-
- /* Use _fmemchr() to find next LF.
- * It's probably optimized for searches.
- */
- dwSearchLen = dwStatusSize -
- (DWORD)(lpC - lpStatusBuffer);
- if ((lpCtemp = _fmemchr(lpC, '\n', (size_t)dwSearchLen)))
- lpC = ++lpCtemp; /* use next char as beg of line */
-
- else /* else use lpC with incremented value */
- lpC += dwSearchLen;
-
- } /* bottom of still-counting-lines loop */
- WinAssert(lpStartC); /* DEBUG */
- lpC = lpStartC; /* restore starting point */
- WinAssert((DWORD)lpC >= (DWORD)lpStatusBuffer && /* DEBUG */
- (DWORD)lpC < (DWORD)&lpStatusBuffer[dwStatusSize]);
-
- } /* bottom of need-to-build-index block */
- else /* index is still valid */
- {
- short nIndexEntry; /* work backwards! */
-
- /* Find index of line number which is equal to or just
- * below the starting line to paint. Work backwards
- * thru the table. Here, "i" is the line no. corresponding
- * to the current table index.
- */
- for (nIndexEntry = nIndexEntries - 1,
- i = nIndexEntry * nLinesPerEntry;
- nIndexEntry >= 0 &&
- nPaintBeg < i ;
- nIndexEntry--, i -= nLinesPerEntry )
- ;
-
- WinAssert(nIndexEntry >= 0); /* DEBUG */
- WinAssert(i <= nPaintBeg); /* DEBUG */
- /* OK, we've got a head start on the search.
- * Start checking characters from the position found
- * in the index table.
- */
- for (lpC = &lpStatusBuffer[dwMsgWinIndex[nIndexEntry]];
- i < nPaintBeg &&
- #ifndef NEW_WAY
- (DWORD)(lpC - lpStatusBuffer) < dwStatusSize;
- #else
- ((DWORD)lpC - (DWORD)lpStatusBuffer) < dwStatusSize;
- #endif
- i++)
- {
- /* Find length of current line. Use _fmemchr() to
- * find next LF.
- */
- dwSearchLen = dwStatusSize -
- (DWORD)(lpC - lpStatusBuffer);
- if ((lpCtemp = _fmemchr(lpC, '\n', (size_t)dwSearchLen)) != NULL)
- lpC = ++lpCtemp; /* point to next char. past '\n' */
-
- else /* If search fails, pretend LF exists, go past it. */
- lpC += dwSearchLen;
-
- }
- } /* bottom of index-is-still-valid block. */
-
- /* At this point we've got the buffer address, lpC, for the 1st
- * line at which we begin painting, nPaintBeg.
- */
- for (i = nPaintBeg;
- i < nPaintEnd &&
- #ifndef NEW_WAY
- (DWORD)(lpC - lpStatusBuffer) >= 0L &&
- (DWORD)(lpC - lpStatusBuffer) < dwStatusSize ;
- #else
- ((DWORD)lpC - (DWORD)lpStatusBuffer) >= 0L &&
- ((DWORD)lpC - (DWORD)lpStatusBuffer) < dwStatusSize ;
- #endif
- i++)
- {
- lpBegLine = lpC;
- /* Find length of current line. Use _fmemchr() to find next LF.
- */
- dwSearchLen = dwStatusSize - (DWORD)(lpC - lpStatusBuffer);
- if ((lpCtemp = _fmemchr(lpC, '\n', (size_t)dwSearchLen)) == NULL)
- {
- /* If search fails, pretend we found LF, we won't
- * display it anyway.
- */
- lpCtemp = lpC + dwSearchLen;
- }
- WinAssert((DWORD)lpCtemp >= (DWORD)lpBegLine); /* should be non-negative */
- WinAssert((DWORD)lpCtemp >= (DWORD)lpStatusBuffer && /* DEBUG */
- (DWORD)lpCtemp <= (DWORD)&lpStatusBuffer[dwStatusSize]);
-
- x = xChar * (1 - nHscrollPos);
- y = yChar * (1 - nVscrollPos + i);
- dwLineLen = (DWORD)(lpCtemp - lpBegLine);/* calc length*/
- if (dwLineLen && lpBegLine[dwLineLen-1] == '\r')
- dwLineLen--; /* don't display '\r' */
-
- /* may be displaying long lines if binary file */
- if (dwLineLen > MAX_TEXTOUT_COUNT)
- dwLineLen = MAX_TEXTOUT_COUNT;
-
- TabbedTextOut(hDC, x, y, lpBegLine, (int)dwLineLen, 0, NULL, 0);
- lpC = ++lpCtemp; /* point to next char. past '\n' */
- }
- EndPaint(hWnd, &ps);
- GlobalUnlock(hGlobalStatus); /* unlock memory */
- return 0;
- }
- return (DefWindowProc(hWnd, iMessage, wParam, lParam));
- break;
- case WM_CLOSE: /* message: close the window */
- DestroyWindow(hWnd); /* close the mesg. window */
- break;
- case WM_DESTROY:
- FreeStatusLog();
- break;
- default:
- return (DefWindowProc(hWnd, iMessage, wParam, lParam));
- }
- return 0L;
- }
-
- /* Printf buffers the current output and counts the number of lines
- * within it. It makes sure there is enough space in the global
- * buffer, then copies the buffered data to the global buffer.
- * It then triggers a repaint of the status buffer.
- */
- int _FAR_ _cdecl printf(const char _FAR_ *format, ...)
- {
- va_list argptr;
- int LinesInBuffer = 0;
- HANDLE hMemory;
- PSTR psBuffer;
-
- va_start(argptr, format);
- hMemory = LocalAlloc(LMEM_MOVEABLE, STDIO_BUF_SIZE);
- WinAssert(hMemory);
- if (!hMemory)
- {
- return 0;
- }
- psBuffer = (PSTR)LocalLock(hMemory);
- WinAssert(psBuffer); /* DEBUG */
- vsprintf(psBuffer, format, argptr);
- va_end(argptr);
- WinAssert(strlen(psBuffer) < STDIO_BUF_SIZE); /* raise STDIO_BUF_SIZE ? */
- WriteStringToMsgWin(psBuffer, bRealTimeMsgUpdate);
- LocalUnlock(hMemory); /* unlock it to Windows */
- LocalFree(hMemory); /* Returns it to Windows */
- return 0;
- }
-
- /* fprintf clone for code in unzip.c, etc.
- */
- int _FAR_ _cdecl fprintf(FILE _FAR_ *file, const char _FAR_ *format, ...)
- {
- va_list argptr;
- int LinesInBuffer = 0;
- HANDLE hMemory;
- PSTR psBuffer;
-
- va_start(argptr, format);
- hMemory = LocalAlloc(LMEM_MOVEABLE, STDIO_BUF_SIZE);
- WinAssert(hMemory);
- if (!hMemory)
- {
- return 0;
- }
- psBuffer = (PSTR)LocalLock(hMemory);
- WinAssert(psBuffer); /* DEBUG */
- vsprintf(psBuffer, format, argptr);
- va_end(argptr);
- WinAssert(strlen(psBuffer) < STDIO_BUF_SIZE); /* raise STDIO_BUF_SIZE ? */
- WriteStringToMsgWin(psBuffer, bRealTimeMsgUpdate);
- LocalUnlock(hMemory); /* unlock it to Windows */
- LocalFree(hMemory); /* Returns it to Windows */
- }
-
- void _FAR_ _cdecl perror(const char _FAR_ *parm1)
- {
- printf(parm1);
- }
-