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.
694 lines
20 KiB
694 lines
20 KiB
// IPEDIT.CPP
|
|
|
|
#include "common.h"
|
|
|
|
const TCHAR szClassEdit[] = "Edit";
|
|
const TCHAR szClassListBox[] = "ListBox";
|
|
|
|
const TCHAR szClassIpEdit[] = "IpEdit";
|
|
const TCHAR szClassIpList[] = "IpList";
|
|
|
|
WNDPROC lpfnEditOld;
|
|
WNDPROC lpfnListBoxOld;
|
|
int ibListBoxOld;
|
|
int ibEditOld;
|
|
|
|
static TCHAR szIpNone[32];
|
|
|
|
#define tIpValue 0
|
|
#define tIpRange 1 // Later
|
|
#define tIpNone 2
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
int ConvertIpAddrToString(
|
|
IP_ADDRESS dwIp, // IN
|
|
TCHAR szIp[]) // OUT
|
|
{
|
|
TCHAR *szTmp;
|
|
szTmp = inet_ntoa (*(in_addr *)&dwIp);
|
|
strcpy (szIp, szTmp);
|
|
return (strlen(szIp));
|
|
} // ConvertIpAddrToString
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
IP_ADDRESS ConvertStringToIpAddr(const TCHAR szIp[])
|
|
{
|
|
IP_ADDRESS dwIpAddress = 0;
|
|
|
|
dwIpAddress = inet_addr (szIp);
|
|
return dwIpAddress;
|
|
|
|
} // ConvertStringToIpAddr
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IpListIpEdit_SetButtons()
|
|
//
|
|
// Attach buttons to both IpList and IpEdit controls
|
|
// NOTE: move up and move down are optional
|
|
//
|
|
void IpListIpEdit_SetButtons(
|
|
HWND hwndIpList, // Window handle of the IpList control
|
|
HWND hwndIpEdit, // Window handle of the IpEdit control
|
|
UINT wIdBtnMoveUp, // Control ID of the MoveUp button
|
|
UINT wIdBtnMoveDown, // Control ID of the MoveDown button
|
|
UINT wIdBtnAdd, // Control ID of the Add button
|
|
UINT wIdBtnRemove) // Control ID of the Remove button
|
|
{
|
|
HWND hwndParent; // Parent of hwndIpList (ie, dialog)
|
|
HWND hwndT;
|
|
|
|
// Make sure hwndIpList is of class "IpList"
|
|
AssertClassName(hwndIpList, szClassIpList);
|
|
// Make sure hwndIpEdit is of class "IpEdit"
|
|
AssertClassName(hwndIpEdit, szClassIpEdit);
|
|
hwndParent = GetParent(hwndIpList);
|
|
Assert(IsWindow(hwndParent));
|
|
if (wIdBtnMoveUp) {
|
|
IpList_SetHwndBtnMoveUp(hwndIpList,
|
|
HGetDlgItem(hwndParent, wIdBtnMoveUp));
|
|
}
|
|
if (wIdBtnMoveDown) {
|
|
IpList_SetHwndBtnMoveDown(hwndIpList,
|
|
HGetDlgItem(hwndParent, wIdBtnMoveDown));
|
|
}
|
|
IpList_SetHwndBtnRemove(hwndIpList,
|
|
HGetDlgItem(hwndParent, wIdBtnRemove));
|
|
hwndT = HGetDlgItem(hwndParent, wIdBtnAdd);
|
|
IpList_SetHwndBtnAdd(hwndIpList, hwndT);
|
|
IpEdit_SetHwndBtnAdd(hwndIpEdit, hwndT);
|
|
IpList_SetHwndIpEdit(hwndIpList, hwndIpEdit);
|
|
} // IpListIpEdit_SetButtons
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IpListIpEdit_HandleButtonCommand()
|
|
//
|
|
// Handle the WM_COMMAND message generated by any of MoveUp, MoveDown,
|
|
// Add or Remove buttons.
|
|
// This function is only to save code in the dialogproc - nothing useful.
|
|
//
|
|
void IpListIpEdit_HandleButtonCommand(HWND hwndIpList, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
HWND hwndT;
|
|
|
|
if (HIWORD(wParam))
|
|
{
|
|
// If there is a notification code, then the message is not
|
|
// comming from a button.
|
|
// Some Edit control send WM_COMMAND messages before the
|
|
// WM_INITDIALOG, so by checking the notification code, we
|
|
// avoid having hwndIpList to be NULL.
|
|
return;
|
|
}
|
|
AssertClassName(hwndIpList, szClassIpList);
|
|
Assert(IsWindow((HWND)lParam));
|
|
hwndT = IpList_GetHwndBtnAdd(hwndIpList);
|
|
if (hwndT == (HWND)lParam || IpList_GetHwndBtnRemove(hwndIpList) == (HWND)lParam)
|
|
{
|
|
HWND hwndIpEdit = IpList_GetHwndIpEdit(hwndIpList);
|
|
Assert(IsWindow(hwndIpEdit));
|
|
AssertClassName(hwndIpEdit, szClassIpEdit);
|
|
if (hwndT == (HWND)lParam)
|
|
{
|
|
// Add button pressed
|
|
IpList_AddAddress(hwndIpList, -1, IpEdit_GetAddress(hwndIpEdit));
|
|
IpEdit_ClearAddress(hwndIpEdit);
|
|
SetFocus(hwndIpEdit);
|
|
}
|
|
else
|
|
{
|
|
// Remove button pressed
|
|
IP_ADDRESS dwIpAddress;
|
|
IpList_RemoveAddress(hwndIpList, -1, OUT &dwIpAddress);
|
|
IpEdit_SetAddress(hwndIpEdit, dwIpAddress);
|
|
}
|
|
}
|
|
else if (IpList_GetHwndBtnMoveUp(hwndIpList) == (HWND)lParam)
|
|
{
|
|
IpList_MoveUp(hwndIpList);
|
|
}
|
|
else if (IpList_GetHwndBtnMoveDown(hwndIpList) == (HWND)lParam)
|
|
{
|
|
IpList_MoveDown(hwndIpList);
|
|
}
|
|
} // IpListIpEdit_HandleButtonCommand
|
|
|
|
|
|
void IpList_EnableWindow(HWND hwndIpList, BOOL fEnable)
|
|
{
|
|
// Make sure hwndIpList is of class "IpList"
|
|
AssertClassName(hwndIpList, szClassIpList);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// IpList_EnableButtons()
|
|
//
|
|
// Enable/disable IpList's buttons according to the listbox state.
|
|
//
|
|
static void IpList_EnableButtons(HWND hwndIpList)
|
|
{
|
|
// Make sure hwndIpList is of class "IpList"
|
|
AssertClassName(hwndIpList, szClassIpList);
|
|
const HWND hwndBtnUp = IpList_GetHwndBtnMoveUp(hwndIpList);
|
|
const HWND hwndBtnDown = IpList_GetHwndBtnMoveDown(hwndIpList);
|
|
const HWND hwndBtnRemove = IpList_GetHwndBtnRemove(hwndIpList);
|
|
BOOL fIsEnabled = IsWindowEnabled(hwndIpList);
|
|
|
|
LRESULT iCurSel = LSendMessage(hwndIpList, LB_GETCURSEL, 0, 0);
|
|
if (hwndBtnUp)
|
|
{
|
|
Assert(IsWindow(hwndBtnUp));
|
|
Assert(LB_ERR < 0);
|
|
EnableWindow(hwndBtnUp, fIsEnabled && (iCurSel > 0));
|
|
} // if
|
|
if (hwndBtnDown)
|
|
{
|
|
Assert(IsWindow(hwndBtnDown));
|
|
if (iCurSel == LB_ERR)
|
|
EnableWindow(hwndBtnDown, FALSE);
|
|
else
|
|
EnableWindow(hwndBtnDown, fIsEnabled &&
|
|
(iCurSel + 1 < LSendMessage(hwndIpList, LB_GETCOUNT, 0, 0)));
|
|
}
|
|
BOOL fListEmpty = IpList_GetFlags(hwndIpList) & IpList_mskfIsEmpty;
|
|
if (hwndBtnRemove)
|
|
{
|
|
Assert(IsWindow(hwndBtnRemove));
|
|
EnableWindow(hwndBtnRemove, fIsEnabled && (!fListEmpty && iCurSel != LB_ERR));
|
|
}
|
|
CallWindowProc(lpfnListBoxOld, hwndIpList, WM_ENABLE, fIsEnabled && !fListEmpty, 0);
|
|
} // IpList_EnableButtons
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
LRESULT CALLBACK WndProcIpList(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
char szT[32];
|
|
int i;
|
|
IP_ADDRESS * pdwIpAddr;
|
|
LRESULT lResult;
|
|
DWORD dwFlags;
|
|
|
|
AssertSz1(IsWindow(hwnd), "WndProcIpList: Invalid window handle hwnd=0x%08X", hwnd);
|
|
Assert(lpfnListBoxOld != NULL);
|
|
dwFlags = IpList_GetFlags(hwnd);
|
|
switch (uMsg)
|
|
{
|
|
case LB_SETSEL:
|
|
// REVIEW: Get rid of this trace
|
|
Trace0(1, "\nLB_SETSEL");
|
|
lResult = CallWindowProc(lpfnListBoxOld, hwnd, LB_SETSEL, wParam, lParam);
|
|
IpList_EnableButtons(hwnd);
|
|
return lResult;
|
|
|
|
case LB_GETCOUNT:
|
|
if (dwFlags & IpList_mskfIsEmpty)
|
|
return 0;
|
|
return CallWindowProc(lpfnListBoxOld, hwnd, LB_GETCOUNT, 0, 0);
|
|
|
|
case LB_ADDSTRING:
|
|
Assert(FALSE);
|
|
break;
|
|
|
|
case IpList_WM_ADDADDRESS:
|
|
if (wParam == (WPARAM)-1)
|
|
wParam = CallWindowProc(lpfnListBoxOld, hwnd, LB_GETCURSEL, 0, 0);
|
|
// Fall Through //
|
|
|
|
case IpList_WM_INSERTADDRESS:
|
|
ConvertIpAddrToString(lParam, szT);
|
|
Assert(lstrlen(szT) < sizeof(szT));
|
|
if (dwFlags & IpList_mskfIsEmpty)
|
|
{
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_RESETCONTENT, 0, 0);
|
|
dwFlags &= ~IpList_mskfIsEmpty;
|
|
}
|
|
// If nothing is selected, append the address at the end of the list
|
|
Assert(LB_ERR == -1);
|
|
lResult = CallWindowProc(lpfnListBoxOld, hwnd, LB_INSERTSTRING, wParam, (LPARAM)szT);
|
|
Report(lResult >= 0);
|
|
Report(tIpValue == CallWindowProc(lpfnListBoxOld, hwnd, LB_GETITEMDATA, lResult, 0));
|
|
IpList_SetFlags(hwnd, dwFlags | IpList_mskfIsDirty);
|
|
IpList_EnableButtons(hwnd);
|
|
return lResult;
|
|
|
|
case IpList_WM_REMOVEADDRESS:
|
|
if (wParam == (WPARAM)-1)
|
|
wParam = CallWindowProc(lpfnListBoxOld, hwnd, LB_GETCURSEL, 0, 0);
|
|
Assert(wParam != LB_ERR);
|
|
if (lParam)
|
|
{
|
|
Assert(CallWindowProc(lpfnListBoxOld, hwnd, LB_GETTEXTLEN, wParam, 0) < sizeof(szT));
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_GETTEXT, wParam, (LPARAM)szT);
|
|
*(DWORD *)lParam = ConvertStringToIpAddr(szT);
|
|
}
|
|
lResult = CallWindowProc(lpfnListBoxOld, hwnd, LB_DELETESTRING, wParam, 0);
|
|
Assert(lResult != LB_ERR);
|
|
if (lResult == 0)
|
|
{
|
|
CchLoadString (IDS_IP_NONE, szIpNone, LENGTH(szIpNone));
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_INSERTSTRING, 0, (LPARAM)szIpNone);
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_SETITEMDATA, 0, tIpNone);
|
|
dwFlags |= IpList_mskfIsEmpty;
|
|
}
|
|
IpList_SetFlags(hwnd, dwFlags | IpList_mskfIsDirty);
|
|
IpList_EnableButtons(hwnd);
|
|
return lResult;
|
|
|
|
case IpList_WM_MOVEADDRESS:
|
|
Trace0(lParam ? mskTraceNone : mskTraceInfo, "\nINFO: Moving address by 0 element(s)");
|
|
if (wParam == (WPARAM)-1)
|
|
wParam = CallWindowProc(lpfnListBoxOld, hwnd, LB_GETCURSEL, 0, 0);
|
|
Assert(wParam != LB_ERR);
|
|
lResult = CallWindowProc(lpfnListBoxOld, hwnd, LB_GETTEXT, wParam, (LPARAM)szT);
|
|
Assert(tIpValue == CallWindowProc(lpfnListBoxOld, hwnd, LB_GETITEMDATA, wParam, 0));
|
|
Assert(lResult != LB_ERR);
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_DELETESTRING, wParam, 0);
|
|
Assert(lResult != LB_ERR);
|
|
lResult = CallWindowProc(lpfnListBoxOld, hwnd, LB_INSERTSTRING, wParam + lParam, (LPARAM)szT);
|
|
AssertSz(lResult != LB_ERR, "Value out of range");
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_SETCURSEL, lResult, 0);
|
|
Assert(lResult != LB_ERR);
|
|
IpList_SetFlags(hwnd, dwFlags | IpList_mskfIsDirty);
|
|
IpList_EnableButtons(hwnd);
|
|
return 0;
|
|
|
|
case IpList_WM_SETLIST:
|
|
// Prevent the window from repainting
|
|
CallWindowProc(lpfnListBoxOld, hwnd, WM_SETREDRAW, FALSE, 0);
|
|
// Flush the content of the previous list
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_RESETCONTENT, 0, 0);
|
|
if (wParam)
|
|
{
|
|
AssertSz((IP_ADDRESS *)lParam != NULL, "Invalid memory address");
|
|
pdwIpAddr = ((IP_ADDRESS *)lParam) + wParam;
|
|
// Insert the items from last to fisrt
|
|
while (wParam)
|
|
{
|
|
pdwIpAddr--;
|
|
ConvertIpAddrToString(*pdwIpAddr, szT);
|
|
Assert(lstrlen(szT) < sizeof(szT));
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_INSERTSTRING, 0, (LPARAM)szT);
|
|
Assert(tIpValue == CallWindowProc(lpfnListBoxOld, hwnd, LB_GETITEMDATA, 0, 0));
|
|
wParam--;
|
|
} // while
|
|
dwFlags &= ~IpList_mskfIsEmpty;
|
|
}
|
|
else
|
|
{
|
|
CchLoadString (IDS_IP_NONE, szIpNone, LENGTH(szIpNone));
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_INSERTSTRING, 0, (LPARAM)szIpNone);
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_SETITEMDATA, 0, tIpNone);
|
|
dwFlags |= IpList_mskfIsEmpty;
|
|
}
|
|
CallWindowProc(lpfnListBoxOld, hwnd, WM_SETREDRAW, TRUE, 0);
|
|
IpList_SetFlags(hwnd, dwFlags & ~IpList_mskfIsDirty);
|
|
IpList_EnableButtons(hwnd);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
return 0;
|
|
|
|
case IpList_WM_GETLIST:
|
|
if (wParam != IpList_GetList_ALLOCATEMEMORY)
|
|
{
|
|
pdwIpAddr = (IP_ADDRESS *)lParam;
|
|
Assert(pdwIpAddr);
|
|
Assert(wParam == (WPARAM)LSendMessage(hwnd, LB_GETCOUNT, 0, 0));
|
|
Assert((int)wParam >= 0);
|
|
}
|
|
else
|
|
{
|
|
wParam = (WPARAM)LSendMessage(hwnd, LB_GETCOUNT, 0, 0);
|
|
Assert((int)wParam >= 0);
|
|
Assert(lParam);
|
|
// Allocate the memory
|
|
pdwIpAddr = (IP_ADDRESS *)Malloc(wParam * sizeof(IP_ADDRESS));
|
|
ReportFSz(pdwIpAddr != NULL, "IpList: Out of memory");
|
|
*(IP_ADDRESS **)lParam = pdwIpAddr;
|
|
if (pdwIpAddr == NULL)
|
|
return 0;
|
|
}
|
|
// Insert the items from last to fisrt
|
|
for (i = 0; i < (int)wParam; i++)
|
|
{
|
|
Assert(CallWindowProc(lpfnListBoxOld, hwnd, LB_GETTEXTLEN, i, 0) < sizeof(szT));
|
|
CallWindowProc(lpfnListBoxOld, hwnd, LB_GETTEXT, i, (LPARAM)szT);
|
|
Assert(tIpValue == CallWindowProc(lpfnListBoxOld, hwnd, LB_GETITEMDATA, i, 0));
|
|
*pdwIpAddr++ = ConvertStringToIpAddr(szT);
|
|
}
|
|
Assert((WPARAM)i == wParam);
|
|
return wParam;
|
|
|
|
case WM_MOUSEMOVE:
|
|
if ((wParam & MK_LBUTTON) == 0)
|
|
break;
|
|
|
|
case WM_ENABLE:
|
|
case WM_KEYDOWN:
|
|
case WM_LBUTTONDOWN:
|
|
CallWindowProc(lpfnListBoxOld, hwnd, uMsg, wParam, lParam);
|
|
IpList_EnableButtons(hwnd);
|
|
return 0;
|
|
|
|
default:
|
|
break;
|
|
} // swtich
|
|
|
|
return CallWindowProc(lpfnListBoxOld, hwnd, uMsg, wParam, lParam);
|
|
} // WndProcIpList
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
LRESULT CALLBACK WndProcEditNumber(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
Assert(lpfnEditOld);
|
|
|
|
switch (uMsg)
|
|
{
|
|
case WM_CHAR:
|
|
if (wParam == VK_BACK)
|
|
break;
|
|
if(wParam >= '0' && wParam <= '9')
|
|
{
|
|
CallWindowProc(lpfnEditOld, hwnd, WM_CHAR, wParam, lParam);
|
|
}
|
|
if (wParam == ' ' || wParam == '.')
|
|
(void)LSendMessage(GetParent(hwnd), UN_KEYDOWN, VK_RIGHT, (LPARAM)hwnd);
|
|
// Eat the character
|
|
return 0;
|
|
|
|
case WM_KEYDOWN:
|
|
if (0 != LSendMessage(GetParent(hwnd), UN_KEYDOWN, wParam, (LPARAM)hwnd))
|
|
return 0;
|
|
break;
|
|
} // switch
|
|
|
|
return CallWindowProc(lpfnEditOld, hwnd, uMsg, wParam, lParam);
|
|
} // WndProcEditNumber
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void IpEdit_EnableAddButton(HWND hwndIpEdit, HWND hwndBtn)
|
|
{
|
|
AssertClassName(hwndIpEdit, szClassIpEdit);
|
|
if (hwndBtn)
|
|
{
|
|
Assert(IsWindow(hwndBtn));
|
|
// Enable the button if the IpAddress is valid
|
|
|
|
EnableWindow(hwndBtn, LSendMessage(hwndIpEdit, IpEdit_WM_ISADDRESSVALID, 0, 0));
|
|
}
|
|
} // IpEdit_EnableAddButton
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
LRESULT CALLBACK WndProcIpEdit(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
|
{
|
|
IPEDITDATA * pData;
|
|
TCHAR * pch;
|
|
TCHAR szT[32];
|
|
int i;
|
|
|
|
AssertSz1(IsWindow(hwnd), "WndProcIpEdit: Invalid window handle hwnd=0x%08X", hwnd);
|
|
Assert(lpfnEditOld != NULL);
|
|
pData = (IPEDITDATA *)GetWindowLongFrom(hwnd, ibIpEditData, szClassIpEdit);
|
|
switch (uMsg)
|
|
{
|
|
|
|
case WM_SETTEXT:
|
|
// Formats allowed: "n.n.n.n" ; n=="" or 0<=n<=255
|
|
// "" ; Clear the text
|
|
Assert(pData);
|
|
pch = (TCHAR *)lParam;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
int j = 0;
|
|
if (pch != NULL)
|
|
{
|
|
while (*pch && *pch != _W'.')
|
|
{
|
|
Assert(*pch >= _W'0' && *pch <= _W'9');
|
|
Assert(j < 3);
|
|
szT[j++] = *pch++;
|
|
}
|
|
if (*pch == _W'.')
|
|
pch++;
|
|
}
|
|
szT[j] = 0; // Append a null terminator
|
|
FSetWindowText(pData->rgChild[i].hwnd, szT);
|
|
} // for
|
|
IpEdit_EnableAddButton(hwnd, pData->hwndBtnAdd);
|
|
return TRUE;
|
|
|
|
case WM_GETTEXT:
|
|
case WM_GETTEXTLENGTH:
|
|
// Return the text in a format "n.n.n.n" where n=="" or 0<=n<=255
|
|
Assert(pData);
|
|
pch = szT;
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
if (i)
|
|
*pch++ = _W'.';
|
|
CchGetWindowText(pData->rgChild[i].hwnd, pch, 2);
|
|
while (*pch)
|
|
pch++;
|
|
} // for
|
|
Assert(lstrlen(szT) < 16);
|
|
if (lParam)
|
|
{
|
|
Assert(wParam >= 16);
|
|
lstrcpy((char *)lParam, szT);
|
|
}
|
|
return lstrlen(szT);
|
|
|
|
case IpEdit_WM_ISADDRESSVALID:
|
|
Assert(lParam == 0);
|
|
// Fall Throuth //
|
|
|
|
case IpEdit_WM_GETADDRESS:
|
|
Assert(wParam == 0);
|
|
{
|
|
DWORD dwIpAddress = 0;
|
|
BOOL fIpFieldEmpty = FALSE;
|
|
for (i = 3; i >= 0; i--)
|
|
{
|
|
dwIpAddress <<= 8; // Shift to the next byte
|
|
CchGetWindowText(pData->rgChild[i].hwnd, szT, 4);
|
|
if (!szT[0])
|
|
fIpFieldEmpty = TRUE;
|
|
AssertSz(atol(szT) <= 255, "You are getting an invalid IP Address");
|
|
dwIpAddress |= atol(szT);
|
|
}
|
|
if (lParam)
|
|
*(BOOL *)lParam = fIpFieldEmpty;
|
|
if (uMsg == IpEdit_WM_GETADDRESS)
|
|
return dwIpAddress;
|
|
// Otherwise process message IpEdit_WM_ISADDRESSVALID
|
|
if (fIpFieldEmpty && (pData->dwFlags & IpEdit_mskfEmptyFieldsValid) == 0)
|
|
return (BOOL)FALSE;
|
|
return (BOOL)(dwIpAddress || (pData->dwFlags & IpEdit_mskfZeroIpValid));
|
|
}
|
|
|
|
case IpEdit_WM_SETADDRESS:
|
|
Assert(wParam == 0);
|
|
ConvertIpAddrToString(lParam, szT);
|
|
Assert(lstrlen(szT) < LENGTH(szT));
|
|
FSetWindowText(hwnd, szT);
|
|
return 0;
|
|
|
|
case IpEdit_WM_CLEARADDRESS:
|
|
FSetWindowText(hwnd, NULL);
|
|
return 0;
|
|
|
|
case WM_SETFOCUS:
|
|
Assert(pData);
|
|
SetFocus(pData->rgChild[0].hwnd);
|
|
InvalidateRect(hwnd, NULL, TRUE);
|
|
return 0;
|
|
|
|
case WM_ENABLE:
|
|
Assert(pData);
|
|
IpEdit_EnableAddButton(hwnd, pData->hwndBtnAdd);
|
|
// Fall Through //
|
|
|
|
case WM_SETFONT:
|
|
case EM_SETREADONLY:
|
|
Assert(pData != NULL);
|
|
// Forward the message to the children
|
|
for (i = 0; i < 4; i++)
|
|
LSendMessage(pData->rgChild[i].hwnd, uMsg, wParam, lParam);
|
|
break;
|
|
|
|
case WM_COMMAND:
|
|
Assert(pData);
|
|
if (pData->dwFlags & IpEdit_mskfNoNofity)
|
|
return 0;
|
|
switch(HIWORD(wParam))
|
|
{
|
|
case EN_SETFOCUS:
|
|
if (pData->dwFlags & IpEdit_mskfHasFocus)
|
|
return 0;
|
|
pData->dwFlags |= IpEdit_mskfHasFocus;
|
|
break;
|
|
case EN_KILLFOCUS:
|
|
Assert(pData->dwFlags & IpEdit_mskfHasFocus);
|
|
// The idea here is to find out who got the focus. If none of
|
|
// the childs has the focus, then we obviously lost the focus,
|
|
// so we need to send the notification message
|
|
if (IsChild(hwnd, GetFocus()))
|
|
return 0;
|
|
// Otherwise, we lost the focus
|
|
pData->dwFlags &= ~IpEdit_mskfHasFocus;
|
|
break;
|
|
case EN_CHANGE:
|
|
// Validate the integer
|
|
pData->dwFlags |= IpEdit_mskfNoNofity;
|
|
gGI_dwFlags |= GI_mskfEmptyStringValid;
|
|
if (!FGetCtrlDWordValue((HWND)lParam, OUT (DWORD *)&i, 0, 255))
|
|
{
|
|
FSetWindowText((HWND)lParam, _W"255");
|
|
LSendMessage((HWND)lParam, EM_SETSEL, 0, -1);
|
|
}
|
|
pData->dwFlags &= ~IpEdit_mskfNoNofity;
|
|
IpEdit_EnableAddButton(hwnd, pData->hwndBtnAdd);
|
|
break;
|
|
|
|
default:
|
|
return 0;
|
|
} // switch
|
|
LSendMessage(
|
|
GetParent(hwnd),
|
|
WM_COMMAND,
|
|
MAKEWPARAM(GetDlgCtrlID(hwnd), HIWORD(wParam)),
|
|
(LPARAM)hwnd);
|
|
return 0;
|
|
|
|
case UN_KEYDOWN:
|
|
{
|
|
// UN_KEYDOWN: Notification message send by the child
|
|
DWORD dwSelStart;
|
|
DWORD dwSelEnd;
|
|
|
|
Assert(pData);
|
|
Assert(IsWindow((HWND)lParam));
|
|
switch (wParam)
|
|
{
|
|
case VK_HOME:
|
|
SetFocus(pData->rgChild[0].hwnd);
|
|
LSendMessage((HWND)lParam, EM_SETSEL, 0, 0);
|
|
return TRUE;
|
|
case VK_END:
|
|
SetFocus(pData->rgChild[3].hwnd);
|
|
LSendMessage((HWND)lParam, EM_SETSEL, 3, 3);
|
|
return TRUE;
|
|
}
|
|
LSendMessage((HWND)lParam, EM_GETSEL, (WPARAM)&dwSelStart, (LPARAM)&dwSelEnd);
|
|
if (dwSelStart != dwSelEnd)
|
|
return 0;
|
|
if ((wParam == VK_LEFT || wParam == VK_BACK) && dwSelStart == 0)
|
|
{
|
|
for (i = 0; i < 4; i++)
|
|
if (pData->rgChild[i].hwnd == (HWND)lParam)
|
|
break;
|
|
Assert(i < 4);
|
|
if (i)
|
|
{
|
|
SetFocus(pData->rgChild[--i].hwnd);
|
|
if (wParam == VK_LEFT)
|
|
LSendMessage(pData->rgChild[i].hwnd, EM_SETSEL, 0, -1);
|
|
}
|
|
return TRUE;
|
|
}
|
|
if (wParam == VK_RIGHT && (int)dwSelEnd == GetWindowTextLength((HWND)lParam))
|
|
{
|
|
for (i = 0; i < 4; i++)
|
|
if (pData->rgChild[i].hwnd == (HWND)lParam)
|
|
break;
|
|
Assert(i < 4);
|
|
if (i < 3)
|
|
{
|
|
SetFocus(pData->rgChild[++i].hwnd);
|
|
LSendMessage(pData->rgChild[i].hwnd, EM_SETSEL, 0, -1);
|
|
}
|
|
return TRUE;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
case WM_CREATE:
|
|
{
|
|
RECT rc;
|
|
LONG id;
|
|
|
|
Assert(pData == NULL);
|
|
pData = (IPEDITDATA *)Malloc(sizeof(IPEDITDATA));
|
|
Report(pData);
|
|
if (pData == NULL)
|
|
return -1;
|
|
// Attatch the allocated block to the window
|
|
SetWindowLong(hwnd, ibIpEditData, (LONG)pData);
|
|
pData->dwFlags = IpEdit_mskfEmptyFieldsValid;
|
|
pData->hwndBtnAdd = NULL;
|
|
GetClientRect(hwnd, &rc);
|
|
Assert(rc.top == 0);
|
|
Assert(rc.left == 0);
|
|
int dxEdit = (rc.right - (4 * 3)) / 4;
|
|
|
|
id = GetWindowLong(hwnd, GWL_ID);
|
|
for (i = 0; i < 4; i++)
|
|
{
|
|
pData->rgChild[i].xPos = 2 + (dxEdit + 4) * i;
|
|
pData->rgChild[i].hwnd = CreateWindow(
|
|
szClassEdit,
|
|
NULL,
|
|
WS_CHILD | WS_VISIBLE | ES_AUTOHSCROLL,
|
|
pData->rgChild[i].xPos,
|
|
1,
|
|
dxEdit,
|
|
rc.bottom,
|
|
hwnd,
|
|
(HMENU)id,
|
|
hInstanceSave,
|
|
NULL);
|
|
LSendMessage(pData->rgChild[i].hwnd, EM_LIMITTEXT, 3, 0);
|
|
SetWindowLong(pData->rgChild[i].hwnd, GWL_WNDPROC, (LONG)WndProcEditNumber);
|
|
} //for
|
|
Assert(((CREATESTRUCT *)lParam)->lpszName != NULL);
|
|
Trace2(((CREATESTRUCT *)lParam)->lpszName[0] ? mskTraceAlways : mskTraceNone,
|
|
"\nIpEdit: You should delete caption \"%s\" of control Id=%d.",
|
|
((CREATESTRUCT *)lParam)->lpszName, GetDlgCtrlID(hwnd));
|
|
}
|
|
break;
|
|
|
|
case WM_DESTROY:
|
|
Assert(pData);
|
|
Free(pData);
|
|
break;
|
|
|
|
case WM_PAINT:
|
|
{
|
|
HDC hdc;
|
|
|
|
Assert(pData);
|
|
// Let lpfnEditOld paint the control for us...
|
|
CallWindowProc(lpfnEditOld, hwnd, WM_PAINT, 0, 0);
|
|
// Then, add the dots
|
|
hdc = GetDC(hwnd);
|
|
SetBkMode(hdc, TRANSPARENT);
|
|
SetTextColor(hdc, clrWindowText);
|
|
SelectObject(hdc, (HGDIOBJ)(HFONT)LSendMessage(hwnd, WM_GETFONT, 0, 0));
|
|
for (i = 1; i < 4; i++)
|
|
TextOut(hdc, pData->rgChild[i].xPos - 4, 1, _W".", 1);
|
|
ReleaseDC(hwnd, hdc);
|
|
}
|
|
return 0;
|
|
|
|
default:
|
|
break;
|
|
} // swtich
|
|
|
|
return CallWindowProc(lpfnEditOld, hwnd, uMsg, wParam, lParam);
|
|
} // WndProcIpEdit
|