mirror of https://github.com/lianthony/NT4.0
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.
1879 lines
42 KiB
1879 lines
42 KiB
/**********************************************************************/
|
|
/** Microsoft Windows/NT **/
|
|
/** Copyright(c) Microsoft Corp., 1995 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
listbox.cpp
|
|
Custom listboxes
|
|
|
|
FILE HISTORY:
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "winsadmn.h"
|
|
#include "listbox.h"
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char BASED_CODE THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
#define new DEBUG_NEW
|
|
|
|
void
|
|
CIpAddressListBox::MeasureItem(
|
|
LPMEASUREITEMSTRUCT lpMIS
|
|
)
|
|
{
|
|
TEXTMETRIC tm;
|
|
//
|
|
// all items are of fixed size
|
|
//
|
|
CDC * pDC = GetDC();
|
|
pDC->GetTextMetrics(&tm);
|
|
lpMIS->itemHeight = tm.tmHeight;
|
|
ReleaseDC(pDC);
|
|
}
|
|
|
|
void
|
|
CIpAddressListBox::DisplayItem(
|
|
LPDRAWITEMSTRUCT lpDIS
|
|
)
|
|
{
|
|
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
|
|
|
|
CIpAddress * p = (CIpAddress *)lpDIS->itemData;
|
|
ASSERT(p != NULL);
|
|
pDC->TextOut(lpDIS->rcItem.left, lpDIS->rcItem.top, (CString)*p);
|
|
}
|
|
|
|
void
|
|
CIpAddressListBox::DrawItem(
|
|
LPDRAWITEMSTRUCT lpDIS
|
|
)
|
|
{
|
|
CDC* pDC = CDC::FromHandle(lpDIS->hDC);
|
|
CBrush brushBackground;
|
|
|
|
if ((lpDIS->itemState & ODS_SELECTED) &&
|
|
(lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
|
|
{
|
|
//
|
|
// Item has been selected. Clear the rectangle with
|
|
// the highlight colour as selected in the control panel
|
|
//
|
|
brushBackground.CreateSolidBrush(::GetSysColor(COLOR_HIGHLIGHT));
|
|
pDC->FillRect(&lpDIS->rcItem, &brushBackground);
|
|
|
|
//
|
|
// And set the colours so that the item will be text-outed
|
|
// in the proper colours
|
|
//
|
|
COLORREF crOldBackground = pDC->SetBkColor(::GetSysColor(COLOR_HIGHLIGHT));
|
|
COLORREF crOldText = pDC->SetTextColor(::GetSysColor(COLOR_HIGHLIGHTTEXT));
|
|
|
|
//
|
|
// Textout the item
|
|
//
|
|
DisplayItem(lpDIS);
|
|
|
|
//
|
|
// And now restore the colours.
|
|
//
|
|
pDC->SetBkColor(crOldBackground);
|
|
pDC->SetTextColor(crOldText);
|
|
}
|
|
|
|
if (!(lpDIS->itemState & ODS_SELECTED) &&
|
|
(lpDIS->itemAction & (ODA_SELECT | ODA_DRAWENTIRE)))
|
|
{
|
|
//
|
|
// Item has been de-selected, clear the rectangle with
|
|
// the regular background colour.
|
|
//
|
|
brushBackground.CreateSolidBrush(::GetSysColor(COLOR_WINDOW));
|
|
pDC->FillRect(&lpDIS->rcItem, &brushBackground);
|
|
|
|
//
|
|
// Textout the item
|
|
//
|
|
DisplayItem(lpDIS);
|
|
}
|
|
|
|
//
|
|
// The focus has changed. DrawFocusRect is a XOR operation,
|
|
// so this will either draw or dismiss the focus rectangle.
|
|
//
|
|
if (lpDIS->itemAction & ODA_FOCUS)
|
|
{
|
|
pDC->DrawFocusRect(&lpDIS->rcItem);
|
|
}
|
|
}
|
|
|
|
void
|
|
CIpAddressListBox::DeleteItem(
|
|
LPDELETEITEMSTRUCT lpDIS
|
|
)
|
|
{
|
|
CIpAddress * p = (CIpAddress *)lpDIS->itemData;
|
|
ASSERT(p != NULL);
|
|
if (p != NULL)
|
|
{
|
|
delete p;
|
|
}
|
|
}
|
|
|
|
int
|
|
CIpAddressListBox::CompareItem(
|
|
LPCOMPAREITEMSTRUCT lpCIS
|
|
)
|
|
{
|
|
CIpAddress * p1 = (CIpAddress *)lpCIS->itemData1;
|
|
CIpAddress * p2 = (CIpAddress *)lpCIS->itemData2;
|
|
|
|
ASSERT(p1 != NULL);
|
|
ASSERT(p2 != NULL);
|
|
|
|
return ((LONG)*p2 == (LONG)*p1
|
|
? 0
|
|
: (LONG)*p2 > (LONG)*p1 ? -1 : +1);
|
|
}
|
|
|
|
void
|
|
DeleteItem(
|
|
LPDELETEITEMSTRUCT lpDIS
|
|
)
|
|
{
|
|
CIpNamePair * p = (CIpNamePair *)lpDIS->itemData;
|
|
delete p;
|
|
}
|
|
|
|
//
|
|
// CODEWORK:: Change to binary search.
|
|
//
|
|
int
|
|
CIpAddressListBox::FindItem(
|
|
CIpAddress * pinpNew
|
|
)
|
|
{
|
|
UINT nIndex = 0;
|
|
BOOL fFound = FALSE;
|
|
UINT nItems = GetCount();
|
|
COMPAREITEMSTRUCT CIS;
|
|
int n;
|
|
|
|
CIpAddress * pinpCurrent;
|
|
|
|
while ((nIndex < nItems) && !fFound)
|
|
{
|
|
CIS.itemData2 = (DWORD)pinpNew;
|
|
CIS.itemData1 = (DWORD)(pinpCurrent = (CIpAddress *)GetItemDataPtr(nIndex));
|
|
n = CompareItem(&CIS);
|
|
if (!n)
|
|
{
|
|
fFound = TRUE;
|
|
}
|
|
else if (n > 0)
|
|
{
|
|
//
|
|
// Not found, and we're not going to find it either, so
|
|
// stop looking.
|
|
//
|
|
nIndex = nItems;
|
|
}
|
|
else
|
|
{
|
|
++nIndex;
|
|
}
|
|
}
|
|
|
|
return fFound ? nIndex : -1;
|
|
}
|
|
|
|
int
|
|
CIpAddressListBox::AddItem(
|
|
CIpAddress & inpAddress
|
|
)
|
|
{
|
|
CIpAddress * pinpNew = new CIpAddress(inpAddress);
|
|
if (pinpNew == NULL)
|
|
{
|
|
return LB_ERR;
|
|
}
|
|
|
|
return AddString((LPCSTR)pinpNew);
|
|
}
|
|
|
|
//
|
|
// Custom Listboxes
|
|
//
|
|
IMPLEMENT_DYNAMIC(CWinssListBox, CListBoxEx);
|
|
|
|
const int CWinssListBox::nBitmaps = 1;
|
|
|
|
void CWinssListBox::DrawItemEx(
|
|
CListBoxExDrawStruct& ds
|
|
)
|
|
{
|
|
int nTab = m_nTab ? m_nTab : ds.m_Rect.right;
|
|
|
|
CIpNamePair * p = (CIpNamePair *)ds.m_ItemData;
|
|
ASSERT(p != NULL);
|
|
|
|
CDC* pBmpDC = (CDC*)&ds.m_pResources->DcBitMap();
|
|
int bmh = ds.m_pResources->BitmapHeight();
|
|
int bmw = ds.m_pResources->BitmapWidth();
|
|
|
|
//
|
|
// select bitmap from resource
|
|
//
|
|
int bm_h = (ds.m_Sel)?0:bmh;
|
|
int bm_w = 0;
|
|
ds.m_pDC->BitBlt( ds.m_Rect.left+1, ds.m_Rect.top, bmw, bmh, pBmpDC, bm_w, bm_h, SRCCOPY );
|
|
|
|
CString strNetBIOSName(
|
|
theApp.CleanNetBIOSName(
|
|
p->GetNetBIOSName(),
|
|
FALSE, // Do not expand
|
|
TRUE, // Do truncate
|
|
theApp.m_wpPreferences.IsLanmanCompatible(),
|
|
FALSE, // Name is not OEM
|
|
TRUE, // Use backslashes
|
|
0));
|
|
|
|
CHAR szLine[128];
|
|
|
|
|
|
switch(m_nAddressDisplay)
|
|
{
|
|
case CPreferences::ADD_NB_ONLY:
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top, strNetBIOSName);
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, nTab,
|
|
ds.m_Rect.bottom, strNetBIOSName);
|
|
break;
|
|
|
|
case CPreferences::ADD_IP_ONLY:
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top, p->GetIpAddress());
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, nTab,
|
|
ds.m_Rect.bottom, p->GetIpAddress());
|
|
break;
|
|
|
|
case CPreferences::ADD_NB_IP:
|
|
::wsprintf(szLine, "%s (%s)", (LPCSTR)strNetBIOSName, (LPCSTR)(CString)p->GetIpAddress());
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top, szLine);
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, nTab,
|
|
ds.m_Rect.bottom, szLine);
|
|
break;
|
|
|
|
case CPreferences::ADD_IP_NB:
|
|
::wsprintf(szLine, "%s (%s)", (LPCSTR)(CString)p->GetIpAddress(), (LPCSTR)strNetBIOSName);
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top, szLine);
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, nTab,
|
|
ds.m_Rect.bottom, szLine);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0 && "Invalid Address Dislay Value");
|
|
}
|
|
}
|
|
|
|
int
|
|
CWinssListBox::CompareItem(
|
|
LPCOMPAREITEMSTRUCT lpCIS
|
|
)
|
|
{
|
|
CIpNamePair * p1 = (CIpNamePair *)lpCIS->itemData1;
|
|
CIpNamePair * p2 = (CIpNamePair *)lpCIS->itemData2;
|
|
|
|
ASSERT(p1 != NULL);
|
|
ASSERT(p2 != NULL);
|
|
|
|
ULONG ip1, ip2;
|
|
switch(m_nAddressDisplay)
|
|
{
|
|
case CPreferences::ADD_NB_ONLY:
|
|
case CPreferences::ADD_NB_IP:
|
|
return p1->GetNetBIOSName().CompareNoCase(p2->GetNetBIOSName());
|
|
|
|
case CPreferences::ADD_IP_ONLY:
|
|
case CPreferences::ADD_IP_NB:
|
|
ip1 = (LONG)p1->GetIpAddress();
|
|
ip2 = (LONG)p2->GetIpAddress();
|
|
return ip2 == ip1 ? 0 : ip2 > ip1 ? -1 : +1;
|
|
|
|
default:
|
|
ASSERT(0 && "Invalid address display value!");
|
|
return 0;
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
void
|
|
CWinssListBox::DeleteItem(
|
|
LPDELETEITEMSTRUCT lpDIS
|
|
)
|
|
{
|
|
CIpNamePair * p = (CIpNamePair *)lpDIS->itemData;
|
|
delete p;
|
|
}
|
|
|
|
int
|
|
CWinssListBox::FindItem(
|
|
CIpNamePair * pinpNew
|
|
)
|
|
{
|
|
CIpNamePair * pinpCurrent;
|
|
|
|
for (int n = 0; n < GetCount(); ++n)
|
|
{
|
|
pinpCurrent = GetItem(n);
|
|
//
|
|
// Has to match both IP address and netbios name
|
|
//
|
|
if ((LONG)pinpCurrent->GetIpAddress() == (LONG)pinpNew->GetIpAddress())
|
|
{
|
|
if (!pinpCurrent->GetNetBIOSName().CompareNoCase(pinpNew->GetNetBIOSName()))
|
|
{
|
|
return n;
|
|
}
|
|
}
|
|
}
|
|
|
|
return -1;
|
|
}
|
|
|
|
int
|
|
CWinssListBox::AddItem(
|
|
CIpNamePair & inpAddress,
|
|
BOOL fUnique,
|
|
BOOL fSort
|
|
)
|
|
{
|
|
CIpNamePair * pinpNew = new CIpNamePair(inpAddress);
|
|
if (pinpNew == NULL)
|
|
{
|
|
return LB_ERR ;
|
|
}
|
|
|
|
if (fUnique)
|
|
{
|
|
int n;
|
|
if ((n = FindItem(pinpNew)) != -1)
|
|
{
|
|
delete pinpNew;
|
|
return n;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Simply add it.
|
|
//
|
|
int nIndex;
|
|
if (fSort)
|
|
{
|
|
nIndex = AddString((LPCSTR)pinpNew);
|
|
}
|
|
else
|
|
{
|
|
nIndex = InsertString(0, (LPCSTR)pinpNew);
|
|
}
|
|
|
|
return nIndex;
|
|
}
|
|
|
|
LPSTR
|
|
CWinssListBox::LongLongToText (
|
|
const LARGE_INTEGER& li
|
|
)
|
|
{
|
|
static CHAR sz[] = "01234567890ABCDEF0";
|
|
CHAR *pch = sz;;
|
|
::wsprintf(sz, "%08lX%08lX", li.HighPart, li.LowPart);
|
|
//
|
|
// Kill leading zeros
|
|
//
|
|
while (*pch == '0')
|
|
{
|
|
++pch;
|
|
}
|
|
//
|
|
// At least one digit...
|
|
//
|
|
if (*pch == '\0')
|
|
{
|
|
--pch;
|
|
}
|
|
|
|
return pch;
|
|
}
|
|
|
|
|
|
/*
|
|
void CWinssListBox::ReSort()
|
|
{
|
|
int nTotal = GetCount();
|
|
if (nTotal==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CIpNamePair **p;
|
|
int i;
|
|
|
|
m_pItems = new CIpNamePair*[nTotal];
|
|
p = m_pItems;
|
|
if (m_pItems == NULL);
|
|
{
|
|
TRACEEOLID("OOM allocating " << nTotal << " items.");
|
|
return;
|
|
}
|
|
|
|
for (i=0; i < nTotal; ++i)
|
|
{
|
|
*p++ = GetItem(i);
|
|
}
|
|
Sort(0, nTotal-1);
|
|
p = m_pItems;
|
|
for (i=0; i < nTotal; ++i)
|
|
{
|
|
SetItemDataPtr(i, (PVOID)*p++);
|
|
}
|
|
delete m_pItems;
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
*/
|
|
|
|
//
|
|
// Quick Sort
|
|
//
|
|
void
|
|
CWinssListBox::Sort(
|
|
int nLow,
|
|
int nHigh
|
|
)
|
|
{
|
|
int nUp, nDown;
|
|
CIpNamePair * pBreak;
|
|
COMPAREITEMSTRUCT CIS;
|
|
|
|
if (nLow < nHigh)
|
|
{
|
|
if((nHigh - nLow) == 1)
|
|
{
|
|
CIS.itemData1 = (DWORD)m_pItems[nLow];
|
|
CIS.itemData2 = (DWORD)m_pItems[nHigh];
|
|
if (CompareItem(&CIS) > 0)
|
|
{
|
|
Swap(nLow, nHigh);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
pBreak = m_pItems[nHigh];
|
|
do
|
|
{
|
|
nUp = nLow;
|
|
nDown = nHigh;
|
|
CIS.itemData1 = (DWORD)m_pItems[nUp];
|
|
CIS.itemData2 = (DWORD)pBreak;
|
|
while((nUp < nDown) && (CompareItem(&CIS) <= 0))
|
|
{
|
|
CIS.itemData1 = (DWORD)m_pItems[++nUp];
|
|
}
|
|
CIS.itemData1 = (DWORD)m_pItems[nDown];
|
|
while((nDown > nUp) && (CompareItem(&CIS) >= 0))
|
|
{
|
|
CIS.itemData1 = (DWORD)m_pItems[--nDown];
|
|
}
|
|
if (nUp < nDown)
|
|
{
|
|
Swap(nUp, nDown);
|
|
}
|
|
} while (nUp < nDown);
|
|
|
|
Swap(nUp, nHigh);
|
|
if ((nUp - nLow) < (nHigh - nUp) )
|
|
{
|
|
Sort(nLow, nUp - 1);
|
|
Sort(nUp + 1, nHigh);
|
|
}
|
|
else
|
|
{
|
|
Sort(nUp + 1, nHigh);
|
|
Sort(nLow, nUp - 1);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void
|
|
CWinssListBox::Swap(
|
|
int n1,
|
|
int n2
|
|
)
|
|
{
|
|
CIpNamePair * pTemp = m_pItems[n1];
|
|
m_pItems[n1] = m_pItems[n2];
|
|
m_pItems[n2] = pTemp;
|
|
}
|
|
|
|
void
|
|
CWinssListBox::ReSort()
|
|
{
|
|
int nTotal = GetCount();
|
|
|
|
if (nTotal==0)
|
|
{
|
|
return;
|
|
}
|
|
|
|
CIpNamePair **p;
|
|
CIpNamePair **m_pItems;
|
|
CIpNamePair *pTmp;
|
|
COMPAREITEMSTRUCT CIS;
|
|
int i,j;
|
|
|
|
m_pItems = new CIpNamePair*[nTotal];
|
|
p = m_pItems;
|
|
ASSERT(m_pItems != NULL);
|
|
|
|
for (i=0; i < nTotal; ++i)
|
|
{
|
|
*p++ = GetItem(i);
|
|
}
|
|
|
|
//
|
|
// Sort the items
|
|
//
|
|
for (i=0; i<nTotal-1; i++)
|
|
{
|
|
for (j=i+1; j<nTotal; j++)
|
|
{
|
|
CIS.itemData1 = (DWORD)m_pItems[i];
|
|
CIS.itemData2 = (DWORD)m_pItems[j];
|
|
|
|
if (CompareItem(&CIS) > 0) {
|
|
pTmp = m_pItems[j];
|
|
m_pItems[j] = m_pItems[i];
|
|
m_pItems[i] = pTmp;
|
|
}
|
|
}
|
|
}
|
|
|
|
p = m_pItems;
|
|
|
|
for (i=0; i < nTotal; ++i)
|
|
{
|
|
SetItemDataPtr(i, (PVOID)*p++);
|
|
}
|
|
|
|
delete m_pItems;
|
|
|
|
Invalidate(FALSE);
|
|
}
|
|
|
|
int
|
|
CWinssListBox::InsertItem(
|
|
UINT nIndex,
|
|
CIpNamePair & inpAddress
|
|
)
|
|
{
|
|
CIpNamePair * p = new CIpNamePair(inpAddress);
|
|
return p != NULL ? InsertString(nIndex, (LPCSTR)p) : LB_ERR;
|
|
}
|
|
|
|
//
|
|
// User presses a key, now set the index
|
|
// to first item with starting with this key
|
|
//
|
|
void
|
|
CWinssListBox::SetIndexFromChar(
|
|
CHAR ch,
|
|
BOOL fMultiSelect // Listbox is multi-select
|
|
)
|
|
{
|
|
UINT nIndex = 0;
|
|
BOOL fFound = FALSE;
|
|
UINT nItems = GetCount();
|
|
COMPAREITEMSTRUCT CIS;
|
|
int n;
|
|
|
|
CIpNamePair * pinpCurrent;
|
|
|
|
switch(m_nAddressDisplay)
|
|
{
|
|
case CPreferences::ADD_NB_ONLY:
|
|
case CPreferences::ADD_NB_IP:
|
|
{
|
|
CIpNamePair newPair(0L, CString(ch));
|
|
CIS.itemData2 = (DWORD)&newPair;
|
|
while ((nIndex < nItems) && !fFound)
|
|
{
|
|
CIS.itemData1 = (DWORD)(pinpCurrent = GetItem(nIndex));
|
|
n = CompareItem(&CIS);
|
|
if (n >= 0)
|
|
{
|
|
fFound = TRUE;
|
|
if (fMultiSelect)
|
|
{
|
|
SetSel(-1, FALSE);
|
|
SetSel(nIndex, TRUE);
|
|
}
|
|
else
|
|
{
|
|
SetCurSel(nIndex);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
++nIndex;
|
|
}
|
|
}
|
|
}
|
|
break;
|
|
|
|
case CPreferences::ADD_IP_ONLY:
|
|
case CPreferences::ADD_IP_NB:
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0 && "Invalid address display value!");
|
|
}
|
|
}
|
|
|
|
IMPLEMENT_DYNAMIC(COwnersListBox, CWinssListBox);
|
|
|
|
// Owner list box
|
|
void
|
|
COwnersListBox::DrawItemEx(
|
|
CListBoxExDrawStruct& ds
|
|
)
|
|
{
|
|
// #define VERSIONNUM_TAB 203
|
|
|
|
//
|
|
// Display the WINS server address in the
|
|
// usual manner
|
|
//
|
|
CWinssListBox::DrawItemEx(ds);
|
|
//
|
|
// But be sure there's enough room for the version
|
|
// number
|
|
//
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left + VERSIONNUM_TAB - 3, ds.m_Rect.top, " ");
|
|
|
|
COwner * p = (COwner *)ds.m_ItemData;
|
|
ASSERT(p != NULL);
|
|
|
|
//
|
|
// Display the version number in hexadecimal
|
|
// format
|
|
//
|
|
char * pch = LongLongToText(p->GetVersion());
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left + VERSIONNUM_TAB, ds.m_Rect.top, pch);
|
|
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + m_nTab, ds.m_Rect.top,
|
|
ds.m_Rect.right, ds.m_Rect.bottom, pch);
|
|
}
|
|
|
|
int
|
|
COwnersListBox::AddItem(
|
|
COwner & inpAddress,
|
|
BOOL fUnique
|
|
)
|
|
{
|
|
COwner * pinpNew = new COwner(inpAddress);
|
|
if (pinpNew == NULL)
|
|
{
|
|
return LB_ERR;
|
|
}
|
|
|
|
if (fUnique)
|
|
{
|
|
int n;
|
|
if ((n = FindItem(pinpNew)) != -1)
|
|
{
|
|
delete pinpNew;
|
|
return n;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Simply add it.
|
|
//
|
|
return AddString((LPCSTR)pinpNew);
|
|
}
|
|
|
|
//
|
|
// Replication Partners list box
|
|
//
|
|
const int CPartnersListBox::nBitmaps = 4;
|
|
|
|
CPartnersListBox::CPartnersListBox(
|
|
int nAddressDisplay
|
|
)
|
|
: CWinssListBox(nAddressDisplay)
|
|
{
|
|
}
|
|
|
|
void
|
|
CPartnersListBox::DrawItemEx(
|
|
CListBoxExDrawStruct& ds
|
|
)
|
|
{
|
|
RECT r, pr;
|
|
UINT PUSH_OFFSET, PULL_OFFSET;
|
|
|
|
CWnd* hParent = GetParent();
|
|
|
|
(hParent->GetDlgItem(IDC_STATIC_WINSSERVER))->GetWindowRect( &pr );
|
|
|
|
(hParent->GetDlgItem(IDC_STATIC_PUSH))->GetWindowRect( &r );
|
|
PUSH_OFFSET = r.left - pr.left;
|
|
|
|
(hParent->GetDlgItem(IDC_STATIC_PULL))->GetWindowRect( &r );
|
|
PULL_OFFSET = r.left - pr.left;
|
|
|
|
CWinsServer * p = (CWinsServer *)ds.m_ItemData;
|
|
ASSERT(p != NULL);
|
|
|
|
CDC* pBmpDC = (CDC*)&ds.m_pResources->DcBitMap();
|
|
int bmh = ds.m_pResources->BitmapHeight();
|
|
int bmw = ds.m_pResources->BitmapWidth();
|
|
|
|
//
|
|
// Select the appropriate bitmap to use
|
|
//
|
|
int nOffset;
|
|
if (p->IsPush() && p->IsPull())
|
|
{
|
|
nOffset = 3;
|
|
}
|
|
else if (p->IsPush())
|
|
{
|
|
nOffset = 2;
|
|
}
|
|
else if (p->IsPull())
|
|
{
|
|
nOffset = 1;
|
|
}
|
|
else
|
|
{
|
|
nOffset = 0;
|
|
}
|
|
|
|
//
|
|
// select bitmap from resource
|
|
//
|
|
int bm_h = (ds.m_Sel)?0:bmh;
|
|
int bm_w = bmw*nOffset;
|
|
ds.m_pDC->BitBlt( ds.m_Rect.left+1, ds.m_Rect.top, bmw, bmh, pBmpDC, bm_w, bm_h, SRCCOPY );
|
|
|
|
CString strNetBIOSName(
|
|
theApp.CleanNetBIOSName(
|
|
p->GetNetBIOSName(),
|
|
FALSE,
|
|
TRUE,
|
|
theApp.m_wpPreferences.IsLanmanCompatible(),
|
|
FALSE, // Name is not OEM
|
|
TRUE, // Use backslashes
|
|
0));
|
|
|
|
CHAR szLine[256];
|
|
switch(m_nAddressDisplay)
|
|
{
|
|
case CPreferences::ADD_NB_ONLY:
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top, (LPCSTR)strNetBIOSName);
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, PUSH_OFFSET,
|
|
ds.m_Rect.bottom, (LPCSTR)strNetBIOSName);
|
|
break;
|
|
|
|
case CPreferences::ADD_IP_ONLY:
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top,
|
|
// (LPCTSTR)(CString)p->GetIpAddress());
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, PUSH_OFFSET,
|
|
ds.m_Rect.bottom, (LPCTSTR)(CString)p->GetIpAddress());
|
|
break;
|
|
|
|
case CPreferences::ADD_NB_IP:
|
|
::wsprintf(szLine, "%s (%s)", (LPCSTR)strNetBIOSName,
|
|
(LPCTSTR)(CString)p->GetIpAddress());
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top, szLine);
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, PUSH_OFFSET,
|
|
ds.m_Rect.bottom, szLine);
|
|
break;
|
|
|
|
case CPreferences::ADD_IP_NB:
|
|
::wsprintf(szLine, "%s (%s)", (LPCSTR)(CString)p->GetIpAddress(), (LPCSTR)strNetBIOSName);
|
|
//ds.m_pDC->TextOut(ds.m_Rect.left+bmw+3, ds.m_Rect.top, szLine);
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, PUSH_OFFSET,
|
|
ds.m_Rect.bottom, szLine);
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0 && "Invalid Address Dislay Value");
|
|
}
|
|
|
|
ASSERT(p != NULL);
|
|
|
|
//
|
|
// In case of long names, we want to make sure that
|
|
// there is enough room for push and pull checkmarks
|
|
//
|
|
// ds.m_pDC->TextOut(ds.m_Rect.left+PUSH_OFFSET-5, ds.m_Rect.top, " ");
|
|
|
|
//
|
|
// Draw checkmarks
|
|
//
|
|
if ((p->IsPush()) || (p->IsPull()))
|
|
{
|
|
CBitmap bitmap;
|
|
bitmap.LoadOEMBitmap(OBM_CHECK);
|
|
|
|
CDC cdcMem;
|
|
cdcMem.CreateCompatibleDC(ds.m_pDC);
|
|
cdcMem.SelectObject(&bitmap);
|
|
cdcMem.SetMapMode(ds.m_pDC->GetMapMode());
|
|
|
|
BITMAP bm;
|
|
POINT ptSize, ptOrg;
|
|
|
|
bitmap.GetObject(sizeof(BITMAP), (LPSTR) &bm);
|
|
ptSize.x = bm.bmWidth;
|
|
ptSize.y = bm.bmHeight;
|
|
ds.m_pDC->DPtoLP(&ptSize, 1);
|
|
|
|
ptOrg.x = 0;
|
|
ptOrg.y = 0;
|
|
cdcMem.DPtoLP(&ptOrg, 1);
|
|
|
|
//
|
|
// If a push partner
|
|
//
|
|
if (p->IsPush())
|
|
{
|
|
ds.m_pDC->BitBlt(ds.m_Rect.left + PUSH_OFFSET, ds.m_Rect.top,
|
|
ptSize.x, ptSize.y, &cdcMem, ptOrg.x, ptOrg.y, SRCCOPY);
|
|
}
|
|
|
|
//
|
|
// If a pull partner
|
|
//
|
|
if (p->IsPull())
|
|
{
|
|
ds.m_pDC->BitBlt(ds.m_Rect.left + PULL_OFFSET, ds.m_Rect.top,
|
|
ptSize.x, ptSize.y, &cdcMem, ptOrg.x, ptOrg.y, SRCCOPY);
|
|
}
|
|
}
|
|
}
|
|
|
|
int
|
|
CPartnersListBox::AddItem (
|
|
CWinsServer & ws,
|
|
BOOL fUnique,
|
|
BOOL fSort
|
|
)
|
|
{
|
|
CWinsServer * pwsNew = new CWinsServer(ws);
|
|
|
|
if (pwsNew == NULL)
|
|
{
|
|
return(LB_ERR);
|
|
}
|
|
|
|
if (fUnique)
|
|
{
|
|
int n;
|
|
if ((n = FindItem(pwsNew)) != -1)
|
|
{
|
|
delete pwsNew;
|
|
return n;
|
|
}
|
|
}
|
|
|
|
// Simply add it.
|
|
return fSort ? AddString((LPCSTR)pwsNew) : InsertString(0, (LPCSTR)pwsNew);
|
|
}
|
|
|
|
int
|
|
CPartnersListBox::InsertItem(
|
|
UINT nIndex,
|
|
CWinsServer & ws
|
|
)
|
|
{
|
|
CWinsServer * p = new CWinsServer(ws);
|
|
|
|
return p != NULL ? InsertString(nIndex, (LPCSTR)p) : LB_ERR;
|
|
}
|
|
|
|
//
|
|
// Static Mappings list box
|
|
//
|
|
const int CStaticMappingsListBox::nBitmaps = 4; // Number of bitmaps
|
|
|
|
IMPLEMENT_DYNAMIC(CStaticMappingsListBox, CListBoxEx);
|
|
|
|
BEGIN_MESSAGE_MAP(CStaticMappingsListBox, CListBoxEx)
|
|
//{{AFX_MSG_MAP(CStaticMappingsListBox)
|
|
ON_WM_VSCROLL()
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
CStaticMappingsListBox::CStaticMappingsListBox(
|
|
int nMessageId,
|
|
BOOL fMultiSelect,
|
|
int nAddressDisplay,
|
|
DWORD dwPageSize,
|
|
DWORD dwLargePageSize
|
|
)
|
|
: m_poblRecords(NULL),
|
|
m_pMask(NULL),
|
|
//m_posLastAdded(NULL),
|
|
m_nidxLastAdded(-1),
|
|
m_nAddressDisplay(nAddressDisplay),
|
|
m_nMessageId(nMessageId),
|
|
m_fMultiSelect(fMultiSelect),
|
|
m_nTab(0)
|
|
{
|
|
m_poblRecords = new COblWinsRecords(dwPageSize, dwLargePageSize);
|
|
}
|
|
|
|
CStaticMappingsListBox::~CStaticMappingsListBox()
|
|
{
|
|
if (m_pMask != NULL)
|
|
{
|
|
delete m_pMask;
|
|
}
|
|
|
|
//
|
|
// Cleaning up the list may take a bit of time
|
|
// with e.g. 100K records, so show an hourglass.
|
|
//
|
|
|
|
theApp.BeginWaitCursor();
|
|
theApp.SetStatusBarText(IDS_STATUS_DECONSTRUCTING);
|
|
ASSERT(m_poblRecords != NULL);
|
|
delete m_poblRecords;
|
|
theApp.SetStatusBarText();
|
|
theApp.EndWaitCursor();
|
|
}
|
|
|
|
//
|
|
// Return a pointer to the mapping at the given
|
|
// index in the listbox
|
|
//
|
|
void *
|
|
CStaticMappingsListBox::GetItemDataPtr(
|
|
int nIndex
|
|
) const
|
|
{
|
|
#ifdef WIN32S
|
|
return CListBoxEx::GetItemDataPtr(nIndex);
|
|
#else
|
|
ASSERT(nIndex <= m_poblRecords->GetUpperBound());
|
|
return m_poblRecords->GetAt(nIndex);
|
|
#endif // WIN32S
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::SortByIp()
|
|
{
|
|
//
|
|
// Must have the whole database read in to
|
|
// sort by IP
|
|
//
|
|
if (!m_poblRecords->AllRecordsReadIn())
|
|
{
|
|
//
|
|
// Don't add new pages to listbox, since they
|
|
// will be updated after the sort anyway
|
|
//
|
|
GetAllPages(FALSE);
|
|
}
|
|
|
|
theApp.SetStatusBarText(IDS_STATUS_SORTING);
|
|
theApp.BeginWaitCursor();
|
|
ASSERT(m_poblRecords != NULL);
|
|
m_poblRecords->SortByIp();
|
|
SetAddressDisplay(CPreferences::ADD_IP_NB);
|
|
theApp.EndWaitCursor();
|
|
|
|
#ifdef WIN32S
|
|
APIERR err = FillListBox();
|
|
#else
|
|
Invalidate(); // Repaint
|
|
#endif // WIN32S
|
|
|
|
theApp.SetStatusBarText();
|
|
|
|
#ifdef WIN32S
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
}
|
|
#endif // WIN32S
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::SortByType()
|
|
{
|
|
//
|
|
// Must have the whole database read in to
|
|
// sort by type
|
|
//
|
|
if (!m_poblRecords->AllRecordsReadIn())
|
|
{
|
|
//
|
|
// Don't add new pages to listbox, since they
|
|
// will be updated after the sort anyway
|
|
//
|
|
GetAllPages(FALSE);
|
|
}
|
|
|
|
theApp.SetStatusBarText(IDS_STATUS_SORTING);
|
|
theApp.BeginWaitCursor();
|
|
ASSERT(m_poblRecords != NULL);
|
|
m_poblRecords->SortByType();
|
|
SetAddressDisplay(CPreferences::ADD_NB_IP);
|
|
theApp.EndWaitCursor();
|
|
|
|
#ifdef WIN32S
|
|
APIERR err = FillListBox();
|
|
#else
|
|
Invalidate(); // Repaint
|
|
#endif // WIN32S
|
|
|
|
theApp.SetStatusBarText();
|
|
|
|
#ifdef WIN32S
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
}
|
|
#endif // WIN32S
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::SortByVersion()
|
|
{
|
|
//
|
|
// Must have the whole database read in to
|
|
// sort by Version
|
|
//
|
|
if (!m_poblRecords->AllRecordsReadIn())
|
|
{
|
|
//
|
|
// Don't add new pages to listbox, since they
|
|
// will be updated after the sort anyway
|
|
//
|
|
GetAllPages(FALSE);
|
|
}
|
|
|
|
theApp.SetStatusBarText(IDS_STATUS_SORTING);
|
|
theApp.BeginWaitCursor();
|
|
ASSERT(m_poblRecords != NULL);
|
|
m_poblRecords->SortByVersion();
|
|
SetAddressDisplay(CPreferences::ADD_NB_IP);
|
|
theApp.EndWaitCursor();
|
|
|
|
#ifdef WIN32S
|
|
APIERR err = FillListBox();
|
|
#else
|
|
Invalidate(); // Repaint
|
|
#endif // WIN32S
|
|
|
|
theApp.SetStatusBarText();
|
|
|
|
#ifdef WIN32S
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
}
|
|
#endif // WIN32S
|
|
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::SortByTime()
|
|
{
|
|
//
|
|
// Must have the whole database read in to
|
|
// sort by Time
|
|
//
|
|
if (!m_poblRecords->AllRecordsReadIn())
|
|
{
|
|
//
|
|
// Don't add new pages to listbox, since they
|
|
// will be updated after the sort anyway
|
|
//
|
|
GetAllPages(FALSE);
|
|
}
|
|
|
|
theApp.SetStatusBarText(IDS_STATUS_SORTING);
|
|
theApp.BeginWaitCursor();
|
|
ASSERT(m_poblRecords != NULL);
|
|
m_poblRecords->SortByTime();
|
|
SetAddressDisplay(CPreferences::ADD_NB_IP);
|
|
theApp.EndWaitCursor();
|
|
|
|
#ifdef WIN32S
|
|
APIERR err = FillListBox();
|
|
#else
|
|
Invalidate(); // Repaint
|
|
#endif // WIN32S
|
|
|
|
theApp.SetStatusBarText();
|
|
|
|
#ifdef WIN32S
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
}
|
|
#endif // WIN32S
|
|
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::SortByName()
|
|
{
|
|
theApp.SetStatusBarText(IDS_STATUS_SORTING);
|
|
theApp.BeginWaitCursor();
|
|
ASSERT(m_poblRecords != NULL);
|
|
m_poblRecords->SortByName();
|
|
SetAddressDisplay(CPreferences::ADD_NB_IP);
|
|
theApp.EndWaitCursor();
|
|
|
|
#ifdef WIN32S
|
|
APIERR err = FillListBox();
|
|
#else
|
|
Invalidate(); // Repaint
|
|
#endif // WIN32S
|
|
|
|
theApp.SetStatusBarText();
|
|
|
|
#ifdef WIN32S
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
}
|
|
#endif // WIN32S
|
|
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::GetAllPages(
|
|
BOOL fAddToListBox
|
|
)
|
|
{
|
|
if (!m_poblRecords->AllRecordsReadIn())
|
|
{
|
|
theApp.SetStatusBarText(m_nMessageId);
|
|
theApp.BeginWaitCursor();
|
|
APIERR err = m_poblRecords->GetAllNextPagesByName();
|
|
theApp.SetStatusBarText();
|
|
theApp.EndWaitCursor();
|
|
|
|
#ifdef WIN32S
|
|
if (err == ERROR_SUCCESS && fAddToListBox)
|
|
{
|
|
err = AddToListBox();
|
|
}
|
|
|
|
#else
|
|
if (err == ERROR_SUCCESS)
|
|
{
|
|
if (SetCount(m_poblRecords->GetSize()) == LB_ERRSPACE)
|
|
{
|
|
err = IDS_ERR_LISTBOX_FULL;
|
|
}
|
|
}
|
|
|
|
#endif // WIN32S
|
|
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
//
|
|
// Given a string, read entries until the string is either
|
|
// contained in the listbox, or at least one string of greater
|
|
// value is, or we got to the end of the data.
|
|
//
|
|
void
|
|
CStaticMappingsListBox::GetAllPagesUntil(
|
|
LPBYTE lpName,
|
|
BOOL fAddToListBox
|
|
)
|
|
{
|
|
if (lpName == NULL)
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (!m_poblRecords->AllRecordsReadIn())
|
|
{
|
|
theApp.SetStatusBarText(m_nMessageId);
|
|
theApp.BeginWaitCursor();
|
|
APIERR err = m_poblRecords->GetAllNextPagesUntil(lpName);
|
|
theApp.SetStatusBarText();
|
|
theApp.EndWaitCursor();
|
|
|
|
#ifdef WIN32S
|
|
if (err == ERROR_SUCCESS && fAddToListBox)
|
|
{
|
|
err = AddToListBox();
|
|
}
|
|
|
|
#else
|
|
if (err == ERROR_SUCCESS)
|
|
{
|
|
if (SetCount(m_poblRecords->GetSize()) == LB_ERRSPACE)
|
|
{
|
|
err = IDS_ERR_LISTBOX_FULL;
|
|
}
|
|
}
|
|
|
|
#endif // WIN32S
|
|
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
return;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Select the string we're looking for
|
|
// in the listbox
|
|
//
|
|
int iIdx = m_poblRecords->GetIndexOfName(lpName);
|
|
if (iIdx == -1)
|
|
{
|
|
return; // no data
|
|
}
|
|
if (m_fMultiSelect)
|
|
{
|
|
//
|
|
// Select only the one we just found
|
|
//
|
|
SetSel(-1, FALSE);
|
|
SetSel(iIdx, TRUE);
|
|
}
|
|
else
|
|
{
|
|
SetCurSel(iIdx);
|
|
}
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::DownPage(
|
|
BOOL fAddToListBox
|
|
)
|
|
{
|
|
if (!m_poblRecords->AllRecordsReadIn())
|
|
{
|
|
theApp.SetStatusBarText(m_nMessageId);
|
|
theApp.BeginWaitCursor();
|
|
APIERR err = m_poblRecords->GetNextPageByName();
|
|
theApp.EndWaitCursor();
|
|
theApp.SetStatusBarText();
|
|
|
|
#ifdef WIN32S
|
|
if (err == ERROR_SUCCESS && fAddToListBox)
|
|
{
|
|
err = AddToListBox();
|
|
}
|
|
#else
|
|
if (err == ERROR_SUCCESS)
|
|
{
|
|
if (SetCount(m_poblRecords->GetSize()) == LB_ERRSPACE)
|
|
{
|
|
err = IDS_ERR_LISTBOX_FULL;
|
|
}
|
|
}
|
|
|
|
#endif // WIN32S
|
|
|
|
if (err != ERROR_SUCCESS)
|
|
{
|
|
theApp.MessageBox(err);
|
|
}
|
|
}
|
|
}
|
|
|
|
#ifndef WIN32S
|
|
int
|
|
CStaticMappingsListBox::SetCount(
|
|
int nCount
|
|
)
|
|
{
|
|
//
|
|
// Set the count without disturbing the current
|
|
// listbox window's view window
|
|
//
|
|
int nView = GetTopIndex();
|
|
int nSel = m_fMultiSelect ? GetCaretIndex() : GetCurSel();
|
|
|
|
int nFirstSel = -1;
|
|
int cSelItems = 0;
|
|
|
|
if (m_fMultiSelect)
|
|
{
|
|
cSelItems = GetSelCount();
|
|
if (cSelItems)
|
|
{
|
|
GetSelItems(1, &nFirstSel);
|
|
}
|
|
}
|
|
|
|
SetRedraw(FALSE);
|
|
int nReturn = (int)::SendMessage(m_hWnd, LB_SETCOUNT, nCount, 0);
|
|
|
|
//
|
|
// And restore the view window
|
|
//
|
|
if (m_fMultiSelect)
|
|
{
|
|
if (cSelItems)
|
|
{
|
|
SetSel(nFirstSel, TRUE);
|
|
}
|
|
|
|
SetCaretIndex(nSel);
|
|
}
|
|
else
|
|
{
|
|
SetCurSel(nSel);
|
|
}
|
|
|
|
SetTopIndex(nView);
|
|
|
|
SetRedraw(TRUE);
|
|
|
|
return nReturn;
|
|
}
|
|
#endif // WIN32S
|
|
|
|
APIERR
|
|
CStaticMappingsListBox::CreateList(
|
|
PWINSINTF_ADD_T pOwnAdd,
|
|
PADDRESS_MASK pMask,
|
|
DWORD TypeOfRecs,
|
|
int nSortBy
|
|
)
|
|
{
|
|
APIERR err = 0;
|
|
|
|
TRY
|
|
{
|
|
//
|
|
// We only read the first few entries
|
|
//
|
|
theApp.SetStatusBarText(m_nMessageId);
|
|
theApp.BeginWaitCursor();
|
|
err = m_poblRecords->GetFirstPageByName(
|
|
pOwnAdd,
|
|
pMask,
|
|
TypeOfRecs
|
|
);
|
|
|
|
#ifndef WIN32S
|
|
if (SetCount(m_poblRecords->GetSize()) == LB_ERRSPACE)
|
|
{
|
|
err = IDS_ERR_LISTBOX_FULL;
|
|
}
|
|
|
|
#endif // WIN32s
|
|
|
|
theApp.EndWaitCursor();
|
|
theApp.SetStatusBarText();
|
|
|
|
//
|
|
// If the sortkey is not by Name, the list should
|
|
// be sorted now.
|
|
//
|
|
switch(nSortBy)
|
|
{
|
|
case CPreferences::SORTBY_IP:
|
|
SortByIp();
|
|
break;
|
|
|
|
case CPreferences::SORTBY_TYPE:
|
|
SortByType();
|
|
break;
|
|
|
|
case CPreferences::SORTBY_VERID:
|
|
SortByVersion();
|
|
break;
|
|
|
|
case CPreferences::SORTBY_TIME:
|
|
SortByTime();
|
|
break;
|
|
|
|
#ifdef WIN32S
|
|
default:
|
|
|
|
if (err == ERROR_SUCCESS)
|
|
{
|
|
err = FillListBox();
|
|
}
|
|
|
|
#endif // WIN32S
|
|
|
|
}
|
|
}
|
|
CATCH_ALL(e)
|
|
{
|
|
err = ::GetLastError();
|
|
}
|
|
END_CATCH_ALL
|
|
|
|
return err;
|
|
}
|
|
|
|
//
|
|
// Given the list of mappings, now start adding them
|
|
// to the listbox. Each listbox entry will actually
|
|
// be a pointer to the appropriate entry in the listbox.
|
|
// Notice that the listbox does NOT sort the entries,
|
|
// they are assumed to be sorted already.
|
|
//
|
|
#ifdef WIN32S
|
|
APIERR
|
|
CStaticMappingsListBox::FillListBox()
|
|
{
|
|
ASSERT(m_poblRecords != NULL);
|
|
const CRawMapping * pMapping;
|
|
|
|
theApp.BeginWaitCursor();
|
|
theApp.SetStatusBarText(IDS_STATUS_ADDING_TO_LISTBOX);
|
|
SetRedraw(FALSE);
|
|
int cOldSelection = m_fMultiSelect ? GetCaretIndex() : GetCurSel();
|
|
ResetContent();
|
|
int cItems = 0;
|
|
int nIdx;
|
|
int nMax = m_poblRecords->GetSize();
|
|
|
|
for (cItems = 0; cItems < nMax; ++cItems)
|
|
{
|
|
pMapping = (CRawMapping *)m_poblRecords->GetAt(cItems);
|
|
nIdx = AddString( (LPCSTR)pMapping );
|
|
if (nIdx == LB_ERRSPACE)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Remember the last position
|
|
//
|
|
m_nidxLastAdded = m_poblRecords->GetUpperBound();
|
|
|
|
SetRedraw(TRUE);
|
|
theApp.SetStatusBarText();
|
|
theApp.EndWaitCursor();
|
|
|
|
//
|
|
// Restore selection, or set to first item if no
|
|
// previous selection existed
|
|
//
|
|
int cNewIndex = cOldSelection != LB_ERR &&
|
|
cOldSelection < GetCount()
|
|
? cOldSelection : cItems ? 0 : -1;
|
|
|
|
if (cNewIndex != -1)
|
|
{
|
|
if (m_fMultiSelect)
|
|
{
|
|
SetSel( cNewIndex );
|
|
SetCaretIndex( cNewIndex );
|
|
}
|
|
else
|
|
{
|
|
SetCurSel(cNewIndex);
|
|
}
|
|
}
|
|
|
|
return nIdx == LB_ERRSPACE ? IDS_ERR_LISTBOX_FULL : ERROR_SUCCESS;
|
|
}
|
|
|
|
//
|
|
// Add the new elements to the listbox. FillListBox
|
|
// must have been called first, which will initialise
|
|
// the position pointer. This function will update
|
|
// the position pointer and add all elements to the
|
|
// listbox which have not yet been added.
|
|
//
|
|
// This function does not update the selection.
|
|
//
|
|
APIERR
|
|
CStaticMappingsListBox::AddToListBox()
|
|
{
|
|
ASSERT(m_poblRecords != NULL);
|
|
const CRawMapping * pMapping;
|
|
|
|
ASSERT(m_nidxLastAdded != -1);
|
|
|
|
//obli.SetPosition(m_posLastAdded);
|
|
theApp.BeginWaitCursor();
|
|
theApp.SetStatusBarText(IDS_STATUS_ADDING_TO_LISTBOX);
|
|
SetRedraw(FALSE);
|
|
|
|
int cItems = 0;
|
|
int nIdx = 0;
|
|
|
|
//
|
|
// We start by advancing one, since the last
|
|
// one was already added the last time.
|
|
//
|
|
|
|
if ( m_nidxLastAdded < m_poblRecords->GetUpperBound())
|
|
{
|
|
int nMax = m_poblRecords->GetSize();
|
|
|
|
for (int n = m_nidxLastAdded + 1; n < nMax; ++n)
|
|
{
|
|
pMapping = (CRawMapping *)m_poblRecords->GetAt(n);
|
|
ASSERT(pMapping != NULL);
|
|
nIdx = AddString( (LPCSTR)pMapping );
|
|
if (nIdx == LB_ERRSPACE)
|
|
{
|
|
break;
|
|
}
|
|
++cItems;
|
|
}
|
|
}
|
|
|
|
//
|
|
// Remember the last position
|
|
//
|
|
m_nidxLastAdded = m_poblRecords->GetUpperBound();
|
|
|
|
SetRedraw(TRUE);
|
|
theApp.SetStatusBarText();
|
|
theApp.EndWaitCursor();
|
|
|
|
return nIdx == LB_ERRSPACE ? IDS_ERR_LISTBOX_FULL : ERROR_SUCCESS;
|
|
}
|
|
|
|
#endif // WIN32S
|
|
|
|
APIERR
|
|
CStaticMappingsListBox::RefreshRecordByName(
|
|
PWINSINTF_ADD_T pWinsAdd,
|
|
CRawMapping * pRecord
|
|
)
|
|
{
|
|
ASSERT( m_poblRecords != NULL );
|
|
|
|
return m_poblRecords->RefreshRecordByName(pWinsAdd, pRecord);
|
|
}
|
|
|
|
BOOL
|
|
CStaticMappingsListBox::RemoveIndex(
|
|
int nIndex
|
|
)
|
|
{
|
|
m_poblRecords->RemoveAt(nIndex, 1);
|
|
|
|
DeleteString(nIndex);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::DrawItemEx(
|
|
CListBoxExDrawStruct& ds
|
|
)
|
|
{
|
|
//
|
|
// Use invisible static text to determine offset for
|
|
// ip and netbios name
|
|
//
|
|
UINT IP_TAB;
|
|
UINT NB_TAB;
|
|
|
|
CWnd* hParent = GetParent();
|
|
|
|
int nRightTab = m_nTab ? m_nTab : ds.m_Rect.right;
|
|
|
|
RECT r, pr;
|
|
(hParent->GetDlgItem(IDC_STATIC_FLT_PROMPT))->GetWindowRect( &pr );
|
|
|
|
(hParent->GetDlgItem(IDC_STATIC_NB_TAB))->GetWindowRect( &r );
|
|
NB_TAB = r.left - pr.left;
|
|
|
|
(hParent->GetDlgItem(IDC_STATIC_IP_TAB))->GetWindowRect( &r );
|
|
IP_TAB = r.left - pr.left;
|
|
|
|
#ifdef WIN32S
|
|
CRawMapping * p = (CRawMapping *)ds.m_ItemData;
|
|
#else
|
|
ASSERT(ds.m_ItemIndex <= m_poblRecords->GetUpperBound());
|
|
if (ds.m_ItemIndex > m_poblRecords->GetUpperBound())
|
|
{
|
|
//
|
|
// BUGBUG: It seems that we're receiving a drawitem
|
|
// message in certain rare instances when
|
|
// there is no data available to be
|
|
// drawn. If no data is available,
|
|
// exit gracefully.
|
|
//
|
|
TRACEEOLID("Nothing to draw in listbox");
|
|
return;
|
|
}
|
|
CRawMapping * p = (CRawMapping *)m_poblRecords->GetAt(ds.m_ItemIndex);
|
|
#endif // WIN32S
|
|
|
|
ASSERT(p != NULL);
|
|
|
|
CDC* pBmpDC = (CDC*)&ds.m_pResources->DcBitMap();
|
|
int bmh = ds.m_pResources->BitmapHeight();
|
|
int bmw = ds.m_pResources->BitmapWidth();
|
|
|
|
int nOffset = p->GetMappingType();
|
|
ASSERT(nOffset >= WINSINTF_E_UNIQUE && nOffset <= WINSINTF_E_MULTIHOMED);
|
|
|
|
//
|
|
// select bitmap from resource
|
|
//
|
|
int bm_h = (ds.m_Sel)?0:bmh;
|
|
int bm_w = bmw*nOffset;
|
|
ds.m_pDC->BitBlt( ds.m_Rect.left+1, ds.m_Rect.top, bmw, bmh, pBmpDC, bm_w, bm_h, SRCCOPY );
|
|
|
|
CString strNetBIOSName(theApp.CleanNetBIOSName(
|
|
p->GetNetBIOSName(),
|
|
TRUE, // Expand
|
|
TRUE, // Truncate
|
|
theApp.m_wpPreferences.IsLanmanCompatible(),
|
|
TRUE, // name is OEM
|
|
FALSE, // No double backslash
|
|
p->GetNetBIOSNameLength()));
|
|
|
|
//
|
|
// Released multihomed addresses no longer
|
|
// have any IP addresses.
|
|
//
|
|
CIpAddress ip(p->GetPrimaryIpAddress());
|
|
|
|
switch(m_nAddressDisplay)
|
|
{
|
|
case CPreferences::ADD_NB_IP:
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, IP_TAB,
|
|
ds.m_Rect.bottom, strNetBIOSName);
|
|
|
|
if (p->HasIpAddress())
|
|
{
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + IP_TAB, ds.m_Rect.top, nRightTab,
|
|
ds.m_Rect.bottom, (CString)ip);
|
|
}
|
|
break;
|
|
|
|
case CPreferences::ADD_IP_NB:
|
|
if (p->HasIpAddress())
|
|
{
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + bmw + 3, ds.m_Rect.top, NB_TAB,
|
|
ds.m_Rect.bottom, (CString)ip);
|
|
}
|
|
|
|
ColumnText(ds.m_pDC, ds.m_Rect.left + NB_TAB, ds.m_Rect.top, nRightTab,
|
|
ds.m_Rect.bottom, strNetBIOSName);
|
|
|
|
break;
|
|
|
|
default:
|
|
ASSERT(0 && "Invalid Address Dislay Value");
|
|
}
|
|
}
|
|
|
|
void
|
|
CStaticMappingsListBox::OnVScroll(
|
|
UINT nSBCode,
|
|
UINT nPos,
|
|
CScrollBar* pScrollBar
|
|
)
|
|
{
|
|
int nMin, nMax;
|
|
|
|
switch(nSBCode)
|
|
{
|
|
case SB_LINEDOWN:
|
|
case SB_PAGEDOWN:
|
|
nPos = GetScrollPos(SB_VERT);
|
|
//
|
|
// No break is deliberate
|
|
//
|
|
case SB_THUMBTRACK:
|
|
case SB_THUMBPOSITION:
|
|
GetScrollRange(SB_VERT, &nMin, &nMax);
|
|
if (nMax <= (int)nPos + PAGE_BOUNDARY)
|
|
{
|
|
DownPage(TRUE);
|
|
}
|
|
break;
|
|
|
|
case SB_BOTTOM:
|
|
GetAllPages(TRUE);
|
|
break;
|
|
}
|
|
|
|
CListBox::OnVScroll(nSBCode, nPos, pScrollBar);
|
|
}
|
|
|
|
int
|
|
CStaticMappingsListBox::CompareItem(
|
|
LPCOMPAREITEMSTRUCT lpCIS
|
|
)
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
//
|
|
// All mappings
|
|
//
|
|
CAllMappingsListBox::CAllMappingsListBox(
|
|
int nMessageId,
|
|
BOOL fMultiSelect,
|
|
int nAddressDisplay,
|
|
DWORD dwPageSize,
|
|
DWORD dwLargePageSize
|
|
)
|
|
: CStaticMappingsListBox(nMessageId, fMultiSelect, nAddressDisplay, dwPageSize, dwLargePageSize)
|
|
{
|
|
}
|
|
|
|
void
|
|
CAllMappingsListBox::DrawItemEx(
|
|
CListBoxExDrawStruct& ds
|
|
)
|
|
{
|
|
RECT r, pr;
|
|
UINT STATE_TAB, STATIC_TAB, TIME_TAB, VERSION_TAB;
|
|
|
|
CWnd* hParent = GetParent();
|
|
ASSERT(hParent != NULL);
|
|
|
|
(hParent->GetDlgItem(IDC_STATIC_FLT_PROMPT))->GetWindowRect( &pr );
|
|
|
|
(hParent->GetDlgItem(IDC_STATIC_STATE))->GetWindowRect( &r );
|
|
STATE_TAB = r.left - pr.left;
|
|
(hParent->GetDlgItem(IDC_STATIC_STATIC))->GetWindowRect( &r );
|
|
STATIC_TAB = r.left - pr.left;
|
|
(hParent->GetDlgItem(IDC_STATIC_TIME))->GetWindowRect( &r );
|
|
TIME_TAB = r.left - pr.left;
|
|
(hParent->GetDlgItem(IDC_STATIC_VERSION))->GetWindowRect( &r );
|
|
VERSION_TAB = r.left - pr.left;
|
|
|
|
SetTab(STATE_TAB);
|
|
//
|
|
// Display IP address and NetBIOS Name
|
|
//
|
|
CStaticMappingsListBox::DrawItemEx(ds);
|
|
|
|
CBitmap bitmap;
|
|
bitmap.LoadOEMBitmap(OBM_CHECK);
|
|
|
|
CDC cdcMem;
|
|
cdcMem.CreateCompatibleDC(ds.m_pDC);
|
|
cdcMem.SelectObject(&bitmap);
|
|
cdcMem.SetMapMode(ds.m_pDC->GetMapMode());
|
|
|
|
BITMAP bm;
|
|
POINT ptSize, ptOrg;
|
|
|
|
bitmap.GetObject(sizeof(BITMAP), (LPSTR) &bm);
|
|
ptSize.x = bm.bmWidth;
|
|
ptSize.y = bm.bmHeight;
|
|
ds.m_pDC->DPtoLP(&ptSize, 1);
|
|
|
|
ptOrg.x = 0;
|
|
ptOrg.y = 0;
|
|
cdcMem.DPtoLP(&ptOrg, 1);
|
|
|
|
CBitmap bitmap2;
|
|
bitmap2.LoadBitmap(IDB_TOMBSTONE);
|
|
|
|
CDC cdcMem2;
|
|
cdcMem2.CreateCompatibleDC(ds.m_pDC);
|
|
cdcMem2.SelectObject(&bitmap2);
|
|
cdcMem2.SetMapMode(ds.m_pDC->GetMapMode());
|
|
|
|
BITMAP bm2;
|
|
POINT ptSize2, ptOrg2;
|
|
|
|
bitmap2.GetObject(sizeof(BITMAP), (LPSTR) &bm2);
|
|
ptSize2.x = bm2.bmWidth;
|
|
ptSize2.y = bm2.bmHeight;
|
|
ds.m_pDC->DPtoLP(&ptSize2, 1);
|
|
|
|
ptOrg2.x = 0;
|
|
ptOrg2.y = 0;
|
|
cdcMem2.DPtoLP(&ptOrg2, 1);
|
|
|
|
#ifdef WIN32S
|
|
CRawMapping * p = (CRawMapping *)ds.m_ItemData;
|
|
#else
|
|
CRawMapping * p = (CRawMapping *)m_poblRecords->GetAt(ds.m_ItemIndex);
|
|
#endif // WIN32S
|
|
ASSERT(p != NULL);
|
|
|
|
switch (p->GetState())
|
|
{
|
|
case WINSINTF_E_ACTIVE:
|
|
ds.m_pDC->BitBlt (ds.m_Rect.left + STATE_TAB,
|
|
ds.m_Rect.top,
|
|
ptSize.x, ptSize.y,
|
|
&cdcMem,
|
|
ptOrg.x,
|
|
ptOrg.y,
|
|
SRCCOPY
|
|
);
|
|
break;
|
|
|
|
case WINSINTF_E_RELEASED:
|
|
ds.m_pDC->TextOut(ds.m_Rect.left + STATE_TAB, ds.m_Rect.top, " -");
|
|
break;
|
|
|
|
case WINSINTF_E_TOMBSTONE:
|
|
ds.m_pDC->BitBlt (ds.m_Rect.left + STATE_TAB,
|
|
ds.m_Rect.top,
|
|
ptSize2.x,
|
|
ptSize2.y,
|
|
&cdcMem2,
|
|
ptOrg2.x,
|
|
ptOrg2.y,
|
|
SRCCOPY
|
|
);
|
|
break;
|
|
|
|
case WINSINTF_E_DELETED:
|
|
break;
|
|
}
|
|
|
|
if (p->IsStatic())
|
|
{
|
|
ds.m_pDC->BitBlt (ds.m_Rect.left + STATIC_TAB,
|
|
ds.m_Rect.top,
|
|
ptSize.x,
|
|
ptSize.y,
|
|
&cdcMem,
|
|
ptOrg.x,
|
|
ptOrg.y,
|
|
SRCCOPY
|
|
);
|
|
}
|
|
|
|
CIntlTime itmTimeStamp(p->GetTimeStamp());
|
|
ds.m_pDC->TextOut(ds.m_Rect.left + TIME_TAB,
|
|
ds.m_Rect.top,
|
|
(CString)itmTimeStamp);
|
|
|
|
char * pch = CWinssListBox::LongLongToText(p->GetVersion());
|
|
ds.m_pDC->TextOut(ds.m_Rect.left + VERSION_TAB, ds.m_Rect.top, pch);
|
|
}
|