📄 dwtext.cpp
字号:
--dest;
}
break;
case 21: // ^U
while (dest > line) {
putch('\b');
putch(' ');
putch('\b');
--dest;
}
break;
default:
if (dest == limit)
MessageBeep(-1);
else {
*dest++ = ch;
putch(ch);
}
break;
}
}
*dest++ = ch;
putch(ch);
return (dest-line);
}
// Read a string from the keyboard, of up to len characters
// (not including trailing NULL)
int
TextWindow::gets(LPSTR line, int len)
{
LPSTR dest = line;
LPSTR limit = dest + len; // don't leave room for '\0'
int ch;
do {
if (dest >= limit)
break;
ch = getch();
switch(ch) {
case 26: // ^Z == EOF
return 0;
case '\b': // ^H
case 0x7f: // DEL
if (dest > line) {
putch('\b');
putch(' ');
putch('\b');
--dest;
}
break;
case 21: // ^U
while (dest > line) {
putch('\b');
putch(' ');
putch('\b');
--dest;
}
break;
default:
*dest++ = ch;
putch(ch);
break;
}
} while (ch != '\n');
*dest = '\0';
return (dest-line);
}
/* Windows 3.1 drag-drop feature */
void
TextWindow::drag_drop(HDROP hdrop)
{
int i, cFiles;
LPSTR p;
if ( (DragPre==(LPSTR)NULL) || (DragPost==(LPSTR)NULL) )
return;
char szFile[256];
cFiles = DragQueryFile(hdrop, (UINT)(-1), (LPSTR)NULL, 0);
for (i=0; i<cFiles; i++) {
DragQueryFile(hdrop, i, szFile, 80);
for (p=DragPre; *p; p++)
SendMessage(hwnd,WM_CHAR,*p,1L);
for (p=szFile; *p; p++) {
if (*p == '\\')
SendMessage(hwnd,WM_CHAR,'/',1L);
else
SendMessage(hwnd,WM_CHAR,*p,1L);
}
for (p=DragPost; *p; p++)
SendMessage(hwnd,WM_CHAR,*p,1L);
}
DragFinish(hdrop);
}
void
TextWindow::copy_to_clipboard(void)
{
int size, count;
HGLOBAL hGMem;
LPSTR cbuf, cp;
TEXTMETRIC tm;
UINT type;
HDC hdc;
int i;
size = ScreenSize.y * (ScreenSize.x + 2) + 1;
hGMem = GlobalAlloc(GHND | GMEM_SHARE, (DWORD)size);
cbuf = cp = (LPSTR)GlobalLock(hGMem);
if (cp == (LPSTR)NULL)
return;
for (i=0; i<ScreenSize.y; i++) {
count = ScreenSize.x;
_fmemcpy(cp, ScreenBuffer + ScreenSize.x*i, count);
/* remove trailing spaces */
for (count=count-1; count>=0; count--) {
if (cp[count]!=' ')
break;
cp[count] = '\0';
}
cp[++count] = '\r';
cp[++count] = '\n';
cp[++count] = '\0';
cp += count;
}
size = _fstrlen(cbuf) + 1;
GlobalUnlock(hGMem);
hGMem = GlobalReAlloc(hGMem, (DWORD)size, GHND | GMEM_SHARE);
/* find out what type to put into clipboard */
hdc = GetDC(hwnd);
SelectFont(hdc, hfont);
GetTextMetrics(hdc,(TEXTMETRIC FAR *)&tm);
if (tm.tmCharSet == OEM_CHARSET)
type = CF_OEMTEXT;
else
type = CF_TEXT;
ReleaseDC(hwnd, hdc);
/* give buffer to clipboard */
OpenClipboard(hwnd);
EmptyClipboard();
SetClipboardData(type, hGMem);
CloseClipboard();
}
/* text window */
LRESULT CALLBACK _export
WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
TextWindow *tw;
if (message == WM_CREATE) {
// Object is stored in window extra data.
// Nothing must try to use the object before WM_CREATE
// initializes it here.
tw = (TextWindow *)(((CREATESTRUCT FAR *)lParam)->lpCreateParams);
SetWindowLong(hwnd, 0, (LONG)tw);
}
// call the object window procedure
tw = (TextWindow *)GetWindowLong(hwnd, 0);
return tw->WndProc(hwnd, message, wParam, lParam);
}
// member window procedure
LRESULT
TextWindow::WndProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HDC hdc;
PAINTSTRUCT ps;
RECT rect;
int nYinc, nXinc;
switch(message) {
case WM_SYSCOMMAND:
switch(LOWORD(wParam)) {
case M_COPY_CLIP:
copy_to_clipboard();
return 0;
}
break;
case WM_SETFOCUS:
bFocus = TRUE;
CreateCaret(hwnd, 0, CharSize.x, 2+CaretHeight);
SetCaretPos(CursorPos.x*CharSize.x - ScrollPos.x,
CursorPos.y*CharSize.y + CharAscent
- CaretHeight - ScrollPos.y);
if (bGetCh)
ShowCaret(hwnd);
break;
case WM_KILLFOCUS:
DestroyCaret();
bFocus = FALSE;
break;
case WM_SIZE:
ClientSize.y = HIWORD(lParam);
ClientSize.x = LOWORD(lParam);
ScrollMax.y = max(0, CharSize.y*ScreenSize.y - ClientSize.y);
ScrollPos.y = min(ScrollPos.y, ScrollMax.y);
SetScrollRange(hwnd, SB_VERT, 0, ScrollMax.y, FALSE);
SetScrollPos(hwnd, SB_VERT, ScrollPos.y, TRUE);
ScrollMax.x = max(0, CharSize.x*ScreenSize.x - ClientSize.x);
ScrollPos.x = min(ScrollPos.x, ScrollMax.x);
SetScrollRange(hwnd, SB_HORZ, 0, ScrollMax.x, FALSE);
SetScrollPos(hwnd, SB_HORZ, ScrollPos.x, TRUE);
if (bFocus && bGetCh) {
SetCaretPos(CursorPos.x*CharSize.x - ScrollPos.x,
CursorPos.y*CharSize.y + CharAscent
- CaretHeight - ScrollPos.y);
ShowCaret(hwnd);
}
return(0);
case WM_VSCROLL:
switch(LOWORD(wParam)) {
case SB_TOP:
nYinc = -ScrollPos.y;
break;
case SB_BOTTOM:
nYinc = ScrollMax.y - ScrollPos.y;
break;
case SB_LINEUP:
nYinc = -CharSize.y;
break;
case SB_LINEDOWN:
nYinc = CharSize.y;
break;
case SB_PAGEUP:
nYinc = min(-1,-ClientSize.y);
break;
case SB_PAGEDOWN:
nYinc = max(1,ClientSize.y);
break;
case SB_THUMBPOSITION:
#ifdef __WIN32__
nYinc = HIWORD(wParam) - ScrollPos.y;
#else
nYinc = LOWORD(lParam) - ScrollPos.y;
#endif
break;
default:
nYinc = 0;
}
if ( (nYinc = max(-ScrollPos.y,
min(nYinc, ScrollMax.y - ScrollPos.y)))
!= 0 ) {
ScrollPos.y += nYinc;
ScrollWindow(hwnd,0,-nYinc,NULL,NULL);
SetScrollPos(hwnd,SB_VERT,ScrollPos.y,TRUE);
UpdateWindow(hwnd);
}
return(0);
case WM_HSCROLL:
switch(LOWORD(wParam)) {
case SB_LINEUP:
nXinc = -CharSize.x;
break;
case SB_LINEDOWN:
nXinc = CharSize.x;
break;
case SB_PAGEUP:
nXinc = min(-1,-ClientSize.x);
break;
case SB_PAGEDOWN:
nXinc = max(1,ClientSize.x);
break;
case SB_THUMBPOSITION:
#ifdef __WIN32__
nXinc = HIWORD(wParam) - ScrollPos.x;
#else
nXinc = LOWORD(lParam) - ScrollPos.x;
#endif
break;
default:
nXinc = 0;
}
if ( (nXinc = max(-ScrollPos.x,
min(nXinc, ScrollMax.x - ScrollPos.x)))
!= 0 ) {
ScrollPos.x += nXinc;
ScrollWindow(hwnd,-nXinc,0,NULL,NULL);
SetScrollPos(hwnd,SB_HORZ,ScrollPos.x,TRUE);
UpdateWindow(hwnd);
}
return(0);
case WM_KEYDOWN:
if (GetKeyState(VK_SHIFT) < 0) {
switch(wParam) {
case VK_HOME:
SendMessage(hwnd, WM_VSCROLL, SB_TOP, (LPARAM)0);
break;
case VK_END:
SendMessage(hwnd, WM_VSCROLL, SB_BOTTOM, (LPARAM)0);
break;
case VK_PRIOR:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEUP, (LPARAM)0);
break;
case VK_NEXT:
SendMessage(hwnd, WM_VSCROLL, SB_PAGEDOWN, (LPARAM)0);
break;
case VK_UP:
SendMessage(hwnd, WM_VSCROLL, SB_LINEUP, (LPARAM)0);
break;
case VK_DOWN:
SendMessage(hwnd, WM_VSCROLL, SB_LINEDOWN, (LPARAM)0);
break;
case VK_LEFT:
SendMessage(hwnd, WM_HSCROLL, SB_LINEUP, (LPARAM)0);
break;
case VK_RIGHT:
SendMessage(hwnd, WM_HSCROLL, SB_LINEDOWN, (LPARAM)0);
break;
}
}
else {
switch(wParam) {
case VK_HOME:
case VK_END:
case VK_PRIOR:
case VK_NEXT:
case VK_UP:
case VK_DOWN:
case VK_LEFT:
case VK_RIGHT:
case VK_DELETE:
{ /* store key in circular buffer */
long count = KeyBufIn - KeyBufOut;
if (count < 0) count += KeyBufSize;
if (count < KeyBufSize-2) {
*KeyBufIn++ = 0;
if (KeyBufIn - KeyBuf >= KeyBufSize)
KeyBufIn = KeyBuf; /* wrap around */
*KeyBufIn++ = HIWORD(lParam) & 0xff;
if (KeyBufIn - KeyBuf >= KeyBufSize)
KeyBufIn = KeyBuf; /* wrap around */
}
}
}
}
break;
case WM_CHAR:
{ /* store key in circular buffer */
long count = KeyBufIn - KeyBufOut;
if (count < 0) count += KeyBufSize;
if (count < KeyBufSize-1) {
*KeyBufIn++ = wParam;
if (KeyBufIn - KeyBuf >= KeyBufSize)
KeyBufIn = KeyBuf; /* wrap around */
}
}
return(0);
case WM_PAINT:
{
POINT source, width, dest;
hdc = BeginPaint(hwnd, &ps);
SelectFont(hdc, hfont);
SetMapMode(hdc, MM_TEXT);
SetBkMode(hdc,OPAQUE);
GetClientRect(hwnd, &rect);
source.x = (rect.left + ScrollPos.x) / CharSize.x; /* source */
source.y = (rect.top + ScrollPos.y) / CharSize.y;
dest.x = source.x * CharSize.x - ScrollPos.x; /* destination */
dest.y = source.y * CharSize.y - ScrollPos.y;
width.x = ((rect.right + ScrollPos.x + CharSize.x - 1) / CharSize.x) - source.x; /* width */
width.y = ((rect.bottom + ScrollPos.y + CharSize.y - 1) / CharSize.y) - source.y;
if (source.x < 0)
source.x = 0;
if (source.y < 0)
source.y = 0;
if (source.x+width.x > ScreenSize.x)
width.x = ScreenSize.x - source.x;
if (source.y+width.y > ScreenSize.y)
width.y = ScreenSize.y - source.y;
/* for each line */
while (width.y>0) {
TextOut(hdc,dest.x,dest.y,
(LPSTR)(ScreenBuffer + source.y*ScreenSize.x + source.x),
width.x);
dest.y += CharSize.y;
source.y++;
width.y--;
}
EndPaint(hwnd, &ps);
return 0;
}
case WM_DROPFILES:
drag_drop((HDROP)wParam);
break;
case WM_CREATE:
{
RECT crect, wrect;
TextWindow::hwnd = hwnd;
GetClientRect(hwnd, &crect);
if ( (CharSize.y*ScreenSize.y < crect.bottom)
|| (CharSize.x*ScreenSize.x < crect.right) ) {
/* shrink size */
GetWindowRect(hwnd,&wrect);
MoveWindow(hwnd, wrect.left, wrect.top,
wrect.right-wrect.left + (CharSize.x*ScreenSize.x - crect.right),
wrect.bottom-wrect.top + (CharSize.y*ScreenSize.y - crect.bottom),
TRUE);
}
if ( (DragPre!=(LPSTR)NULL) && (DragPost!=(LPSTR)NULL) )
DragAcceptFiles(hwnd, TRUE);
}
break;
case WM_CLOSE:
break;
case WM_DESTROY:
DragAcceptFiles(hwnd, FALSE);
if (hfont)
DeleteFont(hfont);
hfont = (HFONT)0;
quitnow = TRUE;
PostQuitMessage(0);
break;
}
return DefWindowProc(hwnd, message, wParam, lParam);
}
#ifdef NOTUSED
// test program
#pragma argsused
int PASCAL
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpszCmdLine, int nCmdShow)
{
// make a test window
TextWindow* textwin = new TextWindow(hInstance);
if (!hPrevInstance) {
HICON hicon = LoadIcon(NULL, IDI_APPLICATION);
textwin->register_class(hicon);
}
textwin->font("Courier New", 10);
textwin->size(80, 80);
textwin->drag("(", ") run\r");
// show the text window
if (!textwin->show("Application Name", nCmdShow)) {
// do the real work here
// TESTING
int ch;
int len;
char *line = new char[256];
while ( (len = textwin->read_line(line, 256-1)) != 0 ) {
textwin->write_buf(line, len);
}
/*
while ( textwin->gets(line, 256-1) ) {
textwin->puts(line);
}
*/
/*
while ( (ch = textwin->getch()) != 4 )
textwin->putch(ch);
*/
}
else {
}
// clean up
delete textwin;
// end program
return 0;
}
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -