Windows NT 4.0 source code leak
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

// 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