📄 connect.c
字号:
// UpdateWindow(hwnd);
// }
// break;
case WM_CHAR:
if (wParam == ' ') {
if (pClientData != NULL) {
if (!pClientData->wantsInput) {
goto spacebarOn;
} else {
goto spacebarOff;
}
}
}
return 0;
case WM_CLOSE:
/* Mark the window closed at the request of the user.
We set the "Lazarus timer" running which prevents
the connection being remotely re-opened until the
timer expires. */
if (pClientData != NULL) {
Lazarus = pClientData->inetSock.sin_addr.s_addr;
LazarusLong = LazarusLength;
}
FORWARD_WM_CLOSE(hwnd, DefMDIChildProc);
return 0;
case WM_CREATE:
#ifdef TRACE_FACE
OutputDebugString("Connection WM_CREATE()\r\n");
#endif
SetFocus(hwnd);
break;
case WM_DESTROY:
if (pClientData != NULL) {
SendMessage(hwnd, WM_CLEAN_UP_YOUR_ACT, 0, 0L);
}
return 0;
case WM_CLEAN_UP_YOUR_ACT:
if (pClientData != NULL) {
if (pClientData->wantsInput && --listeners <= 0) {
terminateWaveInput();
inputPaused = FALSE;
listeners = 0;
}
gsm_destroy(pClientData->gsmh);
if (pClientData->hFile != HFILE_ERROR ||
pClientData->mmioHandle != NULL) {
KillTimer(hwnd, 2);
if (pClientData->hFile != HFILE_ERROR) {
_lclose(pClientData->hFile);
}
readWaveTerm(pClientData);
}
if (pClientData->pgpFileName[0] != 0) {
KillTimer(hwnd, 3); // Kill timer for incomplete PGP poll
// T'would be nice to clean up the temp files here as well.
}
if (pClientData->opgpFileName[0] != 0) {
KillTimer(hwnd, 4); // Kill timer for incomplete PGP poll
// T'would be nice to clean up the temp files here as well.
}
if (pClientData->face_stat == FSrequest ||
pClientData->face_stat == FSreply) {
KillTimer(hwnd, 5); // Kill timer for incomplete face image
}
if (pClientData->face_bmp != NULL) {
GlobalFreePtr(pClientData->face_bmp); // Release face bitmap
}
/* If we're transmitting in RTP or VAT protocol, send a
Bye/Done message to indicate the connection's been
closed. */
if (pClientData->sControl != INVALID_SOCKET) {
unsigned char byebye[128];
int byel;
pClientData->sendSDEStimer = TIMEOUT_RESEND_SDES;
if (protocolSent == PROTOCOL_RTP || protocolSent == PROTOCOL_SPEAKFREE) {
byel = rtp_make_bye(byebye, ssrc, rstring(IDS_T_RAISON_CLOSING), TRUE);
if (protocolSent == PROTOCOL_SPEAKFREE) {
byebye[0] = (byebye[0] & 0x3F) | (1 << 6);
}
} else {
byel = makevatdone(byebye, 0L);
}
if (!((protocolSent == PROTOCOL_SPEAKFREE) && waProtNoHeartbeat)) {
sendSessionCtrl(pClientData, byebye, byel);
}
}
if (pClientData->sReply != INVALID_SOCKET) {
ResetSocket(pClientData->sReply);
pClientData->sReply = INVALID_SOCKET;
}
if (pClientData->sControl != INVALID_SOCKET) {
LINGER linger;
/* Enable linger with a timeout of one second. This
should, in theory, allow the BYE message to go out
before the socket is closed. Why not use the
"graceful disconnect" mechanism? Because there are
WINSOCKs out there that don't do it right. */
linger.l_onoff = TRUE;
linger.l_linger = 1;
setsockopt(pClientData->sControl, SOL_SOCKET, SO_LINGER, (CHAR FAR *) &linger, sizeof(linger));
closesocket(pClientData->sControl);
pClientData->sControl = INVALID_SOCKET;
}
/* If we're listening on a nonstandard channel, decrement
the reference count on the auxiliary socket pair and
close if it's zero. */
if (pClientData->auxSock != NULL) {
if (--pClientData->auxSock->asrefc == 0) {
#ifdef TRACE_AUX_SOCKET
OutputDebugString("Closing aux socket.\r\n");
#endif
ResetSocket(pClientData->auxSock->asdata);
pClientData->auxSock->asdata = INVALID_SOCKET;
ResetSocket(pClientData->auxSock->asctrl);
pClientData->auxSock->asctrl = INVALID_SOCKET;
}
}
if (pClientData->hFile != HFILE_ERROR) {
_lclose(pClientData->hFile);
pClientData->hFile = HFILE_ERROR;
}
#ifdef MODEM
if (pClientData->modemConnection) {
modemSessions--;
}
#endif
if (pClientData->getNameTask != NULL) {
WSACancelAsyncRequest(pClientData->getNameTask);
pClientData->getNameTask = NULL;
}
if (pClientData->uname != NULL) {
GlobalFreePtr(pClientData->uname);
pClientData->uname = NULL;
}
loop_flush(pClientData); // Flush any queued local loopback data
GlobalFreePtr(pClientData);
SetWindowLong(hwnd, GWL_CLIENT, 0L);
openConnections--;
propUpdateAudio();
}
return 0;
case WM_DROPFILES:
if (pClientData != NULL && !broadcasting)
{
pClientData->timeout = -1; // Send file immortalises connection
fileDropped(hwnd, (HDROP) wParam);
}
break;
#ifdef GATES_OF_HELL
/* Well, golly, I though it would be kinda nice to keep
the user from inflating the connection window larger than
the face image in it--doing so only wastes screen
real estate, after all. Little did I know that by trying
to do so (at least with an MDI window), I stuck my toe
back into the tree chipper and caused all kinds of
things to let go--window size changing when iconised
and reactivated, the "disappearing minimise button
syndrome", etc. etc. The Developer CD serves up the
usual crop of incoherent blithering. I give up--go
ahead and make the bloody window as big as Siberia
if you like. */
case WM_GETMINMAXINFO:
if (pClientData != NULL && pClientData->face_shown) {
MINMAXINFO FAR *mm = (MINMAXINFO FAR *) lParam;
BITMAPINFOHEADER FAR *bmi;
RECT cr, wr;
GetWindowRect(hwnd, &wr);
GetClientRect(hwnd, &cr);
bmi = (BITMAPINFOHEADER FAR *) (pClientData->face_bmp + sizeof(BITMAPFILEHEADER));
// Don't allow resize of window larger than face
mm->ptMaxSize.x = mm->ptMaxTrackSize.x = ((int) bmi->biWidth) + ((wr.right - wr.left) - cr.right);
mm->ptMaxSize.x = mm->ptMaxTrackSize.y = ((int) bmi->biHeight) + ((wr.bottom - wr.top) - cr.bottom);
}
break;
#endif
case WM_LBUTTONDBLCLK:
if (pClientData != NULL && pClientData->wantsInput == TRUE) {
pClientData->wantsInput = 2;
if (pClientData->buttonUpTimer) {
KillTimer(hwnd, 8);
pClientData->buttonUpTimer = FALSE;
}
break;
}
case WM_LBUTTONDOWN:
spacebarOn: if (pClientData != NULL && !pClientData->wantsInput && !broadcasting && !bConferencing)
{
if (listeners == 0) {
inputPaused = FALSE;
if (!startWaveInput(hwnd)) {
// Couldn't turn on wave audio input
break;
}
}
if (pClientData->buttonUpTimer) {
KillTimer(hwnd, 8);
pClientData->buttonUpTimer = FALSE;
}
spurt = TRUE; // Mark start of talk spurt
loop_flush(pClientData); // Flush any unplayed local loop packets
pClientData->wantsInput = (nMessage == WM_LBUTTONDBLCLK) ? 2 : TRUE;
listeners++;
pClientData->timeout = -1; // Send audio immortalises connection
pClientData->state = SendingLiveAudio;
SetCursor(earCursor);
changeAudioState(hwnd, pClientData);
}
break;
case WM_LBUTTONUP:
if (pClientData != NULL && !broadcasting && !bConferencing && !pClientData->buttonUpTimer)
{
SetTimer(hwnd, 8, GetDoubleClickTime(), NULL);
pClientData->buttonUpTimer = TRUE;
break;
}
spacebarOff:if (pClientData != NULL && !broadcasting && !bConferencing)
{
if (pClientData->wantsInput == TRUE) {
pClientData->wantsInput = FALSE;
pClientData->state = pClientData->hFile != HFILE_ERROR ?
Transferring : Idle;
SetCursor(phoneCursor);
changeAudioState(hwnd, pClientData);
if (--listeners <= 0) {
terminateWaveInput();
inputPaused = FALSE;
listeners = 0;
}
/* If this the button-up following a double click, don't
turn off listening. This allows a double click to latch
input mode for a window. */
} else if (pClientData->wantsInput == 2) {
pClientData->wantsInput = TRUE;
if (pClientData->buttonUpTimer) {
pClientData->buttonUpTimer = FALSE;
KillTimer(hwnd, 8);
}
SetCursor(earCursor);
UpdateWindow(hwnd);
}
}
break;
case WM_MOUSEMOVE:
if (pClientData != NULL) {
SetCursor((pClientData->wantsInput || broadcasting || bConferencing) ?
(squelched ? boltCursor : earCursor) :
phoneCursor);
}
break;
case WM_PAINT:
{
#define DCOL 11
PAINTSTRUCT psPaint;
HDC hdc;
HBITMAP ibmap = NULL;
int active = hwnd == ((HWND) LOWORD(SendMessage(hwndMDIClient, WM_MDIGETACTIVE, 0, 0L))),
resized = FALSE;
hdc = BeginPaint(hwnd, &psPaint);
if (pClientData != NULL) {
if (pClientData->face_stat == FScomplete &&
pClientData->face_bmp != NULL) {
int bx, by;
RECT cr, wr;
BITMAPFILEHEADER FAR *bfh;
BITMAPINFOHEADER FAR *bmi;
char _huge *bits;
HPALETTE bpal = NULL, opal;
int i;
LPLOGPALETTE lp;
BITMAPINFO FAR *bh;
unsigned short FAR *palidx;
LPSTR lpalette;
unsigned short FAR *savepal;
#ifdef TRACE_FACE
{ char s[256];
wsprintf(s, "Paint %04X: %s\r\n", hwnd, pClientData->szHost);
OutputDebugString(s);
}
#endif
pClientData->face_shown = FALSE;
savepal = (unsigned short FAR *) GlobalAllocPtr(GPTR,
sizeof(LOGPALETTE) +
sizeof(PALETTEENTRY) * 256 +
sizeof(short) * 256);
if (savepal == NULL) {
goto face_failed;
}
lpalette = ((LPSTR) savepal) + 256 * sizeof(short);
GetWindowRect(hwnd, &wr);
GetClientRect(hwnd, &cr);
bfh = (BITMAPFILEHEADER FAR *) pClientData->face_bmp;
bmi = (BITMAPINFOHEADER FAR *) (pClientData->face_bmp + sizeof(BITMAPFILEHEADER));
bh = (BITMAPINFO FAR *) bmi;
bx = (int) bmi->biWidth;
by = (int) bmi->biHeight;
if (bmi->biClrUsed == 0) {
bmi->biClrUsed = 1L << bmi->biBitCount;
}
bits = (char FAR *) (pClientData->face_bmp + bfh->bfOffBits);
lp = (LOGPALETTE FAR *) lpalette;
palidx = (unsigned short FAR *) bh->bmiColors;
_fmemcpy(savepal, palidx, 256 * sizeof(short));
lp->palVersion = 0x0300;
lp->palNumEntries = (WORD) bmi->biClrUsed;
for (i = 0; i < ((int) bmi->biClrUsed); i++) {
lp->palPalEntry[i].peRed = bh->bmiColors[i].rgbRed;
lp->palPalEntry[i].peGreen = bh->bmiColors[i].rgbGreen;
lp->palPalEntry[i].peBlue = bh->bmiColors[i].rgbBlue;
lp->palPalEntry[i].peFlags = PC_NOCOLLAPSE;
// if (active) {
// palidx[i] = (unsigned short) i;
// }
}
bpal = CreatePalette(lp);
if (active && bpal != NULL) {
opal = SelectPalette(hdc, bpal, FALSE);
RealizePalette(hdc);
}
ibmap = CreateDIBitmap(hdc, bmi, CBM_INIT,
bits, (BITMAPINFO FAR *) bmi, DIB_RGB_COLORS);
_fmemcpy(palidx, savepal, 256 * sizeof(short));
if (ibmap != NULL) {
HDC hMemDC;
HBITMAP obmap;
HPALETTE mopal;
hMemDC = CreateCompatibleDC(hdc);
if (bpal != NULL) {
mopal = SelectPalette(hMemDC, bpal, FALSE);
}
obmap = SelectObject(hMemDC, ibmap);
if (bx <= cr.right && by <= cr.bottom) {
BitBlt(hdc, (cr.right - bx) / 2, (cr.bottom - by) / 2,
bx, by, hMemDC, 0, 0, SRCCOPY);
} else {
int nx, ny;
double xshrink = ((double) bx) / cr.right,
yshrink = ((double) by) / cr.bottom;
#ifdef TRACE_FACE
OutputDebugString("Yick!!! Had to stretch face bitmap.\r\n");
#endif
if (xshrink > yshrink) {
nx = cr.right;
ny = (int) (by / xshrink);
} else {
ny = cr.bottom;
nx = (int) (bx / yshrink);
}
SetStretchBltMode(hdc, STRETCH_DELETESCANS);
StretchBlt(hdc, (cr.right - nx) / 2, (cr.bottom - ny) / 2, nx, ny,
hMemDC, 0, 0, bx, by, SRCCOPY);
}
SelectObject(hMemDC, obmap);
DeleteObject(ibmap);
if (bpal != NULL) {
if (active) {
SelectPalette(hdc, opal, FALSE);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -