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.
 
 
 
 
 
 

1382 lines
34 KiB

/* File: D:\WACKER\tdll\statusbr.c (Created: 02-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 <commctrl.h>
#include <time.h>
#include <term\res.h>
#include "assert.h"
#include "stdtyp.h"
#include "session.h"
#include "globals.h"
#include "statusbr.h"
#include "cnct.h"
#include "capture.h"
#include "print.h"
#include "tdll.h"
#include "htchar.h"
#include "mc.h"
#include "load_res.h"
#include "timers.h"
#include "com.h"
#include <emu\emuid.h>
#include <emu\emu.h>
#include <emu\emudlgs.h>
#include <xfer\itime.h>
// Static function prototypes...
//
STATIC_FUNC void sbrSubclassStatusbarWindow(HWND hwnd, HSESSION hSession);
STATIC_FUNC void sbrCnctStatus (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrSetToNoParts (const HWND hwnd, LPTSTR pszStr);
STATIC_FUNC void sbrRefresh (const HWND hwnd, const int iPart, const pSBR pSBRData);
STATIC_FUNC BOOL sbrNeedToSetParts (const HWND hwnd);
STATIC_FUNC void sbrSetParts (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrTimerRefresh (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrDrawCnctPart (const HWND hwnd, const int iCnctStatus,
LPTSTR pszStr);
STATIC_FUNC void sbrSetPartsOnce (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC int sbrGetSizeInPixels (const HWND hwnd, LPTSTR pszStr);
STATIC_FUNC int sbrCalcPartSize (const HWND hwnd, const int iId);
STATIC_FUNC void sbrCachString (pSBR pSBRData,
unsigned int iPart,
LPTSTR pach);
STATIC_FUNC BOOL sbrCnctTimeToSystemTime(const HWND hwnd,
LPSYSTEMTIME lpSysTime,
const pSBR pSBRData);
STATIC_FUNC void sbrEmulatorName (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrScrolLock (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrCapsLock (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrNumLock (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrCapture (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrPrintEcho (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC BOOL sbrCreateTimer (const HWND hwnd, const pSBR pSBRData);
STATIC_FUNC void sbrCom (const HWND hwnd, const pSBR pSBRData);
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCreateSessionStatusbar
*
* DESCRIPTION:
* Not much now but will get more complicated later.
*
* ARGUMENTS:
* hwndSession - session window handle
*
* RETURNS:
* Handle to status window or zero on error.
*
*/
HWND sbrCreateSessionStatusbar(HSESSION hSession)
{
HWND hwnd = (HWND)0;
//int aBorders[3];
HDC hDC;
TEXTMETRIC tm;
HWND hwndSession = (HWND)0;
hwndSession = sessQueryHwnd(hSession);
if (!IsWindow(hwndSession))
return (HWND)0;
hwnd = CreateStatusWindow(WS_CHILD | WS_CLIPSIBLINGS | SBARS_SIZEGRIP,
0,
hwndSession,
IDC_STATUS_WIN);
if (IsWindow(hwnd))
{
#if 0
aBorders[0] = WINDOWSBORDERWIDTH;
aBorders[1] = WINDOWSBORDERHEIGHT;
aBorders[2] = WINDOWSBORDERWIDTH;
SendMessage(hwnd, SB_SETBORDERS, 0, (LPARAM)aBorders);
#endif
hDC = GetDC(hwnd);
GetTextMetrics(hDC, &tm);
ReleaseDC(hwnd, hDC);
SendMessage(hwnd, SB_SETMINHEIGHT, (WPARAM)tm.tmHeight, 0);
ShowWindow(hwnd, SW_SHOWNA);
sbrSubclassStatusbarWindow(hwnd, hSession);
}
return hwnd;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrSubclassStatusbarWindow
*
* DESCRIPTION:
* Subclass the Status Bar and init the data structure.
*
* ARGUMENTS:
* hwnd - window handle.
* hSession - the session handle.
*
* RETURNS:
*
*/
STATIC_FUNC void sbrSubclassStatusbarWindow(HWND hwnd, HSESSION hSession)
{
ATOM atom = (ATOM)0;
pSBR pSBRData;
atom = AddAtom((LPCTSTR)SBR_ATOM_NAME);
if (atom == 0)
{
assert(FALSE);
return;
}
pSBRData = (pSBR)LocalAlloc(LPTR, sizeof(SBR));
if (pSBRData == NULL)
{
assert(FALSE);
return;
}
// Initialize statusbar data structure...
//
pSBRData->hSession = hSession;
pSBRData->hwnd = hwnd;
pSBRData->hTimer = (HTIMER)0;
pSBRData->pachCNCT = (LPTSTR)0;
pSBRData->pachCAPL = (LPTSTR)0;
pSBRData->pachNUML = (LPTSTR)0;
pSBRData->pachSCRL = (LPTSTR)0;
pSBRData->pachCAPT = (LPTSTR)0;
pSBRData->pachPECHO = (LPTSTR)0;
// Do the subclass...
//
pSBRData->wpOrigStatusbarWndProc =
(WNDPROC)SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)sbrWndProc);
SetProp(hwnd, (LPCTSTR)atom, (HANDLE)pSBRData);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrWndProc
*
* DESCRIPTION:
* Our own statusbar window proc.
*
* ARGUMENTS:
* Standard window proc parameters.
*
* RETURNS:
* Standard return value.
*
*/
LRESULT APIENTRY sbrWndProc(HWND hwnd, UINT uMsg, WPARAM wPar, LPARAM lPar)
{
ATOM atom = (ATOM)0;
pSBR pSBRData;
int nRet;
LRESULT lpResult = 0;
atom = FindAtom((LPCTSTR)SBR_ATOM_NAME);
pSBRData = (pSBR)GetProp(hwnd, (LPCTSTR)atom);
if (pSBRData != NULL && IsWindow(hwnd))
{
switch (uMsg)
{
case SBR_NTFY_INITIALIZE:
sbrCreateTimer(hwnd, pSBRData);
sbrSetPartsOnce(hwnd, pSBRData);
sbrRefresh(hwnd, SBR_MAX_PARTS, pSBRData);
break;
case SBR_NTFY_REFRESH:
if (IsWindowVisible(hwnd))
sbrRefresh(hwnd, LOWORD(wPar), pSBRData);
/* Fall through */
case SBR_NTFY_TIMER:
if (IsWindowVisible(hwnd) && !sbrNeedToSetParts(hwnd))
sbrTimerRefresh(hwnd, pSBRData);
return 0;
case SBR_NTFY_NOPARTS:
if (IsWindowVisible(hwnd))
sbrSetToNoParts(hwnd, (LPTSTR)lPar);
return 0;
case WM_DESTROY:
if (atom)
{
RemoveProp(hwnd, (LPCTSTR)atom);
DeleteAtom(atom);
atom = (ATOM)0;
}
// Remove subclass from the statusbar window
//
SetWindowLongPtr(hwnd, GWLP_WNDPROC, (LONG_PTR)pSBRData->wpOrigStatusbarWndProc);
// Destroy the timer...
//
if (pSBRData->hTimer)
{
nRet = TimerDestroy(&pSBRData->hTimer);
assert(nRet == TIMER_OK);
}
if (pSBRData->pachCNCT)
{
free(pSBRData->pachCNCT);
pSBRData->pachCNCT = NULL;
}
if (pSBRData->pachCAPL)
{
free(pSBRData->pachCAPL);
pSBRData->pachCAPL = NULL;
}
if (pSBRData->pachNUML)
{
free(pSBRData->pachNUML);
pSBRData->pachNUML = NULL;
}
if (pSBRData->pachSCRL)
{
free(pSBRData->pachSCRL);
pSBRData->pachSCRL = NULL;
}
if (pSBRData->pachCAPT)
{
free(pSBRData->pachCAPT);
pSBRData->pachCAPT = NULL;
}
if (pSBRData->pachPECHO)
{
free(pSBRData->pachPECHO);
pSBRData->pachPECHO = NULL;
}
LocalFree(pSBRData);
pSBRData = NULL;
default:
break;
}
}
if (pSBRData != NULL)
{
lpResult = CallWindowProc(pSBRData->wpOrigStatusbarWndProc,
hwnd, uMsg, wPar, lPar);
}
return lpResult;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrSetToNoParts
*
* DESCRIPTION:
* Show status bar with no parts. This is usefull in showing help for
* menu items on the statusbar.
*
* ARGUMENTS:
* hwnd - window handle.
* pszStr - text to display on the status bar.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrSetToNoParts(const HWND hwnd, LPTSTR pszStr)
{
if (IsWindow(hwnd))
{
int aWidths[1];
aWidths[0] = -1;
SendMessage(hwnd, SB_SETPARTS, (WPARAM)1, (LPARAM)aWidths);
SendMessage(hwnd, SB_SETTEXT, 0, (LPARAM)pszStr);
ShowWindow(hwnd, SW_SHOWNA);
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrRefresh
*
* DESCRIPTION:
* Figure out what has changed and display status info appropriately.
*
* ARGUMENTS:
* hwnd - window handle.
* iPart - a part number for a part we want to explicitly refresh.
* It can be SBR_MAX_PARTS, in which case all parts are refreshed and
* it can be SBR_KEY_PARTS, in which case all KEY parts are refreshed.
* In some cases it makes sense to just refresh only one part instead
* of refreshing all of them.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrRefresh(const HWND hwnd, const int iPart, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
// Make sure we are displaying the correct # of parts
//
if (sbrNeedToSetParts(hwnd))
sbrSetParts(hwnd, pSBRData);
switch (iPart)
{
case SBR_KEY_PARTS:
sbrScrolLock(hwnd, pSBRData);
sbrCapsLock(hwnd, pSBRData);
sbrNumLock(hwnd, pSBRData);
break;
case SBR_CNCT_PART_NO:
sbrCnctStatus(hwnd, pSBRData);
break;
case SBR_EMU_PART_NO:
sbrEmulatorName(hwnd, pSBRData);
break;
case SBR_COM_PART_NO:
sbrCom(hwnd, pSBRData);
break;
case SBR_SCRL_PART_NO:
sbrScrolLock(hwnd, pSBRData);
break;
case SBR_CAPL_PART_NO:
sbrCapsLock(hwnd, pSBRData);
break;
case SBR_NUML_PART_NO:
sbrNumLock(hwnd, pSBRData);
break;
case SBR_CAPT_PART_NO:
sbrCapture(hwnd, pSBRData);
break;
case SBR_PRNE_PART_NO:
sbrPrintEcho(hwnd, pSBRData);
break;
default:
sbrCnctStatus(hwnd, pSBRData);
sbrEmulatorName(hwnd, pSBRData);
sbrCom(hwnd, pSBRData);
sbrScrolLock(hwnd, pSBRData);
sbrCapsLock(hwnd, pSBRData);
sbrNumLock(hwnd, pSBRData);
sbrCapture(hwnd, pSBRData);
sbrPrintEcho(hwnd, pSBRData);
break;
}
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrNeedToSetParts
*
* DESCRIPTION:
* Check the number of parts shown in the status bar. If it is less then
* expected, i.e., the maximum parts we usually show, then we need to reset
* the status bar parts. This happens, for example, when help text is
* displayed for menu items, i.e., parts are set to 0.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* TRUE if parts need to be set/re-set.
* FALSE otherwise.
*
*/
STATIC_FUNC BOOL sbrNeedToSetParts(const HWND hwnd)
{
BOOL bRet = FALSE;
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && IsWindow(hwnd))
{
int nParts = 0;
int aWidths[SBR_MAX_PARTS+1];
memset(aWidths, 0, (SBR_MAX_PARTS+1) * sizeof(int));
nParts = (int)SendMessage(hwnd, SB_GETPARTS, (WPARAM)SBR_MAX_PARTS+1,
(LPARAM)aWidths);
if (nParts != SBR_MAX_PARTS)
{
bRet = TRUE;
}
}
return bRet;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrSetParts
*
* DESCRIPTION:
* Set parts in the statusbar.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrSetParts(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
SendMessage(hwnd, SB_SETPARTS, (WPARAM)SBR_MAX_PARTS,
(LPARAM)pSBRData->aWidths);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrSetPartsOnce
*
* DESCRIPTION:
* Set parts in the statusbar according to the length of strings to be
* displayed in the appropriate parts. This function should be called only
* once to figure out the part lengths, from then on the part rigth edges are
* stored in the statusbar data structure.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void
*/
STATIC_FUNC void sbrSetPartsOnce(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
int aWidths[SBR_MAX_PARTS] = {1, 1, 1, 1, 1, 1, 1, 1};
int iNewWidth = 0, i;
TCHAR ach[256];
unsigned int iPart = 0;
int aiBorders[3];
// To make sure that we always have enough space to display the text
// in the appropriate statusbar part read the text corresponding to each
// part and check its length, adjust the size of the part if needed.
//
for (i = 0; i < SBR_MAX_PARTS; i++)
{
switch (i)
{
default:
case SBR_CNCT_PART_NO:
case SBR_EMU_PART_NO:
iNewWidth = sbrCalcPartSize(hwnd, i);
break;
case SBR_COM_PART_NO: iPart = IDS_STATUSBR_COM; break;
case SBR_SCRL_PART_NO: iPart = IDS_STATUSBR_SCRL; break;
case SBR_CAPL_PART_NO: iPart = IDS_STATUSBR_CAPL; break;
case SBR_NUML_PART_NO: iPart = IDS_STATUSBR_NUML; break;
case SBR_CAPT_PART_NO: iPart = IDS_STATUSBR_CAPTUREON; break;
case SBR_PRNE_PART_NO: iPart = IDS_STATUSBR_PRINTECHOON; break;
}
if (i != SBR_CNCT_PART_NO && i != SBR_EMU_PART_NO)
{
// Get the width for the current part string...
//
iNewWidth = 0;
LoadString(glblQueryDllHinst(), iPart, ach,
sizeof(ach) / sizeof(TCHAR));
sbrCachString(pSBRData, iPart, ach);
iNewWidth = (int)sbrGetSizeInPixels(hwnd, ach);
}
aWidths[i] = iNewWidth;
}
// When computing widths, we need to take the borders into account.
//
memset(aiBorders, 0, sizeof(aiBorders));
SendMessage(hwnd, SB_GETBORDERS, 0, (LPARAM)aiBorders);
// Calculate right edges of the statusbar parts...
// put them back into aWidths.
//
aWidths[0] += aiBorders[1];
for (i = 1; i < SBR_MAX_PARTS; i++)
aWidths[i] += aWidths[i-1] + aiBorders[2];
MemCopy(pSBRData->aWidths, aWidths, SBR_MAX_PARTS * sizeof(int));
SendMessage(hwnd, SB_SETPARTS, (WPARAM)SBR_MAX_PARTS,
(LPARAM)pSBRData->aWidths);
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCachString
*
* DESCRIPTION:
* Save the string we've just loaded from the resource file in our internal
* statusbar structure for future use. This way we minimize the
* LoadStirng() calls.
*
* ARGUMENTS:
* pSBRData - handle to internal structure.
* iPart - part identifier.
* pach - label for that part.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrCachString(pSBR pSBRData, unsigned int iPart, LPTSTR pach)
{
unsigned int pachSize;
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL)
{
pachSize = (StrCharGetByteCount(pach) + 1) * sizeof(TCHAR);
switch (iPart)
{
case IDS_STATUSBR_CONNECT_FORMAT:
if (pSBRData->pachCNCT)
{
free(pSBRData->pachCNCT);
pSBRData->pachCNCT = NULL;
}
pSBRData->pachCNCT = malloc(pachSize);
StrCharCopyN(pSBRData->pachCNCT, pach, pachSize);
break;
case IDS_STATUSBR_SCRL:
if (pSBRData->pachSCRL)
{
free(pSBRData->pachSCRL);
pSBRData->pachSCRL = NULL;
}
pSBRData->pachSCRL = malloc(pachSize);
StrCharCopyN(pSBRData->pachSCRL, pach, pachSize);
break;
case IDS_STATUSBR_CAPL:
if (pSBRData->pachCAPL)
{
free(pSBRData->pachCAPL);
pSBRData->pachCAPL = NULL;
}
pSBRData->pachCAPL = malloc(pachSize);
StrCharCopyN(pSBRData->pachCAPL, pach, pachSize);
break;
case IDS_STATUSBR_NUML:
if (pSBRData->pachNUML)
{
free(pSBRData->pachNUML);
pSBRData->pachNUML = NULL;
}
pSBRData->pachNUML = malloc(pachSize);
StrCharCopyN(pSBRData->pachNUML, pach, pachSize);
break;
case IDS_STATUSBR_CAPTUREON:
if (pSBRData->pachCAPT)
{
free(pSBRData->pachCAPT);
pSBRData->pachCAPT = NULL;
}
pSBRData->pachCAPT = malloc(pachSize);
StrCharCopyN(pSBRData->pachCAPT, pach, pachSize);
break;
case IDS_STATUSBR_PRINTECHOON:
if (pSBRData->pachPECHO)
{
free(pSBRData->pachPECHO);
pSBRData->pachPECHO = NULL;
}
pSBRData->pachPECHO = malloc(pachSize);
StrCharCopyN(pSBRData->pachPECHO, pach, pachSize);
break;
default:
break;
}
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrGetSizeInPixels
*
* DESCRIPTION:
* Caluclate the length of the string in pixels. Adjust the
* length by some extra space to appear on the right of the string in the
* statusbar part.
*
* ARGUMENTS:
* hwnd - window handle.
* pszStr - pointer to a string.
*
* RETURNS:
* sz.cx - the size of the strings in pixels.
*
*/
STATIC_FUNC int sbrGetSizeInPixels(const HWND hwnd, LPTSTR pszStr)
{
if (IsWindow(hwnd))
{
HDC hDC;
SIZE sz;
// Select the font of the statusbar...
//
hDC = GetDC(hwnd);
GetTextExtentPoint32(hDC,
(LPCTSTR)pszStr,
StrCharGetStrLength(pszStr),
&sz);
sz.cx += (EXTRASPACE * WINDOWSBORDERWIDTH);
ReleaseDC(hwnd, hDC);
return (sz.cx);
}
else
{
return 0;
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCalcPartSize
*
* DESCRIPTION:
* Calculate the largest string that may be displayed in a given
* statusbar part. This function is called to calculate the length of the
* emulator part and the connection status part. Depending on the translation
* of the strings in the resources these parts will have to be of different
* length.
*
* ARGUMENTS:
* hwnd - window handle
* iId - part identifier
*
* RETURNS:
* iLongest - the maximum size, in pixels, for the given part
*/
STATIC_FUNC int sbrCalcPartSize(const HWND hwnd, const int iId)
{
int iLongest = 0;
if (IsWindow(hwnd))
{
unsigned int aCnctTable[]= {IDS_STATUSBR_CONNECT,
IDS_STATUSBR_CONNECT_FORMAT,
IDS_STATUSBR_CONNECT_FORMAT_X,
IDS_STATUSBR_DISCONNECT,
IDS_STATUSBR_CONNECTING,
IDS_STATUSBR_DISCONNECTING};
TCHAR ach[100],
achText[100];
int i;
int iRet = 0;
int nLimit;
if (iId == SBR_CNCT_PART_NO)
{
TCHAR_Fill(ach, TEXT('\0'), sizeof(ach) / sizeof(TCHAR));
nLimit = sizeof(aCnctTable) / sizeof(int);
for (i = 0; i < nLimit; i++)
{
LoadString(glblQueryDllHinst(), aCnctTable[i], ach, sizeof(ach) / sizeof(TCHAR));
if ((iRet = sbrGetSizeInPixels(hwnd, ach)) > iLongest)
iLongest = iRet;
}
}
else
{
#if 0
DWORD nLen;
BYTE *pv;
if (resLoadDataBlock(glblQueryDllHinst(), IDT_EMU_NAMES,
(LPVOID *)&pv, &nLen))
{
return 0;
}
nEmuCount = *(RCDATA_TYPE *)pv;
pv += sizeof(RCDATA_TYPE);
for (i = 0 ; i < nEmuCount ; i++)
{
if ((nLen = (DWORD)StrCharGetByteCount((LPTSTR)pv) + (DWORD)sizeof(BYTE)) == 0)
{
return 0;
}
if ((iRet = sbrGetSizeInPixels(hwnd, pv)) > iLongest)
iLongest = iRet;
pv += (nLen + (DWORD)sizeof(RCDATA_TYPE));
}
#else 0
int nLen;
for (i = IDS_EMUNAME_BASE ; i < IDS_EMUNAME_BASE + NBR_EMULATORS; i++)
{
nLen = LoadString(glblQueryDllHinst(), (unsigned int)i, achText, sizeof(achText) / sizeof(TCHAR));
if (nLen == 0)
{
return (0);
}
if ((iRet = sbrGetSizeInPixels(hwnd, achText)) > iLongest)
iLongest = iRet;
}
#endif // 0
}
}
return (iLongest);
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrTimerRefresh
*
* DESCRIPTION:
* Refresh the timer display if we are connected.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrTimerRefresh(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
TCHAR ach[256], achFormat[256];
TCHAR achTime[256];
int iRet = -1;
HCNCT hCnct = (HCNCT)0;
SYSTEMTIME stSystem;
hCnct = sessQueryCnctHdl(pSBRData->hSession);
if (hCnct)
{
iRet = cnctQueryStatus(hCnct);
}
if (iRet == CNCT_STATUS_TRUE)
{
pSBRData->iLastCnctStatus = iRet;
sbrCnctTimeToSystemTime(hwnd, &stSystem, pSBRData);
achTime[0] = TEXT('\0');
if (GetTimeFormat(LOCALE_SYSTEM_DEFAULT,
TIME_NOTIMEMARKER | TIME_FORCE24HOURFORMAT,
&stSystem, NULL, achTime, sizeof(achTime)) == 0)
{
DbgShowLastError();
sbrDrawCnctPart(hwnd, iRet, 0);
return;
}
// Load the "Connected %s" format string...
// Since this operation is costly, cach the connected format
// string...
//
if (pSBRData->pachCNCT)
{
wsprintf(ach, pSBRData->pachCNCT, achTime);
}
else
{
LoadString(glblQueryDllHinst(), IDS_STATUSBR_CONNECT_FORMAT,
achFormat, sizeof(achFormat) / sizeof(TCHAR));
sbrCachString(pSBRData, IDS_STATUSBR_CONNECT_FORMAT, achFormat);
wsprintf(ach, achFormat, achTime);
}
sbrDrawCnctPart(hwnd, -1, (LPTSTR)ach);
}
else
{
if (iRet != pSBRData->iLastCnctStatus)
{
pSBRData->iLastCnctStatus = iRet;
sbrDrawCnctPart(hwnd, iRet, 0);
}
}
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCnctTimeToSystemTime
*
* DESCRIPTION:
* Get the connection elapsed time and express it in the SYSTEMTIME structure.
*
* ARGUMENTS:
* hwnd - statusbar window handle.
* lpSysTime - pointer to the SYSTEMTIME structure to fill.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC BOOL sbrCnctTimeToSystemTime(const HWND hwnd,
LPSYSTEMTIME lpSysTime, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
HCNCT hCnct = (HCNCT)0;
time_t tElapsed_time = (time_t)0;
WORD wElapsed;
hCnct = sessQueryCnctHdl(pSBRData->hSession);
if (hCnct == (HCNCT)0)
return FALSE;
// Get the elapsed time from the connection driver...
//
if (cnctQueryElapsedTime(hCnct, &tElapsed_time) != 0)
{
assert(FALSE);
return FALSE;
}
// Do the neccessary conversion to get SYSTEMTIME from the elapsed time.
//
wElapsed = (WORD)tElapsed_time;
memset(lpSysTime, 0, sizeof(SYSTEMTIME));
lpSysTime->wMonth = 1; // Jan=1 so it can't be zero.
lpSysTime->wHour = wElapsed/3600;
lpSysTime->wMinute = (wElapsed%3600)/60;
lpSysTime->wSecond = (wElapsed%3600)%60;
return TRUE;
}
else
{
return FALSE;
}
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCnctStatus
*
* DESCRIPTION:
* Refresh the contents of the connection part.
* Query the connection status and display appropriate text in the connection
* part.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrCnctStatus(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
int iRet = -1;
HCNCT hCnct = (HCNCT)0;
hCnct = sessQueryCnctHdl(pSBRData->hSession);
if (hCnct)
iRet = cnctQueryStatus(hCnct);
sbrDrawCnctPart(hwnd, iRet, (LPTSTR)0);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrDrawCnctPart
*
* DESCRIPTION:
* Draw a string in the connection part.
*
* ARGUMENTS:
* hwnd - window handle.
* iCnctStatus - connection status.
* pszStr - if this string exists, then display it in the connection part,
* otherwise read the string from the resource file according to
* the value of the iCnctStatus parameter.
*
* RETURNS:
*
*/
STATIC_FUNC void sbrDrawCnctPart(const HWND hwnd, const int iCnctStatus,
LPTSTR pszStr)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && IsWindow(hwnd))
{
TCHAR ach[100];
UINT iResId;
if (pszStr)
{
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_CNCT_PART_NO, (LPARAM)pszStr);
return;
}
switch (iCnctStatus)
{
case CNCT_STATUS_TRUE:
iResId = IDS_STATUSBR_CONNECT;
break;
case CNCT_STATUS_CONNECTING:
iResId = IDS_STATUSBR_CONNECTING;
break;
case CNCT_STATUS_DISCONNECTING:
iResId = IDS_STATUSBR_DISCONNECTING;
break;
case CNCT_STATUS_ANSWERING:
iResId = IDS_STATUSBR_ANSWERING;
break;
default:
iResId = IDS_STATUSBR_DISCONNECT;
break;
}
// For Far-East version nothing would have to be done here since we are
// just reading a string from the resource and sending it to the common
// control which should be able to display a string containing DB chars.
//
LoadString(glblQueryDllHinst(),
iResId,
ach,
sizeof(ach) / sizeof(TCHAR));
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_CNCT_PART_NO, (LPARAM)(LPCTSTR)ach);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrEmulatorName
*
* DESCRIPTION:
* Refresh the contents of the emulator part.
* Get the emulator name and display it in the emulator part.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrEmulatorName(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
TCHAR ach[100];
HEMU hEmu = (HEMU)0;
hEmu = sessQueryEmuHdl(pSBRData->hSession);
ach[0] = TEXT('\0');
if (hEmu)
emuQueryName(hEmu, ach, sizeof(ach));
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_EMU_PART_NO,
(LPARAM)(LPCTSTR)ach);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCom
*
* DESCRIPTION:
* Handles the Com portion of the status bar
*
* ARGUMENTS:
* hwnd - statusbar window handle
* pSBRData - data for this instance
*
* RETURNS:
* void
*
*/
STATIC_FUNC void sbrCom(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
TCHAR ach[100];
if (cnctGetComSettingsString(sessQueryCnctHdl(pSBRData->hSession), ach,
sizeof(ach) / sizeof(TCHAR)) == 0)
{
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_COM_PART_NO, (LPARAM)ach);
}
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrScrolLock
*
* DESCRIPTION:
* Display the status of the scroll lock key in the status bar.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrScrolLock(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
int iScrl = 0, nFlag = 0;
iScrl = (GetKeyState(VK_SCROLL) & 1);
nFlag = (iScrl == 0) ? SBT_OWNERDRAW : 0;
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_SCRL_PART_NO | nFlag,
(LPARAM)(LPCTSTR)pSBRData->pachSCRL);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCapsLock
*
* DESCRIPTION:
* Refresh the display of the scroll lock key state in the status bar.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrCapsLock(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
int iCap = 0, nFlag = 0;
iCap = (GetKeyState(VK_CAPITAL) & 1);
nFlag = (iCap == 0) ? SBT_OWNERDRAW : 0;
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_CAPL_PART_NO | nFlag,
(LPARAM)(LPCTSTR)pSBRData->pachCAPL);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrNumLock
*
* DESCRIPTION:
* Display the current status for the Num Lock key on the status bar.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrNumLock(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
int iNum = 0, nFlag = 0;
iNum = (GetKeyState(VK_NUMLOCK) & 1);
nFlag = (iNum == 0) ? SBT_OWNERDRAW : 0;
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_NUML_PART_NO | nFlag,
(LPARAM)(LPCTSTR)pSBRData->pachNUML);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCapture
*
* DESCRIPTION:
* Refresh Caputre part on the status bar.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrCapture(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
HCAPTUREFILE hCapt;
int nCapState = 0, nFlag = 0;
hCapt = sessQueryCaptureFileHdl(pSBRData->hSession);
if (hCapt != (HCAPTUREFILE)0)
nCapState = cpfGetCaptureState(hCapt);
nFlag = (nCapState & CPF_CAPTURE_ON) ? 0 : SBT_OWNERDRAW;
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_CAPT_PART_NO | nFlag,
(LPARAM)(LPCTSTR)pSBRData->pachCAPT);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrPrintEcho
*
* DESCRIPTION:
* Display the status of the print echo in the status bar.
*
* ARGUMENTS:
* hwnd - window handle.
*
* RETURNS:
* void.
*
*/
STATIC_FUNC void sbrPrintEcho(const HWND hwnd, const pSBR pSBRData)
{
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
TCHAR ach[50];
HEMU hEmu;
int nPrneStatus = 0, nFlag = 0;
hEmu = sessQueryEmuHdl(pSBRData->hSession);
ach[0] = TEXT('\0');
if (hEmu != 0)
nPrneStatus = printQueryStatus(emuQueryPrintEchoHdl(hEmu));
nFlag = (nPrneStatus) ? 0 : SBT_OWNERDRAW;
SendMessage(hwnd, SB_SETTEXT, (WPARAM)SBR_PRNE_PART_NO | nFlag,
(LPARAM)(LPCTSTR)pSBRData->pachPECHO);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrCreateTimer
*
* DESCRIPTION:
* Create timer in order to show the connected time on the statusbar.
*
* ARGUMENTS:
* HWND hwnd - statusbar window handle.
*
* RETURNS:
* TRUE - is success, FALSE - if failure
*
*/
STATIC_FUNC BOOL sbrCreateTimer(const HWND hwnd, const pSBR pSBRData)
{
int nRet;
BOOL bRet = FALSE;
if (FindAtom((LPCTSTR)SBR_ATOM_NAME) != 0 && pSBRData != NULL &&
IsWindow(hwnd))
{
nRet = TimerCreate(pSBRData->hSession,
&pSBRData->hTimer,
1000,
sbrTimerProc,
(void *)pSBRData);
if (nRet == TIMER_OK)
{
bRet =TRUE;
}
}
return bRet;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbrTimerProc
*
* DESCRIPTION:
* Timer callback that simply notifies the status line to check its
* display components.
*
* ARGUMENTS:
* DWORD dwhWnd - window handle of status line.
* long uTime - not used.
*
* RETURNS:
* void.
*
*/
void CALLBACK sbrTimerProc(void *pvData, long uTime)
{
pSBR pSBRData = (SBR *)pvData;
if (pSBRData != NULL && IsWindow(pSBRData->hwnd))
{
SendMessage((HWND)pSBRData->hwnd, SBR_NTFY_TIMER, 0, 0L);
}
return;
}
/*=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
* FUNCTION:
* sbr_WM_DRAWITEM
*
* DESCRIPTION:
* When SB_SETTEXT message is sent to the statusbar with SBT_OWNERDRAW flag
* set a WM_DRAWITEM is posted to the parent window, in our case the session
* window. This function is called from there with the data needed to draw,
* i.e., the pointer to DRAWITEMSTRUCT structure.
*
* ARGUMENTS:
* hwnd - statusbar window handle.
* lpdis - pointer to a DRAWITEMSTRUCT structure filled with useful
* information needed to draw the item.
*
* RETURNS:
* void.
*
*/
void sbr_WM_DRAWITEM(HWND hwnd, LPDRAWITEMSTRUCT lpdis)
{
COLORREF crSave;
int nBkMode;
if (IsWindow(hwnd))
{
// Save and set text color, mode, etc...
//
crSave = GetTextColor(lpdis->hDC);
SetTextColor(lpdis->hDC, GetSysColor(COLOR_3DSHADOW));
nBkMode = GetBkMode(lpdis->hDC);
SetBkMode(lpdis->hDC, TRANSPARENT);
//
// OK, draw the text...
//
TextOut(lpdis->hDC, lpdis->rcItem.left + 2 * WINDOWSBORDERWIDTH,
lpdis->rcItem.top, (LPTSTR)lpdis->itemData,
StrCharGetStrLength((LPTSTR)lpdis->itemData));
SetTextColor(lpdis->hDC, crSave);
SetBkMode(lpdis->hDC, nBkMode);
}
return;
}