📄 wprintf.c
字号:
/******************************************************************************\
* This is a part of the Microsoft Source Code Samples.
* Copyright (C) 1993-1997 Microsoft Corporation.
* All rights reserved.
* This source code is only intended as a supplement to
* Microsoft Development Tools and/or WinHelp documentation.
* See these sources for detailed information regarding the
* Microsoft samples programs.
\******************************************************************************/
/*****************************************************************************\
*
* Module: wprintf.c
*
* Contains the routines for using printf windows
*
* Functions:
*
* MyCreatePrintfWin()
* SetPrintFont()
* SetPrintfTabs()
* ClearPrintfWindow()
* CopyToClipboard()
* IsPrintfEmpty()
* PrintfWndProc()
* DebugPaint()
* InsertString()
* DebugHScroll()
* DebugVScroll()
* SetWindowClass()
* LinesInDebugWindow()
* CharsInDebugWindow()
* wprintfSetScrollRange()
* NewLine()
*
* Comments:
*
\*****************************************************************************/
#include "spy.h"
/*****************************************************************************\
*
* g e n e r a l c o n s t a n t s
*
\*****************************************************************************/
#define MAXBUFLEN 200 /* Maximum string length for wprintf */
#define FIRST(pTxt) ((pTxt)->iFirst)
#define TOP(pTxt) (((pTxt)->iFirst + (pTxt)->iTop) % (pTxt)->iMaxLines)
#define LAST(pTxt) (((pTxt)->iFirst + (pTxt)->iCount-1) % (pTxt)->iMaxLines)
#define INC(pTxt,x) ((x) = ++(x) % (pTxt)->iMaxLines)
#define DEC(pTxt,x) ((x) = --(x) % (pTxt)->iMaxLines)
#define OFFSETX (pTxt->Tdx/2)
#define OFFSETY 1
#define VARSIZE 1
#define BOUND(x,mn,mx) ((x) < (mn) ? (mn) : ((x) > (mx) ? (mx) : (x)))
#define FTwixtI3(l,x,h) ((x)>=(l) && (x<=h))
#define EnterCrit(p)
#define LeaveCrit(p)
/*****************************************************************************\
*
* g l o b a l v a r i a b l e s
*
\*****************************************************************************/
typedef struct {
INT iLen;
CHAR * *hText;
} LINE;
struct TEXT_STRUCT {
CRITICAL_SECTION csSync; // CritSect to sync the threads
INT iFirst; /* First line in queue */
INT iCount; /* Number of lines in queue */
INT iTop; /* Line at top of window */
INT iLeft; /* X offset of the window */
INT MaxLen; /* Max String Length */
INT iMaxLines; /* max number of LINEs */
HFONT hFont; /* Font to draw with */
DWORD Tdx, Tdy; /* Font Size */
LINE arLines[VARSIZE]; /* array of iMaxLines LINEs */
};
typedef struct TEXT_STRUCT *PTXT; /* pointer to a text struct */
typedef PTXT *HTXT; /* Handle to a text struct */
PRIVATE INT iSem = 0;
INT tabs[20];
INT nTabs = 0;
/*****************************************************************************\
*
* f u n c t i o n d e f i n i t i o n s
*
\*****************************************************************************/
LONG APIENTRY PrintfWndProc(HWND, UINT, WPARAM, LONG);
PRIVATE VOID DebugPaint(HWND hwnd, LPPAINTSTRUCT pps);
PRIVATE INT InsertString (PTXT, CHAR *);
PRIVATE VOID DebugHScroll(HWND, PTXT, INT);
PRIVATE VOID DebugVScroll(HWND, PTXT, INT);
PRIVATE BOOL SetWindowClass (HANDLE, LPSTR);
PRIVATE INT LinesInDebugWindow (HWND);
PRIVATE INT CharsInDebugWindow (HWND);
PRIVATE VOID wprintfSetScrollRange (HWND, BOOL);
PRIVATE VOID NewLine (PTXT pTxt);
PRIVATE INT mwprintf( HWND hwnd, LPSTR format, ... );
/*****************************************************************************\
* MyCreatePrintfWin
*
* Creates a window to printf to.
*
* Arguments:
* HWND hwnd - handle to the parent window
*
* Returns:
* VOID
\*****************************************************************************/
VOID
MyCreatePrintfWin(
HWND hwnd
)
{
RECT rc;
if (ghwndPrintf)
DestroyWindow(ghwndPrintf);
GetClientRect(hwnd, &rc);
ghwndPrintf = CreatePrintfWin(hwnd, ghInst, "", WS_CHILD | WS_VSCROLL |
WS_HSCROLL, -gcxBorder, -gcyBorder, rc.right + (2 *gcxBorder),
rc.bottom + (2 * gcyBorder), gnLines);
}
/*****************************************************************************\
* DebugPaint(hwnd, pps)
*
* The paint function.
*
* Arguments:
* HWND hwnd - Window to paint to.
* LPPAINTSTRUCT - pps
*
* Returns:
* nothing
*
\*****************************************************************************/
PRIVATE VOID
DebugPaint(
HWND hwnd,
LPPAINTSTRUCT pps
)
{
PTXT pTxt;
HTXT hTxt;
INT iQueue;
INT xco;
INT yco;
INT iLast;
HBRUSH hb;
COLORREF c;
hTxt = (HTXT)GetWindowLong(hwnd, 0);
pTxt = *hTxt;
SetTextColor(pps->hdc, GetSysColor(COLOR_WINDOWTEXT));
c = GetSysColor(COLOR_WINDOW);
SetBkColor(pps->hdc, c);
hb = CreateSolidBrush(c);
if (pTxt->hFont)
SelectObject(pps->hdc, pTxt->hFont);
iLast = LAST(pTxt);
iQueue = TOP(pTxt);
xco = OFFSETX - pTxt->iLeft * pTxt->Tdx;
yco = OFFSETY;
for (;;)
{
if (yco <= pps->rcPaint.bottom &&
(yco + (LONG)(pTxt->Tdy)) >= pps->rcPaint.top)
{
if (pTxt->arLines[iQueue].hText == NULL
|| (LPSTR)*(pTxt->arLines[iQueue].hText) == NULL)
{
RECT rcT;
rcT.top = yco;
rcT.bottom = yco+pTxt->Tdy;
rcT.left = pps->rcPaint.left;
rcT.right = pps->rcPaint.right;
FillRect(pps->hdc, &rcT, hb);
}
else
{
TabbedTextOut(pps->hdc, xco, yco,
(LPSTR)*(pTxt->arLines[iQueue].hText),
pTxt->arLines[iQueue].iLen, nTabs, tabs, xco);
}
}
if (iQueue == iLast)
break;
yco += pTxt->Tdy;
INC(pTxt, iQueue);
}
DeleteObject((HANDLE)hb);
}
/*****************************************************************************\
* SetWindowClass (hInstance)
*
* Registers the window class of the printf window
*
* Arguments:
* HANDLE hInstance - instance handle of current instance
* LPSTR lpch - pointer to class name
*
* Returns:
* TRUE if successful, FALSE if not
\*****************************************************************************/
PRIVATE BOOL
SetWindowClass(
HANDLE hInstance,
LPSTR lpch
)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = PrintfWndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = sizeof(HANDLE);
wc.hInstance = hInstance;
wc.hIcon = NULL;
wc.hCursor = LoadCursor(NULL, IDC_ARROW);
wc.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
wc.lpszMenuName = NULL;
wc.lpszClassName = lpch;
return RegisterClass(&wc);
}
/*****************************************************************************\
* CreatePrintfWin (hParent, lpchName, dwStyle, x, y, dx, dy, iMaxLines)
*
* Creates a window for the depositing of debuging messages.
*
* Arguments:
* HWND hParent - Window handle of the parent window.
* HANDLE hInstance - Module instance handle.
* lPSTR lpchName - String to appear in the caption bar of the debuging window
* DWORD dwStyle - Window style
* INT x,y - Location of window
* INT dx,dy - Size of the window
* INT iMaxLines - The maximum number of text lines to display in the window
*
* Returns:
* A window handle of the debuging window, or NULL if a error occured.
\*****************************************************************************/
PUBLIC HWND APIENTRY
CreatePrintfWin (
HWND hParent,
HANDLE hInstance,
LPSTR lpchName,
DWORD dwStyle,
INT x,
INT y,
INT dx,
INT dy,
INT iMaxLines
)
{
static BOOL bClass = FALSE; /* Is the class registered */
HWND hwnd;
HTXT hTxt; /* handle to a debuging window struct */
PTXT pTxt;
static CHAR achClass[40];
/*
* Make a Class name that is unique across instances
*/
if (!bClass++) {
wsprintf(achClass, "WPRINTF_%4.4X", hInstance);
SetWindowClass(hInstance, achClass);
}
/* Allocate the window long before create the window, such that the
window proc can find the window long during the create. */
hTxt = (HTXT)LocalAlloc(LHND, sizeof(struct TEXT_STRUCT) + (iMaxLines
- VARSIZE) * sizeof(LINE));
if (!hTxt) {
return FALSE;
}
pTxt = *hTxt;
//InitializeCriticalSection(&pTxt->csSync);
pTxt->iFirst = 0; /* Set the queue up to have 1 NULL line */
pTxt->iCount = 1;
pTxt->iTop = 0;
pTxt->iLeft = 0;
pTxt->MaxLen = 0;
pTxt->iMaxLines = iMaxLines;
pTxt->arLines[0].hText = NULL;
pTxt->arLines[0].iLen = 0;
hwnd = CreateWindow((LPSTR)achClass, (LPSTR)lpchName, dwStyle, x, y,
dx, dy, (HWND)hParent, /* parent window */
(HMENU)NULL, /* use class menu */
(HANDLE)hInstance, /* handle to window instance */
(LPSTR)hTxt /* used by WM_CREATE to set the window long */
);
if (!hwnd) {
return FALSE;
}
wprintfSetScrollRange(hwnd, FALSE);
/* Make window visible */
ShowWindow(hwnd, SHOW_OPENWINDOW);
return hwnd;
}
/*****************************************************************************\
* SetPrintfFont (hwnd,hFont)
*
* Sets the font for the printf window.
*
* Arguments:
* HWND hwnd - Window handle of the printf window.
* HFONT hFont - Font handle
*
* Returns:
*
\*****************************************************************************/
VOID
SetPrintfFont(
HWND hwnd,
HFONT hfont
)
{
PTXT pTxt;
HDC hDC;
TEXTMETRIC tm;
HFONT hfontOld;
pTxt = *(HTXT)GetWindowLong(hwnd, 0);
pTxt->hFont = hfont;
/* Find out the size of a Char in the font */
hDC = GetDC(hwnd);
hfontOld = SelectObject(hDC, hfont);
DeleteObject(hfontOld);
GetTextMetrics(hDC, &tm);
pTxt->Tdy = tm.tmHeight;
pTxt->Tdx = tm.tmAveCharWidth;
ReleaseDC(hwnd, hDC);
CalculatePrintfTabs(hfont);
InvalidateRect(hwnd, NULL, TRUE);
UpdateWindow(hwnd);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -