📄 w32start.h
字号:
// __________________________________________________________
//
// W32Start.h
// Startup Code for Win32 Applications V1.02
// 08-23-2000 Sven B. Schreiber
// sbs@orgon.com
// __________________________________________________________
#ifndef _W32START_H_
#define _W32START_H_
#include "proginfo.h"
// =================================================================
// DISCLAIMER
// =================================================================
/*
This software is provided "as is" and any express or implied
warranties, including, but not limited to, the implied warranties of
merchantibility and fitness for a particular purpose are disclaimed.
In no event shall the author Sven B. Schreiber be liable for any
direct, indirect, incidental, special, exemplary, or consequential
damages (including, but not limited to, procurement of substitute
goods or services; loss of use, data, or profits; or business
interruption) however caused and on any theory of liability,
whether in contract, strict liability, or tort (including negligence
or otherwise) arising in any way out of the use of this software,
even if advised of the possibility of such damage.
*/
// =================================================================
// REVISION HISTORY
// =================================================================
/*
06-25-1999 V1.00 Original version (SBS).
This is a replacement for ConStart.h and GuiStart.h, containing
common startup and library code for both Win32 console and GUI
applications. Differences are accounted for by checking the
existence of the _CONSOLE symbol in conditional compilation
blocks. New enhanced printf(), fprintf(), vfprintf(), sprintf(),
and vsprintf() implementations for Unicode and ANSI. mprintf()
and vmprintf() are derivatives of fprintf() and vfprintf(),
displaying the data in a MessageBox() instead of writing it to
a stream. All *printf() functions impose no restrictions on the
size of the data and have various new formatting features. If
sprintf() and vsprintf() receive a buffer pointer of NULL, the
required buffer size is computed only. GUI applications are
allowed to call printf(), which will automatically create a
console window on first invocation. The console status can also
be controlled explicitly using the ConsoleCreate() and
ConsoleDestroy() run-time functions. The console line length
computation has moved from Main() to the startup code. New
command line parser, featuring an argp[] array of pointers to
the arguments in the raw command line. Main() and WinMain()
prototypes slightly revised for the new parser.
07-17-1999 V1.01 Upgrade (SBS).
Added vprintfA(), vprintfW(), and the corresponding ANSI/Unicode
macro vprintf. Changed printf() to use vprintf() now instead of
vfprintf().
08-23-2000 V1.02 Upgrade (SBS).
Moved the WriteFile() calls into a loop that outputs the data
in 16-KB blocks. Moved the ConsoleCreate() call inside printf()
to vprintf(). Added eprintf() and veprintf(), which write to
STDERR instead of STDOUT. Added ConsoleTest() and redesigned
ConsoleCreate() and ConsoleDestroy(). Renamed ConsoleCreate() to
ConsoleOpen() and ConsoleDestroy() to ConsoleClose().
*/
////////////////////////////////////////////////////////////////////
#ifndef _RC_PASS_
////////////////////////////////////////////////////////////////////
// =================================================================
// MACROS
// =================================================================
#define ALLOC_ANSI(_n) \
((PBYTE) LocalAlloc (LMEM_FIXED, (_n)))
#define ALLOC_UNICODE(_n) \
((PWORD) LocalAlloc (LMEM_FIXED, (_n) * sizeof (WORD)))
// =================================================================
// CONSTANTS
// =================================================================
#define UNICODE_UNMAPPED 0x7F
#define WRITE_FILE_BLOCK 0x4000
#define CONSOLE_TITLE 0x1000
// =================================================================
// STRUCTURES
// =================================================================
typedef struct _WIN_CMD
{
DWORD argc;
PTBYTE *argv;
PTBYTE *argp;
PTBYTE ptRaw;
PTBYTE ptCooked;
PTBYTE ptTail;
BYTE abData [];
}
WIN_CMD, *PWIN_CMD, **PPWIN_CMD;
#define WIN_CMD_ sizeof (WIN_CMD)
// =================================================================
// GLOBAL VARIABLES
// =================================================================
HANDLE ghStdInput = INVALID_HANDLE_VALUE;
HANDLE ghStdOutput = INVALID_HANDLE_VALUE;
HANDLE ghStdError = INVALID_HANDLE_VALUE;
BOOL gfStdHandles = FALSE;
BOOL gfStdFailure = FALSE;
BOOL gfStdTransient = FALSE;
DWORD gdLine = 80;
INT giNetwork = 0;
INT giDebug = 0;
WORD gwFill = ' ';
// =================================================================
// GLOBAL STRINGS
// =================================================================
TBYTE atUsage [] = T("\r\n")
T("Usage: ") S(MAIN_MODULE) T(" %s\r\n");
TBYTE atAbout [] = T("\r\n")
T("// ") S(ABOUT_TEXT1) T("\r\n")
T("// ") S(ABOUT_TEXT2) T("\r\n")
T("// ") S(ABOUT_TEXT3) T("\r\n")
T("// ") S(ABOUT_TEXT4) T("\r\n");
// =================================================================
// CONDITIONAL ANSI/UNICODE NAMES
// =================================================================
#ifdef UNICODE
#define ConsoleTest ConsoleTestW
#define vsprintf vsprintfW
#define vmprintf vmprintfW
#define vfprintf vfprintfW
#define veprintf veprintfW
#define vprintf vprintfW
#define sprintf sprintfW
#define mprintf mprintfW
#define fprintf fprintfW
#define eprintf eprintfW
#define printf printfW
#else
#define ConsoleTest ConsoleTestA
#define vsprintf vsprintfA
#define vmprintf vmprintfA
#define vfprintf vfprintfA
#define veprintf veprintfA
#define vprintf vprintfA
#define sprintf sprintfA
#define mprintf mprintfA
#define fprintf fprintfA
#define eprintf eprintfA
#define printf printfA
#endif
// =================================================================
// CONSOLE MANAGEMENT
// =================================================================
BOOL WINAPI ConsoleTestA (void)
{
BYTE abTitle [CONSOLE_TITLE];
return GetConsoleTitleA (abTitle, CONSOLE_TITLE) != 0;
}
// -----------------------------------------------------------------
BOOL WINAPI ConsoleTestW (void)
{
WORD awTitle [CONSOLE_TITLE];
return GetConsoleTitleW (awTitle, CONSOLE_TITLE) != 0;
}
// -----------------------------------------------------------------
BOOL WINAPI ConsoleOpen (void)
{
if ((!gfStdHandles) && (!gfStdFailure))
{
gfStdTransient = (!ConsoleTest ()) && AllocConsole ();
if (ConsoleTest ())
{
ghStdInput = GetStdHandle (STD_INPUT_HANDLE);
ghStdOutput = GetStdHandle (STD_OUTPUT_HANDLE);
ghStdError = GetStdHandle (STD_ERROR_HANDLE);
if ((ghStdInput != INVALID_HANDLE_VALUE) &&
(ghStdOutput != INVALID_HANDLE_VALUE) &&
(ghStdError != INVALID_HANDLE_VALUE))
{
gfStdHandles = TRUE;
}
else
{
ghStdInput = INVALID_HANDLE_VALUE;
ghStdOutput = INVALID_HANDLE_VALUE;
ghStdError = INVALID_HANDLE_VALUE;
}
}
if ((gfStdFailure = !gfStdHandles) && gfStdTransient)
{
FreeConsole ();
gfStdTransient = FALSE;
}
}
return gfStdHandles;
}
// -----------------------------------------------------------------
BOOL WINAPI ConsoleClose (void)
{
BOOL fOk = FALSE;
if (gfStdHandles)
{
ghStdInput = INVALID_HANDLE_VALUE;
ghStdOutput = INVALID_HANDLE_VALUE;
ghStdError = INVALID_HANDLE_VALUE;
gfStdHandles = FALSE;
fOk = TRUE;
}
if (gfStdTransient)
{
if (ConsoleTest ()) FreeConsole ();
gfStdTransient = FALSE;
}
gfStdFailure = FALSE;
return fOk;
}
// =================================================================
// TEXT CONVERSION ROUTINES
// =================================================================
PWORD WINAPI ConvertAnsiToUnicode (PBYTE pbData,
PWORD pwData)
{
DWORD n;
PWORD pwData1 = NULL;
if (pbData != NULL)
{
for (n = 0; pbData [n]; n++);
if ((pwData1 = (pwData != NULL ? pwData
: ALLOC_UNICODE (n+1)))
!= NULL)
{
do {
pwData1 [n] = pbData [n];
}
while (n--);
}
}
return pwData1;
}
// -----------------------------------------------------------------
PBYTE WINAPI ConvertUnicodeToAnsi (PWORD pwData,
PBYTE pbData)
{
DWORD n;
PBYTE pbData1 = NULL;
if (pwData != NULL)
{
for (n = 0; pwData [n]; n++);
if ((pbData1 = (pbData != NULL ? pbData
: ALLOC_ANSI (n+1)))
!= NULL)
{
if (!WideCharToMultiByte
(CP_ACP, WC_COMPOSITECHECK | WC_DISCARDNS,
pwData, -1, pbData1, n+1, NULL, NULL))
{
do {
pbData1 [n] = (pwData [n] < 0x0100
? (BYTE) pwData [n]
: UNICODE_UNMAPPED);
}
while (n--);
}
}
}
return pbData1;
}
// =================================================================
// printf() PRIMITIVES
// =================================================================
DWORD WINAPI FormatAnsiW (PWORD pwBuffer,
DWORD dOffset,
PBYTE pbData,
DWORD dData,
DWORD dWidth,
DWORD dPrecision,
WORD wFill,
BOOL fRight,
BOOL fZero)
{
PWORD pwBuffer1;
WORD wData;
DWORD i, j, k;
DWORD n = 0;
if (pbData != NULL)
{
if (dData != -1)
{
i = dData;
}
else
{
for (i = 0; pbData [i]; i++);
}
}
j = (dPrecision == -1 ? i : max (i, dPrecision));
n = max (i, dWidth);
if (pwBuffer != NULL)
{
pwBuffer1 = pwBuffer + dOffset;
wData = (fZero ? '0' : wFill);
if (fRight)
{
k = n;
while (k > j) pwBuffer1 [--k] = wData;
while (k > i) pwBuffer1 [--k] = ' ';
k = 0;
}
else
{
k = 0;
while (k < n - j) pwBuffer1 [k++] = wData;
while (k < n - i) pwBuffer1 [k++] = ' ';
}
while (i--)
{
pwBuffer1 [k+i] = pbData [i];
}
}
if (pwBuffer != NULL) pwBuffer [dOffset+n] = 0;
return n;
}
// -----------------------------------------------------------------
DWORD WINAPI FormatUnicodeW (PWORD pwBuffer,
DWORD dOffset,
PWORD pwData,
DWORD dData,
DWORD dWidth,
DWORD dPrecision,
WORD wFill,
BOOL fRight,
BOOL fZero)
{
PWORD pwBuffer1;
WORD wData;
DWORD i, j, k;
DWORD n = 0;
if (pwData != NULL)
{
if (dData != -1)
{
i = dData;
}
else
{
for (i = 0; pwData [i]; i++);
}
}
j = (dPrecision == -1 ? i : max (i, dPrecision));
n = max (i, dWidth);
if (pwBuffer != NULL)
{
pwBuffer1 = pwBuffer + dOffset;
wData = (fZero ? '0' : wFill);
if (fRight)
{
k = n;
while (k > j) pwBuffer1 [--k] = wData;
while (k > i) pwBuffer1 [--k] = ' ';
k = 0;
}
else
{
k = 0;
while (k < n - j) pwBuffer1 [k++] = wData;
while (k < n - i) pwBuffer1 [k++] = ' ';
}
while (i--)
{
pwBuffer1 [k+i] = pwData [i];
}
}
if (pwBuffer != NULL) pwBuffer [dOffset+n] = 0;
return n;
}
// -----------------------------------------------------------------
DWORD WINAPI FormatDecimalW (PWORD pwBuffer,
DWORD dOffset,
DWORD dData,
DWORD dWidth,
DWORD dPrecision,
WORD wFill,
BOOL fRight,
BOOL fZero,
BOOL fPrefix,
BOOL fSigned)
{
BOOL fMinus;
PWORD pwBuffer1;
WORD wPrefix, wData;
DWORD dData1, i, j, k;
DWORD n = 0;
fMinus = (fSigned && ((LONG) dData < 0));
dData1 = (fMinus ? 0 - dData : dData);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -