Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

1066 lines
26 KiB

/* File: D:\WACKER\tdll\sessutil.c (Created: 30-Dec-1993)
*
* Copyright 1994 by Hilgraeve Inc. -- Monroe, MI
* All rights reserved
*
* $Revision: 9 $
* $Date: 7/08/02 6:48p $
*/
#include <windows.h>
#pragma hdrstop
#include <time.h>
#include "features.h"
#include "stdtyp.h"
#include "sf.h"
#include "mc.h"
#include "term.h"
#include "cnct.h"
#include "print.h"
#include "assert.h"
#include "capture.h"
#include "globals.h"
#include "sess_ids.h"
#include "load_res.h"
#include "open_msc.h"
#include "xfer_msc.h"
#include "file_msc.h"
#include "backscrl.h"
#include "cloop.h"
#include "com.h"
#include <term\res.h>
#include "session.h"
#include "session.hh"
#include "errorbox.h"
#include <emu\emu.h>
#include "tdll.h"
#include "htchar.h"
#include "misc.h"
#ifdef INCL_NAG_SCREEN
#include "nagdlg.h"
#endif
STATIC_FUNC void sessPreventOverlap(const HSESSION hSession, BOOL fIsToolbar);
STATIC_FUNC int sessCountMenuLines(HWND hwnd);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessSnapToTermWindow
*
* DESCRIPTION:
* Sizes the session window so that the terminal is full size (usually
* 80 x 24).
*
* ARGUMENTS:
* hwnd - session window handle
*
* RETURNS:
* void
*
*/
void sessSnapToTermWindow(const HWND hwnd)
{
RECT rc;
RECT rc2;
LONG lw;
LONG lh;
LONG l2w;
LONG l2h;
const HSESSION hSession = (HSESSION)GetWindowLongPtr(hwnd, GWLP_USERDATA);
/* --- Doesn't make much sense to snap when we're maximized - mrw --- */
if (IsZoomed(hwnd))
return;
if (sessComputeSnapSize(hSession, &rc))
{
// Make sure we don't go beyond size of screen
// mrw,1/20/95
//
if (SystemParametersInfo(SPI_GETWORKAREA, sizeof(LPRECT), &rc2, 0))
{
lw = rc.right - rc.left;
lh = rc.bottom - rc.top;
l2w = rc2.right - rc2.left;
l2h = rc2.bottom - rc2.top;
GetWindowRect(hwnd, &rc);
// When we first start-up we move the window off screen.
// If we're off screen, we don't do any screen bounds
// checking.
//
if (rc.top > rc2.bottom)
{
SetWindowPos(hwnd, 0, 0, 0, lw, lh, SWP_NOMOVE);
}
else
{
// Calculate new size in desktop coordinates.
//
rc.right = rc.left + lw;
rc.bottom = rc.top + lh;
// Check if too wide
//
if (lw > l2w)
{
rc.left = rc2.left;
rc.right = rc2.right;
}
// Check if to high
//
if (lh > l2h)
{
rc.top = rc2.top;
rc.bottom = rc2.bottom;
}
// Check if we're off to the right
//
if (rc.right > rc2.right)
{
lw = rc.right - rc2.right;
rc.right -= lw;
rc.left -= lw;
}
// Check if we're off the bottom
//
if (rc.bottom > rc2.bottom)
{
lh = rc.bottom - rc2.bottom;
rc.bottom -= lh;
rc.top -= lh;
}
SetWindowPos(hwnd, 0, rc.left, rc.top,
rc.right-rc.left, rc.bottom-rc.top, 0);
}
}
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessSetMinMaxInfo
*
* DESCRIPTION:
* Calculates the max horizontal size for the session and sets that
* value in the mmi structure. If the window is being maximized, then
* we just return. Later, we'll have flags to control autosnapping so
* this function will change. Also some minimum tracking size is set.
*
* ARGUMENTS:
* hSession - public session handle.
* pmmi - pointer to MINMAXINFO structure
*
* RETURNS:
* void
*
*/
void sessSetMinMaxInfo(const HSESSION hSession, const PMINMAXINFO pmmi)
{
RECT rc;
HWND hwndStatusbar, hwndToolbar, hwndSess;
NONCLIENTMETRICS stNCM;
int i, iLineCnt = 0;
/* --- Believe it or not, this gets called before WM_CREATE --- */
if (hSession == (HSESSION)0)
return;
hwndSess = sessQueryHwnd(hSession);
if (IsZoomed(hwndSess))
return;
#if 0 // removed on a trial basis - mrw
if (sessComputeSnapSize(hSession, &rc))
pmmi->ptMaxTrackSize.x = (rc.right - rc.left);
#endif
/* --- Set the minimum height for the session --- */
memset(&rc, 0, sizeof(RECT));
hwndStatusbar = sessQueryHwndStatusbar(hSession);
if (IsWindow(hwndStatusbar) && IsWindowVisible(hwndStatusbar))
{
GetWindowRect(hwndStatusbar, &rc);
pmmi->ptMinTrackSize.y += (rc.bottom - rc.top);
}
memset(&rc, 0, sizeof(RECT));
hwndToolbar = sessQueryHwndToolbar(hSession);
if (IsWindow(hwndToolbar) && IsWindowVisible(hwndToolbar))
{
GetWindowRect(hwndToolbar, &rc);
pmmi->ptMinTrackSize.y += (rc.bottom - rc.top);
}
// Menus take up at least one iMenuHeight...
//
stNCM.cbSize = sizeof(NONCLIENTMETRICS);
if (SystemParametersInfo(SPI_GETNONCLIENTMETRICS,
sizeof(NONCLIENTMETRICS), &stNCM, 0) == TRUE)
{
pmmi->ptMinTrackSize.y += (stNCM.iMenuHeight - 1);
// And if they take up more than that then adjust for it.
//
iLineCnt = sessCountMenuLines(hwndSess);
for (i = 1; i < iLineCnt; i++)
pmmi->ptMinTrackSize.y += (stNCM.iMenuHeight);
DbgOutStr("%i, %i ", stNCM.iMenuHeight, iLineCnt, 0, 0, 0);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessCountMenuLines
*
* DESCRIPTION:
* Counts the lines a menu associated with a window is taking up.
*
* ARGUMENTS:
* hwnd - the window handle.
*
* RETURNS:
* How many lines a menu is taking up.
*
*/
STATIC_FUNC int sessCountMenuLines(HWND hwnd)
{
int i, iLineCnt = 0, iRemembered = 0;
HMENU hMenu;
RECT rc;
hMenu = GetMenu(hwnd);
memset(&rc, 0, sizeof(RECT));
for (i = 0; i < GetMenuItemCount(hMenu); i++)
{
GetMenuItemRect(hwnd, hMenu, (UINT)i, &rc);
if ((int)rc.bottom > iRemembered)
{
iRemembered = (int)rc.bottom;
iLineCnt++;
}
}
return (iLineCnt);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessComputeSnapSize
*
* DESCRIPTION:
* Computes the minimum size of the session window that will display
* the entire terminal screen.
*
* ARGUMENTS:
* hSession - public session handle
* prc - pointer to rectangle that contains minimum size
*
* RETURNS:
* TRUE if success, FALSE contains worthless data
*
*/
BOOL sessComputeSnapSize(const HSESSION hSession, const LPRECT prc)
{
RECT rcTmp;
const HWND hwndTerm = sessQueryHwndTerminal(hSession);
const HWND hwndToolbar = sessQueryHwndToolbar(hSession);
const HWND hwndStatusbar = sessQueryHwndStatusbar(hSession);
const HWND hwndSidebar = sessQuerySidebarHwnd(hSession);
if (IsWindow(hwndTerm) == FALSE)
return FALSE;
/* --- Ask terminal for it's snapped size --- */
SendMessage(hwndTerm, WM_TERM_Q_SNAP, 0, (LPARAM)prc);
/* --- Compute the client window height --- */
if (IsWindow(hwndToolbar) && sessQueryToolbarVisible(hSession))
{
GetWindowRect(hwndToolbar, &rcTmp);
prc->top -= (rcTmp.bottom - rcTmp.top);
}
if (IsWindow(hwndStatusbar) && sessQueryStatusbarVisible(hSession))
{
GetWindowRect(hwndStatusbar, &rcTmp);
prc->bottom += (rcTmp.bottom - rcTmp.top);
}
if (IsWindow(hwndSidebar) && IsWindowVisible(hwndSidebar))
{
GetWindowRect(hwndSidebar, &rcTmp);
prc->right += (rcTmp.right - rcTmp.left);
}
/* --- Compute the necessary frame size --- */
if (AdjustWindowRectEx(prc, WS_OVERLAPPEDWINDOW, TRUE, WS_EX_WINDOWEDGE))
return TRUE;
return FALSE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* NotifyClient
*
* DESCRIPTION:
* Called from the engine thread primarily, this function notifies the
* main thread of some event in the engine, such as new data for the
* terminal to display.
*
* ARGUMENTS:
* hSession - external session handle
* nEvent - event that occured
* lExtra - extra data to pass
*
* RETURNS:
* void
*
*/
void NotifyClient(const HSESSION hSession, const NOTIFICATION nEvent,
const long lExtra)
{
const HHSESSION hhSess = (HHSESSION)hSession;
PostMessage(hhSess->hwndSess, WM_SESS_NOTIFY, (WPARAM)nEvent, lExtra);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void sessInitializeIcons(HSESSION hSession)
{
const HHSESSION hhSess = VerifySessionHandle(hSession);
hhSess->nIconId = IDI_PROG;
hhSess->hIcon = extLoadIcon(MAKEINTRESOURCE(IDI_PROG));
//hhSess->hIcon = LoadIcon(glblQueryDllHinst(),
// MAKEINTRESOURCE(IDI_PROG));
//hhSess->hLittleIcon = LoadIcon(glblQueryDllHinst(),
// MAKEINTRESOURCE(IDI_PROG + IDI_PROG_ICON_CNT));
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void sessLoadIcons(HSESSION hSession)
{
const HHSESSION hhSess = VerifySessionHandle(hSession);
long lSize;
lSize = sizeof(hhSess->nIconId);
sfGetSessionItem(hhSess->hSysFile, SFID_ICON_DEFAULT, &lSize,
&hhSess->nIconId);
hhSess->hIcon = extLoadIcon(MAKEINTRESOURCE(hhSess->nIconId));
//hhSess->hIcon = LoadIcon(glblQueryDllHinst(),
// MAKEINTRESOURCE(hhSess->nIconId));
//hhSess->hLittleIcon = LoadIcon(glblQueryDllHinst(),
// MAKEINTRESOURCE(hhSess->nIconId+IDI_PROG_ICON_CNT));
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
*
* DESCRIPTION:
*
* ARGUMENTS:
*
* RETURNS:
*
*/
void sessSaveIcons(HSESSION hSession)
{
const HHSESSION hhSess = VerifySessionHandle(hSession);
sfPutSessionItem(hhSess->hSysFile, SFID_ICON_DEFAULT,
sizeof(hhSess->nIconId), &hhSess->nIconId);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessSetSuspend
*
* DESCRIPTION:
* We need to block the flow of data going into the emulators which is
* done by suspending the CLoop. Suspending is done for several reasons.
* User presses the scroll lock key. User has pressed left mouse button
* down in preparation for marking (note: user could just let up mouse
* without marking so its a separate reason). User is marking or has
* marked text.
*
* ARGUMENTS:
* hSession - public session handle
* iReason - which event has called this routine
*
* RETURNS:
* void
*
*/
void sessSetSuspend(const HSESSION hSession, const int iReason)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
switch (iReason)
{
case SUSPEND_SCRLCK:
hhSession->fSuspendScrlLck = TRUE;
break;
case SUSPEND_TERMINAL_MARKING:
hhSession->fSuspendTermMarking = TRUE;
break;
case SUSPEND_TERMINAL_LBTNDN:
hhSession->fSuspendTermLBtnDn = TRUE;
break;
case SUSPEND_TERMINAL_COPY:
hhSession->fSuspendTermCopy = TRUE;
break;
default:
assert(FALSE);
return;
}
CLoopRcvControl(sessQueryCLoopHdl(hSession), CLOOP_SUSPEND,
CLOOP_RB_SCRLOCK);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessClearSuspend
*
* DESCRIPTION:
* Clearing suspends is essentially the opposite of setting execept that
* we do not resume cloop processing until all flags are FALSE. Sets
* and clears are not cumulative which is what I first wanted to do but
* particularly in the area's of scroll lock keys and text marking the
* events are not always toggled (ie. might get many marks but only one
* unmark). Also, event can be easily added although none come to mind.
*
* ARGUMENTS:
* hSession - public session handle
* iReason - which event has called this routine
*
* RETURNS:
* void
*
*/
void sessClearSuspend(const HSESSION hSession, const int iReason)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
switch (iReason)
{
case SUSPEND_SCRLCK:
hhSession->fSuspendScrlLck = FALSE;
break;
case SUSPEND_TERMINAL_MARKING:
hhSession->fSuspendTermMarking = FALSE;
break;
case SUSPEND_TERMINAL_LBTNDN:
hhSession->fSuspendTermLBtnDn = FALSE;
break;
case SUSPEND_TERMINAL_COPY:
hhSession->fSuspendTermCopy = FALSE;
break;
default:
assert(FALSE);
return;
}
if (!hhSession->fSuspendScrlLck && !hhSession->fSuspendTermMarking
&& !hhSession->fSuspendTermLBtnDn && !hhSession->fSuspendTermCopy)
{
CLoopRcvControl(sessQueryCLoopHdl(hSession), CLOOP_RESUME,
CLOOP_RB_SCRLOCK);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* IsSessionSuspended
*
* DESCRIPTION:
* Checks if the session is suspended. Suspends occur
* whenever the user is marking text, holds the mouse button down, or
* presses the scroll lock key.
*
* ARGUMENTS:
* hSession - public session handle
*
* RETURNS:
* TRUE if were suspended.
*
*/
BOOL IsSessionSuspended(const HSESSION hSession)
{
const HHSESSION hhSess = VerifySessionHandle(hSession);
return (hhSess->fSuspendScrlLck || hhSess->fSuspendTermMarking ||
hhSess->fSuspendTermLBtnDn || hhSess->fSuspendTermCopy);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessQueryToolbarVisible
*
* DESCRIPTION:
* This function returns the expected visibility state of the Toolbar.
*
* ARGUMENTS:
* hSession -- the session handle
*
* RETURNS:
* The expected visibility state of the Toolbar.
*
*/
BOOL sessQueryToolbarVisible(const HSESSION hSession)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
return hhSession->fToolbarVisible;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessSetToolbarVisible
*
* DESCRIPTION:
* This function changes the expected visibility state of the Toolbar.
* It does not change the actual visibility of the Toolbar.
*
* ARGUMENTS:
* hSession -- the session handle
* fVisible -- indicates visibility as TRUE or FALSE
*
* RETURNS:
* The previous visibility state of the Toolbar.
*
*/
BOOL sessSetToolbarVisible(const HSESSION hSession, const BOOL fVisible)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
BOOL bRet = TRUE;
bRet = hhSession->fToolbarVisible;
hhSession->fToolbarVisible = (fVisible != FALSE);
if (fVisible)
sessPreventOverlap(hSession, TRUE);
ShowWindow(hhSession->hwndToolbar, (fVisible) ? SW_SHOW : SW_HIDE);
return bRet;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessQueryStatusbarVisible
*
* DESCRIPTION:
* This function returns the expected visibility state of the Statusbar.
*
* ARGUMENTS:
* hSession -- the session handle
*
* RETURNS:
* The expected visibility state of the Statusbar.
*
*/
BOOL sessQueryStatusbarVisible(const HSESSION hSession)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
return hhSession->fStatusbarVisible;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessSetStatusbarVisible
*
* DESCRIPTION:
* This function changes the expected visibility state of the Statusbar.
* It does not change the actual visibility of the Statusbar.
*
* ARGUMENTS:
* hSession -- the session handle
* fVisible -- indicates visibility as TRUE or FALSE
*
* RETURNS:
* The previous visibility state of the Statusbar.
*
*/
BOOL sessSetStatusbarVisible(const HSESSION hSession, const BOOL fVisible)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
BOOL bRet = TRUE;
bRet = hhSession->fStatusbarVisible;
hhSession->fStatusbarVisible = (fVisible != FALSE);
if (fVisible)
sessPreventOverlap(hSession, FALSE);
ShowWindow(hhSession->hwndStatusbar, (fVisible) ? SW_SHOW : SW_HIDE);
return bRet;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessCmdLnDial
*
* DESCRIPTION:
* Everytime we open a session, we call this function to attempt to
* dial.
*
*
* ARGUMENTS:
* hSession - public session handle
*
* RETURNS:
* void
*
*/
void sessCmdLnDial(const HSESSION hSession)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
switch (hhSession->iCmdLnDial)
{
case CMDLN_DIAL_DIAL:
cnctConnect(sessQueryCnctHdl(hSession), 0);
break;
case CMDLN_DIAL_NEW:
cnctConnect(sessQueryCnctHdl(hSession), CNCT_NEW);
break;
case CMDLN_DIAL_WINSOCK:
cnctConnect(sessQueryCnctHdl(hSession), CNCT_WINSOCK);
break;
case CMDLN_DIAL_OPEN:
default:
break;
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessUpdateAppTitle
*
* DESCRIPTION:
*
* ARGUMENTS:
* hwnd - app window.
*
* RETURNS:
* void.
*
*/
void sessUpdateAppTitle(const HSESSION hSession)
{
HWND hwnd = sessQueryHwnd(hSession);
TCHAR acTitle[256], acName[256], acNewTitle[256];
#ifdef INCL_NAG_SCREEN
TCHAR acUnregistered[256];
#endif
LPTSTR pNewTitle;
int iSize;
TCHAR *pszSeperator = TEXT(" - ");
BOOL bEval = FALSE;
TCHAR_Fill(acNewTitle, TEXT('\0'), sizeof(acNewTitle) / sizeof(TCHAR));
TCHAR_Fill(acTitle, TEXT('\0'), sizeof(acTitle) / sizeof(TCHAR));
sessQueryName(hSession, acName, sizeof(acName));
if (sessIsSessNameDefault(acName))
{
LoadString(glblQueryDllHinst(), IDS_GNRL_NEW_CNCT, acName,
sizeof(acName) / sizeof(TCHAR));
}
StrCharCopyN(acNewTitle, acName, sizeof(acTitle) / sizeof(TCHAR));
LoadString(glblQueryDllHinst(), IDS_GNRL_APPNAME, acTitle,
sizeof(acTitle) / sizeof(TCHAR));
#ifdef INCL_NAG_SCREEN
if ( IsEval() )
{
bEval = TRUE;
LoadString(glblQueryDllHinst(), IDS_GNRL_UNREGISTERED, acUnregistered,
sizeof(acUnregistered) / sizeof(TCHAR));
}
#endif
iSize = StrCharGetByteCount(acNewTitle);
iSize += StrCharGetByteCount(pszSeperator);
iSize += StrCharGetByteCount(acTitle);
#ifdef INCL_NAG_SCREEN
if ( bEval )
{
iSize += StrCharGetByteCount(acUnregistered);
}
#endif
iSize += sizeof(TCHAR);
pNewTitle = malloc(iSize);
if (pNewTitle)
{
StrCharCopyN(pNewTitle, acNewTitle, iSize);
StrCharCat(pNewTitle, pszSeperator);
StrCharCat(pNewTitle, acTitle);
#ifdef INCL_NAG_SCREEN
if ( bEval )
{
StrCharCat(pNewTitle, acUnregistered);
}
#endif
SetWindowText(hwnd, pNewTitle);
free(pNewTitle);
pNewTitle = NULL;
}
else
{
SetWindowText(hwnd, acNewTitle);
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessDisconnectToContinue
*
* DESCRIPTION:
* If connecterd, ask the user if he wants to disconnect and continue with
* whatever he set out to perform, such as close the app, open a new session,
* create a new connection, etc.
*
* ARGUMENTS:
* hSession - the Session handle.
* hwnd - the session window.
*
* RETURNS:
* TRUE - if the user wants to disconnect and go on with his request.
* FALSE - if he changes his mind.
*
*/
BOOL sessDisconnectToContinue(const HSESSION hSession, HWND hwnd)
{
HCNCT hCnct = (HCNCT)0;
int iRet = 0;
TCHAR ach[256], achTitle[100];
hCnct = sessQueryCnctHdl(hSession);
if (hCnct)
iRet = cnctQueryStatus(hCnct);
if (iRet == CNCT_STATUS_TRUE)
{
LoadString(glblQueryDllHinst(), IDS_GNRL_CNFRM_DCNCT,
ach, sizeof(ach) / sizeof(TCHAR));
LoadString(glblQueryDllHinst(), IDS_MB_TITLE_WARN, achTitle,
sizeof(achTitle) / sizeof(TCHAR));
if ((iRet = TimedMessageBox(hwnd, ach, achTitle,
MB_YESNO | MB_ICONEXCLAMATION, 0)) == IDYES)
{
if (SendMessageTimeout(hwnd, WM_COMMAND, IDM_ACTIONS_HANGUP, 0L,
SMTO_ABORTIFHUNG, 1000, NULL) == 0)
{
PostMessage(hwnd, WM_COMMAND, IDM_ACTIONS_HANGUP, 0L);
}
}
else
return FALSE;
}
return TRUE;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessSizeAndShow
*
* DESCRIPTION:
* Called only once from the InitInstance() this function will size
* the window via snap and insure it lands on the desktop. This
* function is called via a posted message because it was found that
* the session was not fully initialized after returning from the
* CreateWindow call.
*
* ARGUMENTS:
* hwnd - session window.
* nCmdShow - Show command passed from WinMain()
*
* RETURNS:
* void
*
*/
void sessSizeAndShow(const HWND hwnd, const int nCmdShow)
{
HSESSION hSession = (HSESSION)GetWindowLongPtr(hwnd, GWLP_USERDATA);
const HWND hwndBanner = glblQueryHwndBanner();
WINDOWPLACEMENT stWP;
RECT rc, rc2, rc3;
int cx, cy;
int xWA, yWA, cxWA, cyWA;
int iWidth = 0, iHeight = 0;
// Size session window...
//
if (!sessQueryIsNewSession(hSession))
{
// Size and position the session window according to the
// remembered values, if no values were remembered, i.e., an old
// session, then treat it as a default session.
//
memset(&rc, 0, sizeof(RECT));
sessQueryWindowRect(hSession, &rc);
iWidth = rc.right - rc.left;
iHeight = rc.bottom - rc.top;
if (iWidth != 0 && iHeight != 0)
{
stWP.length = sizeof(WINDOWPLACEMENT);
stWP.flags = 0;
stWP.showCmd = (UINT)sessQueryWindowShowCmd(hSession);
memmove(&stWP.rcNormalPosition, &rc, sizeof(RECT));
SetWindowPlacement(hwnd, &stWP);
UpdateWindow(hwnd);
if (IsWindow(hwndBanner))
PostMessage(hwndBanner, WM_CLOSE, 0, 0);
return;
}
}
// Well, were back to our windows tricks. The toolbar height
// has changed with the introduction of the larger bitmaps (from
// 16x16 to 22x24). On program startup, the toolbar window reports
// a default size which is not the correct size since the new bitmaps
// will force it to be larger. This doesn't happen however, until
// the window is displayed. So we display the window off screen,
// do the resizing, then move it back on screen.
GetWindowRect(hwnd, &rc);
SetWindowPos(hwnd, 0, 20000, 20000, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
ShowWindow(hwnd, nCmdShow);
UpdateWindow(hwnd);
// Size to terminal window for a default session, i.e., the user
// did not specify a session name on the command line.
//
sessSnapToTermWindow(hwnd);
// Get new window size but keep original origin
//
GetWindowRect(hwnd, &rc2);
rc.right = rc.left + (rc2.right - rc2.left);
rc.bottom = rc.top + (rc2.bottom - rc2.top);
// Until the SPI parameters are defined
//
if (SystemParametersInfo(SPI_GETWORKAREA, sizeof(LPRECT), &rc3, 0) == TRUE)
{
xWA = rc3.left;
yWA = rc3.top;
cxWA = rc3.right - rc3.left;
cyWA = rc3.bottom - rc3.top;
}
else
{
xWA = 0;
yWA = 0;
cxWA = GetSystemMetrics(SM_CXSCREEN);
cyWA = GetSystemMetrics(SM_CYSCREEN);
}
cx = rc.left;
cy = rc.top;
if (rc.right > (xWA + cxWA))
cx = max(xWA, rc.left - (rc.right - (xWA + cxWA)));
if (rc.bottom > (yWA + cyWA))
cy = max(yWA, rc.top - (rc.bottom - (yWA + cyWA)));
// Move window back to either its original or adjusted position.
//
SetWindowPos(hwnd, 0, cx, cy, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
UpdateWindow(hwnd);
if (IsWindow(hwndBanner))
PostMessage(hwndBanner, WM_CLOSE, 0, 0);
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessPreventOverlap
*
* DESCRIPTION:
* The main purpose for existance of this function is to prevent the toolbar
* window and the status window overlapping each other. That is accomplished
* by sizing the session window to be big enough to display both of the
* windows comfortably.
*
* ARGUMENTS:
* hSession - the session handle.
* fIsToolbar - TRUE if we showing the toolbar window, FALSE otherwise.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sessPreventOverlap(const HSESSION hSession, BOOL fIsToolbar)
{
const HHSESSION hhSession = VerifySessionHandle(hSession);
RECT rcSess, rcTool, rcStat;
if ((fIsToolbar) ? hhSession->fStatusbarVisible :
hhSession->fToolbarVisible)
{
GetWindowRect(hhSession->hwndSess, &rcSess);
GetWindowRect(hhSession->hwndToolbar, &rcTool);
GetWindowRect(hhSession->hwndStatusbar, &rcStat);
if (rcTool.bottom > rcStat.top)
{
SetWindowPos(hhSession->hwndSess, 0,
0, 0, rcSess.right - rcSess.left,
(rcSess.bottom - rcSess.top) + (rcTool.bottom - rcStat.top),
SWP_NOMOVE | SWP_NOZORDER);
}
}
}
#if defined(DEADWOOD)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* DoBeeper
*
* DESCRIPTION:
* Produces three audible beeps in sequence
*
* ARGUMENTS:
* dw - required by CreateThread()
*
* RETURNS:
* DWORD - required by CreateThread
*
*/
DWORD WINAPI DoBeeper(DWORD dw)
{
//mpt:06-04-98 changed to use windows sounds
MessageBeep(MB_ICONEXCLAMATION);
#if 0
int i;
for (i = 0 ; i < 3 ; ++i)
{
MessageBeep((unsigned)-1);
Sleep(300);
}
#endif
return 0;
}
#endif // defined(DEADWOOD)
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sessBeeper
*
* DESCRIPTION:
* Launches thread to do beeps if session setting is on. Seems silly
* to launch a thread to do something like this but it really is the
* simplist and most direct way. - mrw
*
* ARGUMENTS:
* hSession - public session handle
*
* RETURNS:
* void
*
*/
void sessBeeper(const HSESSION hSession)
{
if (sessQuerySound(hSession))
{
#if defined(DEADWOOD)
DWORD dwID;
if (CreateThread(0, 100, (LPTHREAD_START_ROUTINE)DoBeeper, 0, 0,
&dwID) == 0)
#else // defined(DEADWOOD)
if(mscMessageBeep(MB_ICONEXCLAMATION) == FALSE)
#endif // defined(DEADWOOD)
{
DbgShowLastError();
}
}
return;
}