mirror of https://github.com/lianthony/NT4.0
701 lines
15 KiB
701 lines
15 KiB
/****************************************************************************
|
|
|
|
FILE: mcp.c
|
|
|
|
Functions used in handling Mark/Copy/Paste functions of display text.
|
|
|
|
TABS:
|
|
|
|
Set for 4 spaces.
|
|
|
|
****************************************************************************/
|
|
|
|
#include <windows.h> /* required for all Windows applications */
|
|
#include <commdlg.h>
|
|
#include <stdlib.h>
|
|
#include "NetBIOS.h"
|
|
#include "netobj.h"
|
|
#include "WinVTP.h" /* specific to this program */
|
|
#include "winvtpsz.h"
|
|
|
|
|
|
|
|
void
|
|
MarkModeOn(HWND hwnd, DWORD dwFlags)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
|
|
/* Need to clear out old selection if any */
|
|
if ( !(dwFlags & fdwDontResetSelection) )
|
|
{
|
|
if ( FSelected(pwi->spb) )
|
|
{
|
|
InvertSelection(hwnd, &pwi->spb.rectSelect);
|
|
pwi->spb.dwFlags &= ~fdwSelected;
|
|
pwi->spb.rectSelect.top = pwi->spb.rectSelect.bottom =
|
|
pwi->spb.rectSelect.left = pwi->spb.rectSelect.right = 0;
|
|
}
|
|
else if ( FShowCursor(pwi->spb) )
|
|
{
|
|
DoCursorFlicker(hwnd, dwForceOff);
|
|
}
|
|
|
|
/* set cursor point to top-left corner */
|
|
pwi->spb.ptCursor.y = pwi->spb.ptCursor.x = 0;
|
|
pwi->spb.dwFlags |= fdwMarkMode;
|
|
}
|
|
|
|
dwMarkMode = (dwFlags & fdwMouseSelected) ? dwMarkMouse : dwMarkKeyboard;
|
|
if (dwFlags & fdwMouseSelected)
|
|
{
|
|
SetCapture( hwnd );
|
|
pwi->spb.dwFlags &= ~fdwShowCursor;
|
|
pwi->spb.dwFlags |= fdwMouseSelected | fdwMouseCaptured;
|
|
}
|
|
else
|
|
{
|
|
pwi->spb.dwFlags &= ~(fdwMouseSelected | fdwMouseCaptured);
|
|
pwi->spb.dwFlags |= fdwShowCursor;
|
|
}
|
|
|
|
SetWindowTitle(hwnd, dwMarkMode,
|
|
(pwi->nd.SessionNumber != nSessionNone)
|
|
? (LPSTR)rgchHostName : NULL);
|
|
}
|
|
|
|
void
|
|
MarkModeOff(HWND hwnd)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
|
|
/* Turn off Mark mode */
|
|
if ( FSelected(pwi->spb) )
|
|
{
|
|
InvertSelection(hwnd, &pwi->spb.rectSelect);
|
|
pwi->spb.dwFlags &= ~fdwSelected;
|
|
}
|
|
else if ( FShowCursor(pwi->spb) )
|
|
{
|
|
DoCursorFlicker(hwnd, dwForceOff);
|
|
pwi->spb.dwFlags &= ~fdwShowCursor;
|
|
}
|
|
|
|
dwMarkMode = dwMarkNone;
|
|
SetWindowTitle(hwnd, dwMarkMode,
|
|
(pwi->nd.SessionNumber != nSessionNone)
|
|
? (LPSTR)rgchHostName : NULL);
|
|
|
|
pwi->spb.dwFlags &= ~fdwMarkMode;
|
|
|
|
/* Notify app of pending data */
|
|
if ( FDataPending(pwi->spb) )
|
|
SendMessage(hwnd, NN_RECV, pwi->spb.wData, 0);
|
|
|
|
pwi->spb.dwFlags = 0;
|
|
}
|
|
|
|
void
|
|
DoCursorFlicker(HWND hwnd, DWORD dwForce)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
RECT rectCursor;
|
|
HDC hdc;
|
|
|
|
if ((dwForce == dwForceNone) ||
|
|
((dwForce == dwForceOn) && !FCursorOn(pwi->spb)) ||
|
|
((dwForce == dwForceOff) && FCursorOn(pwi->spb)))
|
|
{
|
|
hdc = GetDC( hwnd );
|
|
if (hdc == NULL)
|
|
return;
|
|
|
|
rectCursor.top = aiyPos[pwi->spb.ptCursor.y];
|
|
rectCursor.left = aixPos[pwi->spb.ptCursor.x];
|
|
rectCursor.bottom = rectCursor.top+iCursorHeight;
|
|
rectCursor.right = rectCursor.left+iCursorWidth;
|
|
|
|
InvertRect(hdc, &rectCursor);
|
|
|
|
if ( FCursorOn(pwi->spb) )
|
|
pwi->spb.dwFlags &= ~fdwCursorOn;
|
|
else
|
|
pwi->spb.dwFlags |= fdwCursorOn;
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
}
|
|
|
|
void
|
|
InvertSelection(HWND hwnd, RECT *prect)
|
|
{
|
|
HDC hdc = GetDC( hwnd );
|
|
RECT rect= *prect;
|
|
|
|
if (hdc == NULL)
|
|
return;
|
|
|
|
/* convert to graphic display coordinates */
|
|
rect.top = aiyPos[rect.top];
|
|
rect.bottom = aiyPos[rect.bottom]+iCursorHeight;
|
|
rect.left = aixPos[rect.left];
|
|
rect.right = aixPos[rect.right]+iCursorWidth;
|
|
|
|
InvertRect(hdc, &rect);
|
|
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
|
|
void
|
|
ExtendSelection(HWND hwnd, POINT *ppt, DWORD dwChange)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
|
|
/* Limit checking */
|
|
if (ppt->x < 0)
|
|
{
|
|
ppt->x = 0;
|
|
}
|
|
else if (ppt->x >= (int)ui.dwMaxCol)
|
|
{
|
|
ppt->x = (int)(ui.dwMaxCol-1);
|
|
}
|
|
|
|
if (ppt->y < 0)
|
|
{
|
|
ppt->y = 0;
|
|
}
|
|
else if (ppt->y >= (int)ui.dwMaxRow)
|
|
{
|
|
ppt->y = (int)(ui.dwMaxRow-1);
|
|
}
|
|
|
|
if ( !FSelected(pwi->spb) )
|
|
{
|
|
DoCursorFlicker(hwnd, dwForceOff);
|
|
|
|
pwi->spb.dwFlags &= ~fdwShowCursor;
|
|
pwi->spb.dwFlags |= fdwSelected;
|
|
pwi->spb.rectSelect.left = pwi->spb.rectSelect.right =
|
|
pwi->spb.ptCursor.x;
|
|
pwi->spb.rectSelect.top = pwi->spb.rectSelect.bottom =
|
|
pwi->spb.ptCursor.y;
|
|
pwi->spb.ptAnchor = pwi->spb.ptCursor;
|
|
InvertSelection(hwnd, &pwi->spb.rectSelect);
|
|
}
|
|
|
|
if (dwChange != dwNothingChanged)
|
|
{
|
|
RECT rectOld = pwi->spb.rectSelect;
|
|
HRGN hrgnOld;
|
|
HRGN hrgnNew;
|
|
HRGN hrgnInvert;
|
|
HDC hdc;
|
|
|
|
if (dwChange & dwXChanged)
|
|
{
|
|
if (ppt->x <= pwi->spb.ptAnchor.x)
|
|
{
|
|
pwi->spb.rectSelect.left = ppt->x;
|
|
pwi->spb.rectSelect.right = pwi->spb.ptAnchor.x;
|
|
}
|
|
else if (ppt->x > pwi->spb.ptAnchor.x)
|
|
{
|
|
pwi->spb.rectSelect.left = pwi->spb.ptAnchor.x;
|
|
pwi->spb.rectSelect.right = ppt->x;
|
|
}
|
|
}
|
|
|
|
if (dwChange & dwYChanged)
|
|
{
|
|
if (ppt->y <= pwi->spb.ptAnchor.y)
|
|
{
|
|
pwi->spb.rectSelect.top = ppt->y;
|
|
pwi->spb.rectSelect.bottom = pwi->spb.ptAnchor.y;
|
|
}
|
|
else if (ppt->y > pwi->spb.ptAnchor.y)
|
|
{
|
|
pwi->spb.rectSelect.top = pwi->spb.ptAnchor.y;
|
|
pwi->spb.rectSelect.bottom = ppt->y;
|
|
}
|
|
}
|
|
|
|
/*
|
|
* Find the difference between the old and new selection
|
|
* rectangles and invert that area
|
|
*/
|
|
|
|
hrgnInvert = CreateRectRgn(0, 0, 0, 0);
|
|
hrgnOld = CreateRectRgn(aixPos[rectOld.left], aiyPos[rectOld.top],
|
|
aixPos[rectOld.right]+iCursorWidth,
|
|
aiyPos[rectOld.bottom]+iCursorHeight);
|
|
hrgnNew = CreateRectRgn(aixPos[pwi->spb.rectSelect.left],
|
|
aiyPos[pwi->spb.rectSelect.top],
|
|
aixPos[pwi->spb.rectSelect.right]+iCursorWidth,
|
|
aiyPos[pwi->spb.rectSelect.bottom]+iCursorHeight);
|
|
|
|
if ((hrgnInvert != NULL) && (hrgnOld != NULL) && (hrgnNew != NULL))
|
|
{
|
|
CombineRgn(hrgnInvert, hrgnOld, hrgnNew, RGN_XOR);
|
|
|
|
hdc = GetDC( hwnd );
|
|
if (hdc != NULL)
|
|
{
|
|
InvertRgn(hdc, hrgnInvert);
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
}
|
|
|
|
/* Cleanup */
|
|
if ( hrgnNew )
|
|
DeleteObject( hrgnNew );
|
|
if ( hrgnOld )
|
|
DeleteObject( hrgnOld );
|
|
if ( hrgnInvert )
|
|
DeleteObject( hrgnInvert );
|
|
}
|
|
}
|
|
|
|
void
|
|
HandleMCPKeyEvent(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
WORD wKeyCode = LOWORD(wParam);
|
|
DWORD dwChange = dwNothingChanged;
|
|
POINT ptNew = pwi->spb.ptCursor;
|
|
BOOL fHandled = FALSE;
|
|
|
|
switch ( wKeyCode )
|
|
{
|
|
case VK_DOWN:
|
|
if (ptNew.y < (int)(ui.dwMaxRow-1))
|
|
{
|
|
dwChange = dwYChanged;
|
|
++ptNew.y;
|
|
}
|
|
break;
|
|
|
|
case VK_UP:
|
|
if (ptNew.y > 0)
|
|
{
|
|
dwChange = dwYChanged;
|
|
--ptNew.y;
|
|
}
|
|
break;
|
|
|
|
case VK_LEFT:
|
|
if (ptNew.x > 0)
|
|
{
|
|
dwChange = dwXChanged;
|
|
--ptNew.x;
|
|
}
|
|
break;
|
|
|
|
case VK_RIGHT:
|
|
if (ptNew.x < (int)(ui.dwMaxCol-1))
|
|
{
|
|
dwChange = dwXChanged;
|
|
++ptNew.x;
|
|
}
|
|
break;
|
|
|
|
case VK_PRIOR:
|
|
if (ptNew.y > 0)
|
|
{
|
|
dwChange = dwYChanged;
|
|
ptNew.y = 0;
|
|
}
|
|
break;
|
|
|
|
case VK_NEXT:
|
|
if (ptNew.y < (int)(ui.dwMaxRow-1))
|
|
{
|
|
dwChange = dwYChanged;
|
|
ptNew.y = ui.dwMaxRow-1;
|
|
}
|
|
break;
|
|
|
|
case VK_HOME:
|
|
if (ptNew.x > 0)
|
|
{
|
|
dwChange = dwXChanged;
|
|
ptNew.x = 0;
|
|
}
|
|
break;
|
|
|
|
case VK_END:
|
|
if (ptNew.x < (int)(ui.dwMaxCol-1))
|
|
{
|
|
dwChange = dwXChanged;
|
|
ptNew.x = ui.dwMaxCol-1;
|
|
}
|
|
break;
|
|
|
|
case VK_ESCAPE:
|
|
case VK_RETURN:
|
|
if ( FMouseCaptured(pwi->spb) )
|
|
{
|
|
MessageBeep( MB_ICONEXCLAMATION );
|
|
}
|
|
|
|
/* fall through */
|
|
|
|
default:
|
|
if ((wKeyCode != VK_SHIFT) && (wKeyCode != VK_CONTROL) &&
|
|
(wKeyCode != VK_MENU) && (wKeyCode != VK_CAPITAL) &&
|
|
(wKeyCode != VK_NUMLOCK) && (wKeyCode != VK_ESCAPE) &&
|
|
(wKeyCode != VK_RETURN))
|
|
{
|
|
MessageBeep( 0xFFFFFFFF );
|
|
}
|
|
fHandled = TRUE;
|
|
break;
|
|
}
|
|
|
|
if (fHandled == FALSE)
|
|
{
|
|
if ( FMouseCaptured(pwi->spb) )
|
|
{
|
|
MessageBeep( MB_ICONEXCLAMATION );
|
|
return;
|
|
}
|
|
|
|
/* Are we marking a region with the mouse? */
|
|
if ( FMouseSelected(pwi->spb) )
|
|
{
|
|
/* Are we still using the mouse to mark a region? */
|
|
if ( FMouseCaptured(pwi->spb) )
|
|
{
|
|
/* Yes, beep at the user then and bail */
|
|
MessageBeep( 0xFFFFFFFF );
|
|
return;
|
|
}
|
|
else
|
|
{
|
|
/* No, then revert to keyboard mark mode. */
|
|
pwi->spb.dwFlags &= ~(fdwMouseSelected | fdwMouseCaptured);
|
|
CursorOff( hwnd );
|
|
|
|
/* Make sure the screen is painted correctly */
|
|
InvalidateRect(hwnd, NULL, FALSE);
|
|
if ( !FSelected(pwi->spb) )
|
|
{
|
|
pwi->spb.dwFlags |= fdwShowCursor;
|
|
}
|
|
|
|
/* update the window caption */
|
|
dwMarkMode = dwMarkKeyboard;
|
|
SetWindowTitle(hwnd, dwMarkMode,
|
|
(pwi->nd.SessionNumber != nSessionNone)
|
|
? (LPSTR)rgchHostName : NULL);
|
|
}
|
|
}
|
|
|
|
if (GetKeyState(VK_SHIFT) & wKeyPressed)
|
|
{
|
|
ExtendSelection(hwnd, &ptNew, dwChange);
|
|
}
|
|
else
|
|
{
|
|
if ( FShowCursor(pwi->spb) )
|
|
{
|
|
DoCursorFlicker(hwnd, dwForceOff);
|
|
}
|
|
else if ( FSelected(pwi->spb) )
|
|
{
|
|
InvertSelection(hwnd, &pwi->spb.rectSelect);
|
|
pwi->spb.dwFlags &= ~fdwSelected;
|
|
pwi->spb.dwFlags |= fdwShowCursor;
|
|
}
|
|
}
|
|
if (dwChange != dwNothingChanged)
|
|
pwi->spb.ptCursor = ptNew;
|
|
}
|
|
}
|
|
|
|
void
|
|
HandleMCPMouseEvent(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
POINT ptNew;
|
|
|
|
/*
|
|
* Convert the mouse point to a character cell point.
|
|
* Need to handle the case where the cursor goes off
|
|
* the left or top edge of the window. In those cases
|
|
* WIN32 seems to return numbers that have the high
|
|
* bit set. So check for that and use 0 instead.
|
|
*/
|
|
ptNew.x = (LOWORD(lParam) & 0x8000) ? 0 : LOWORD(lParam)/iCursorWidth;
|
|
ptNew.y = (HIWORD(lParam) & 0x8000) ? 0 : HIWORD(lParam)/iCursorHeight;
|
|
|
|
/*
|
|
* If the msg is a button down AND the shift key is up,
|
|
* make the pt the new anchor pt, otherwise the selection
|
|
* will be extended
|
|
*/
|
|
if ((message == WM_LBUTTONDOWN) && !(wParam & MK_SHIFT))
|
|
pwi->spb.ptCursor = ptNew;
|
|
|
|
ExtendSelection(hwnd, &ptNew, dwXChanged | dwYChanged);
|
|
pwi->spb.ptCursor = ptNew;
|
|
}
|
|
|
|
void
|
|
DoCopy(HWND hwnd)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
LPSTR szT = NULL;
|
|
UCHAR *puch;
|
|
DWORD cRows;
|
|
DWORD cColumns;
|
|
DWORD cchNeed;
|
|
HGLOBAL hglb;
|
|
int iRow;
|
|
DWORD ich;
|
|
BOOL fAppendCRLF = FALSE;
|
|
|
|
if ( !FInMarkMode(pwi->spb) )
|
|
return;
|
|
|
|
/* nothing selected == nothing to copy */
|
|
if ( !FSelected(pwi->spb) )
|
|
goto nomark;
|
|
|
|
/*
|
|
* make sure there is something left to copy
|
|
* if the size of the window changed after a selection,
|
|
* If the top of the selected area isn't visible
|
|
* anymore then there's nothing to copy.
|
|
*/
|
|
if (pwi->spb.rectSelect.top >= (int)ui.dwMaxRow)
|
|
goto nomark;
|
|
|
|
if (OpenClipboard(hwnd) == FALSE)
|
|
goto nomark;
|
|
|
|
EmptyClipboard();
|
|
|
|
/*
|
|
* make sure there is something left to copy
|
|
* if the size of the window changed after a selection,
|
|
* check that the bottom of the selection area is still
|
|
* visible. If it isn't then set it to the current
|
|
* window bottom.
|
|
*/
|
|
if (pwi->spb.rectSelect.bottom >= (int)ui.dwMaxRow)
|
|
pwi->spb.rectSelect.bottom = ui.dwMaxRow-1;
|
|
|
|
/* calculate no. of rows and columns to copy */
|
|
cRows = (pwi->spb.rectSelect.bottom+1 - pwi->spb.rectSelect.top);
|
|
cColumns = (pwi->spb.rectSelect.right+1 - pwi->spb.rectSelect.left);
|
|
|
|
/* Don't forget the null-terminator */
|
|
cchNeed = (cRows * cColumns) + 1;
|
|
|
|
/*
|
|
* If more than one line is copied, append CRLFs to all
|
|
* but the last line
|
|
*/
|
|
if (cRows > 1)
|
|
{
|
|
cchNeed += (cRows-1)*2;
|
|
fAppendCRLF = TRUE;
|
|
}
|
|
|
|
hglb = GlobalAlloc(GMEM_DDESHARE, cchNeed);
|
|
if (hglb == NULL)
|
|
goto err;
|
|
|
|
szT = GlobalLock( hglb );
|
|
if (szT == NULL)
|
|
goto err;
|
|
|
|
/*
|
|
* Copy the selected text. If there is more than one line
|
|
* selected, append CRLFs to every line except the last line
|
|
*/
|
|
for (iRow = pwi->spb.rectSelect.top;
|
|
iRow < (pwi->spb.rectSelect.bottom+1); ++iRow)
|
|
{
|
|
cchNeed = cColumns;
|
|
|
|
if (ui.fCursorEdit & fdwTrimEndWhitespace)
|
|
{
|
|
puch = apcRows[iRow]+pwi->spb.rectSelect.left+cchNeed-1;
|
|
for (cchNeed = cColumns; cchNeed > 0; --cchNeed, --puch)
|
|
{
|
|
if (*puch == 0)
|
|
{
|
|
if (*(puch + ui.dwMaxCol) == 0x20)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
else if (*puch == 0x20)
|
|
{
|
|
continue;
|
|
}
|
|
else
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
memcpy(szT, apcRows[iRow]+pwi->spb.rectSelect.left, cchNeed);
|
|
for (ich=0; ich < cchNeed; ++ich, ++szT)
|
|
{
|
|
if (*szT == '\0')
|
|
{
|
|
*szT = apcRows[iRow][pwi->spb.rectSelect.left+ich+ui.dwMaxCol];
|
|
if (*szT == '\0')
|
|
*szT = ' ';
|
|
}
|
|
}
|
|
if ((fAppendCRLF == TRUE) && (iRow < pwi->spb.rectSelect.bottom))
|
|
{
|
|
*szT++ = '\r';
|
|
*szT++ = '\n';
|
|
}
|
|
*szT = '\0';
|
|
}
|
|
|
|
GlobalUnlock( hglb );
|
|
|
|
/* Pass off the text to the clipboard */
|
|
SetClipboardData(CF_TEXT, hglb);
|
|
|
|
hglb = NULL;
|
|
|
|
err:
|
|
if ( hglb )
|
|
{
|
|
if ( szT )
|
|
GlobalUnlock( hglb );
|
|
GlobalFree( hglb );
|
|
}
|
|
CloseClipboard();
|
|
|
|
nomark:
|
|
MarkModeOff( hwnd );
|
|
}
|
|
|
|
void
|
|
DoPaste(HWND hwnd)
|
|
{
|
|
HGLOBAL hglbTextSrc;
|
|
LPSTR szTextSrc;
|
|
LPSTR szDest;
|
|
LPSTR szT;
|
|
|
|
if (IsClipboardFormatAvailable(CF_TEXT) == FALSE)
|
|
return;
|
|
|
|
if (OpenClipboard(hwnd) == FALSE)
|
|
return;
|
|
|
|
if (hglbTextSrc = GetClipboardData(CF_TEXT))
|
|
{
|
|
szDest = (LPSTR)LocalAlloc(LPTR, GlobalSize(hglbTextSrc));
|
|
szTextSrc = GlobalLock( hglbTextSrc );
|
|
|
|
if ((szDest != NULL) && (szTextSrc != NULL))
|
|
{
|
|
szT = szDest;
|
|
|
|
/*
|
|
* Remove the LFs from any CRLFs since
|
|
* we're going to be sending the data
|
|
* to Xenix/Unix machines which wouldn't
|
|
* handle CRLFs as DOS/Win16/Win32 boxes
|
|
*/
|
|
while (*szTextSrc != '\0')
|
|
{
|
|
if (*szTextSrc != '\n')
|
|
{
|
|
*szT++ = *szTextSrc;
|
|
}
|
|
++szTextSrc;
|
|
}
|
|
*szT = '\0';
|
|
|
|
/*
|
|
* The MS machines have a real problem when they
|
|
* get sent a lot of data at once. They seem to
|
|
* want to echo all the data back which really
|
|
* slows things up since they echo the data
|
|
* one character at a time.
|
|
* So I put in a limit of 256 bytes at once.
|
|
* Anything more will get delayed until idle time
|
|
* where the data will be sent one byte at a time
|
|
* if the user so chooses.
|
|
* Hey, it's better than typing the stuff in.
|
|
*/
|
|
if (lstrlen(szDest) < 256)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
|
|
NetBIOSWrite(pwi->nd.SessionNumber,
|
|
(LPSTR)szDest, lstrlen(szDest));
|
|
}
|
|
else if (MessageBox(hwnd, szTooMuchText, szAppName,
|
|
MB_DEFBUTTON2 | MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
|
|
{
|
|
pchTextPaste = szTextPaste = szDest;
|
|
szDest = NULL;
|
|
}
|
|
}
|
|
|
|
if (szDest != NULL)
|
|
LocalFree( szDest );
|
|
if (szTextSrc != NULL)
|
|
GlobalUnlock( hglbTextSrc );
|
|
|
|
/*
|
|
* For Clipboard operations, you're not supposed to free
|
|
* the handle you get back from GetClipboardData()
|
|
* according to the SDK.
|
|
*/
|
|
}
|
|
|
|
CloseClipboard();
|
|
}
|
|
|
|
void
|
|
StopPaste(HWND hwnd)
|
|
{
|
|
if (szTextPaste != NULL)
|
|
{
|
|
WI *pwi = (WI *)GetWindowLong(hwnd, WL_VTPWI);
|
|
|
|
KillTimer(hwnd, uTerminalTimerID);
|
|
pwi->trm.uTimer = SetTimer(hwnd, uTerminalTimerID,
|
|
uCursorBlinkMsecs, NULL);
|
|
LocalFree( szTextPaste );
|
|
szTextPaste = pchTextPaste = NULL;
|
|
}
|
|
}
|
|
|
|
|
|
void
|
|
SetWindowTitle(HWND hwnd, DWORD dwMarkMode, LPSTR szHost)
|
|
{
|
|
char rgch[64];
|
|
|
|
if (dwMarkMode == dwMarkKeyboard)
|
|
lstrcpy(rgch, szMarkMode);
|
|
else if (dwMarkMode == dwMarkMouse)
|
|
lstrcpy(rgch, szMarkModeMouse);
|
|
else
|
|
rgch[0] = '\0';
|
|
|
|
lstrcat(rgch, (szHost) ? szTitleBase : szTitleNone);
|
|
if (szHost != NULL)
|
|
lstrcat(rgch, szHost);
|
|
|
|
SetWindowText(hwnd, rgch);
|
|
}
|
|
|