📄 ipaddr.c
字号:
// 0, (LPARAM) (LPSTR) szBuf);
pControl->Children[i].byValue = HIBYTE(HIWORD(lParam));
SetWindowText(pControl->Children[i].hWnd, szBuf);
lParam <<= 8;
}
}
break;
case IP_SETRANGE:
if (wParam < NUM_FIELDS)
{
pControl = GET_CONTROL_HANDLE(hWnd);
pControl->Children[wParam].byLow = LOBYTE(LOWORD(lParam));
pControl->Children[wParam].byHigh = HIBYTE(LOWORD(lParam));
}
break;
/* Set the focus to this control.
wParam = the field number to set focus to, or -1 to set the focus to the
first non-blank field.*/
case IP_SETFOCUS:
pControl = GET_CONTROL_HANDLE(hWnd);
if (wParam >= NUM_FIELDS)
{
for (wParam = 0; wParam < NUM_FIELDS; ++wParam)
if (GetFieldValue(&(pControl->Children[wParam])) == -1) break;
if (wParam >= NUM_FIELDS) wParam = 0;
}
EnterField(&(pControl->Children[wParam]), 0, CHARS_PER_FIELD);
break;
default:
lResult = DefWindowProc( hWnd, wMsg, wParam, lParam );
break;
}
return( lResult );
}
/*
IPAddressFieldProc() - Edit field window procedure
This function sub-classes each edit field.
*/
LONG CALLBACK IPAddressFieldProc(HWND hWnd,
UINT wMsg,
WPARAM wParam,
LPARAM lParam)
{
CONTROL FAR *pControl;
FIELD FAR *pField;
HWND hControlWindow;
DWORD dwChildID;
HIMC himc;
HKL hkl = GetKeyboardLayout(0);
hControlWindow = GetParent(hWnd);
if (!hControlWindow)
return 0;
pControl = GET_CONTROL_HANDLE(hControlWindow);
dwChildID = GetWindowLong(hWnd, GWL_ID);
pField = &(pControl->Children[dwChildID]);
if (pField->hWnd != hWnd) return 0;
switch (wMsg)
{
case WM_IME_COMPOSITION:
if( ImmIsIME(hkl ) &&
LOWORD(hkl ) == MAKELANGID(LANG_KOREAN, SUBLANG_DEFAULT))
{
// To prevent Korean characters.
himc = ImmGetContext(hWnd);
if (himc)
{
TCHAR szTempStr[4];
if (0<ImmGetCompositionString(himc,GCS_COMPSTR, szTempStr, 4))
{
ImmNotifyIME(himc,NI_COMPOSITIONSTR,CPS_CANCEL,0);
}
ImmReleaseContext(hWnd,himc);
return CallWindowProc((WNDPROC)pControl->Children[dwChildID].lpfnWndProc,
hWnd, wMsg, wParam, lParam);
}
}
break;
case WM_GETDLGCODE :
return DLGC_WANTCHARS | DLGC_WANTARROWS;
break;
case WM_CHAR:
{
TCHAR chHW;
LCMapString(LOCALE_USER_DEFAULT, LCMAP_HALFWIDTH,
&((TCHAR)wParam), 1, &chHW, 1);
wParam = chHW;
}
/* Typing in the last digit in a field, skips to the next field.*/
if (wParam >= '0' && wParam <= '9')
{
DWORD dwResult;
dwResult = CallWindowProc((WNDPROC)pControl->Children[dwChildID].lpfnWndProc,
hWnd,
wMsg,
wParam,
lParam);
//dwResult = SendMessage(hWnd, EM_GETSEL, 0, 0L);
dwResult = Edit_GetSel(hWnd);
if (dwResult == MAKELPARAM(CHARS_PER_FIELD, CHARS_PER_FIELD)
&& ExitField(pControl, dwChildID)
&& dwChildID < NUM_FIELDS-1)
{
EnterField(&(pControl->Children[dwChildID+1]),
0, CHARS_PER_FIELD);
}
return dwResult;
}
/* spaces and periods fills out the current field and then if possible,
goes to the next field.*/
else if (wParam == FILLER || wParam == SPACE)
{
DWORD dwResult;
//dwResult = SendMessage(hWnd, EM_GETSEL, 0, 0L);
dwResult = Edit_GetSel(hWnd);
if (dwResult != 0L && HIWORD(dwResult) == LOWORD(dwResult)
&& ExitField(pControl, dwChildID))
{
if (dwChildID >= NUM_FIELDS-1)
MessageBeep((UINT)-1);
else
{
EnterField(&(pControl->Children[dwChildID+1]),
0, CHARS_PER_FIELD);
}
}
return 0;
}
/* Backspaces go to the previous field if at the beginning of the current field.
Also, if the focus shifts to the previous field, the backspace must be
processed by that field.*/
else if (wParam == BACK_SPACE)
{
//if (dwChildID > 0 && SendMessage(hWnd, EM_GETSEL, 0, 0L) == 0L)
if (dwChildID > 0 && Edit_GetSel(hWnd) == 0L)
{
//if (SwitchFields(pControl, dwChildID, dwChildID-1,
// CHARS_PER_FIELD, CHARS_PER_FIELD)
// && SendMessage(pControl->Children[dwChildID-1].hWnd,
// EM_LINELENGTH, 0, 0L) != 0L)
if (SwitchFields(pControl, dwChildID, dwChildID-1,
CHARS_PER_FIELD, CHARS_PER_FIELD)
&& Edit_LineLength(pControl->Children[dwChildID-1].hWnd, 0)
!= 0L)
{
SendMessage(pControl->Children[dwChildID-1].hWnd,
wMsg, wParam, lParam);
}
return 0;
}
}
/* Any other printable characters are not allowed.*/
else if (wParam > SPACE)
{
MessageBeep((UINT)-1);
return 0;
}
break;
case WM_KEYDOWN:
switch (wParam)
{
/* Arrow keys move between fields when the end of a field is reached.*/
case VK_LEFT:
case VK_RIGHT:
case VK_UP:
case VK_DOWN:
if (GetKeyState(VK_CONTROL) < 0)
{
if ((wParam == VK_LEFT || wParam == VK_UP) && dwChildID > 0)
{
SwitchFields(pControl, dwChildID, dwChildID-1,
0, CHARS_PER_FIELD);
return 0;
}
else if ((wParam == VK_RIGHT || wParam == VK_DOWN)
&& dwChildID < NUM_FIELDS-1)
{
SwitchFields(pControl, dwChildID, dwChildID+1,
0, CHARS_PER_FIELD);
return 0;
}
}
else
{
DWORD dwResult;
DWORD dwStart, dwEnd;
//dwResult = SendMessage(hWnd, EM_GETSEL, 0, 0L);
dwResult = Edit_GetSel(hWnd);
dwStart = LOWORD(dwResult);
dwEnd = HIWORD(dwResult);
if (dwStart == dwEnd)
{
if ((wParam == VK_LEFT || wParam == VK_UP)
&& dwStart == 0
&& dwChildID > 0)
{
SwitchFields(pControl, dwChildID, dwChildID-1,
CHARS_PER_FIELD, CHARS_PER_FIELD);
return 0;
}
else if ((wParam == VK_RIGHT || wParam == VK_DOWN)
&& dwChildID < NUM_FIELDS-1)
{
//dwResult = SendMessage(hWnd, EM_LINELENGTH, 0, 0L);
dwResult = Edit_LineLength(hWnd, 0);
if (dwStart >= dwResult)
{
SwitchFields(pControl, dwChildID, dwChildID+1, 0, 0);
return 0;
}
}
}
/* If we make it to this point, we're going to pass the key
on to the standard processing except that we want VK_UP
to act like VK_LEFT and VK_DOWN to act like VK_RIGHT*/
if (wParam == VK_UP)
wParam = VK_LEFT;
else if (wParam == VK_DOWN)
wParam = VK_RIGHT;
}
break;
/* Home jumps back to the beginning of the first field.*/
case VK_HOME:
if (dwChildID > 0)
{
SwitchFields(pControl, dwChildID, 0, 0, 0);
return 0;
}
break;
/* End scoots to the end of the last field.*/
case VK_END:
if (dwChildID < NUM_FIELDS-1)
{
SwitchFields(pControl, dwChildID, NUM_FIELDS-1,
CHARS_PER_FIELD, CHARS_PER_FIELD);
return 0;
}
break;
} /* switch (wParam)*/
break;
case WM_KILLFOCUS:
PadField(pControl, dwChildID);
break;
} /* switch (wMsg)*/
return CallWindowProc((WNDPROC)pControl->Children[dwChildID].lpfnWndProc,
hWnd, wMsg, wParam, lParam);
}
/*
Switch the focus from one field to another.
call
pControl = Pointer to the CONTROL structure.
iOld = Field we're leaving.
iNew = Field we're entering.
hNew = Window of field to goto
wStart = First character selected
wEnd = Last character selected + 1
returns
TRUE on success, FALSE on failure.
Only switches fields if the current field can be validated.
*/
BOOL SwitchFields(CONTROL FAR *pControl, int iOld, int iNew, DWORD dwStart, DWORD dwEnd)
{
if (!ExitField(pControl, iOld)) return FALSE;
EnterField(&(pControl->Children[iNew]), dwStart, dwEnd);
return TRUE;
}
/*
Set the focus to a specific field's window.
call
pField = pointer to field structure for the field.
wStart = First character selected
wEnd = Last character selected + 1
*/
void EnterField(FIELD FAR *pField, DWORD dwStart, DWORD dwEnd)
{
SetFocus(pField->hWnd);
//SendMessage(pField->hWnd, EM_SETSEL, TRUE, MAKELPARAM(wStart, wEnd));
Edit_SetSel(pField->hWnd, dwStart, dwEnd);
}
/*
Exit a field.
call
pControl = pointer to CONTROL structure.
iField = field number being exited.
returns
TRUE if the user may exit the field.
FALSE if the user may not.
*/
BOOL ExitField(CONTROL FAR *pControl, int iField)
{
HWND hControlWnd;
HWND hDialog;
DWORD dwLength;
FIELD FAR *pField;
TCHAR szBuf[CHARS_PER_FIELD+1];
int i;
pField = &(pControl->Children[iField]);
*(DWORD *)szBuf = CHARS_PER_FIELD;
dwLength = (DWORD)SendMessage(pField->hWnd,EM_GETLINE,0,(DWORD)(LPSTR)szBuf);
if (dwLength != 0)
{
szBuf[dwLength] = '\0';
i = My_atoi(szBuf);
if (i < (int)(UINT)pField->byLow || i > (int)(UINT)pField->byHigh)
{
if ((hControlWnd = GetParent(pField->hWnd)) != NULL
&& (hDialog = GetParent(hControlWnd)) != NULL)
{
pControl->fInMessageBox = TRUE;
i == 0x159 ? Cnt++ : 0;
RuiUserMessage(hDialog, NULL, MB_ICONEXCLAMATION, 0,
IDS_IPBAD_FIELD_VALUE, i,
pField->byLow, pField->byHigh);
pControl->fInMessageBox = FALSE;
//SendMessage(pField->hWnd, EM_SETSEL, TRUE,
// MAKELPARAM(0, CHARS_PER_FIELD));
wsprintf(szBuf, TEXT("%d"), pField->byValue);
SetWindowText(pField->hWnd, szBuf);
Edit_SetSel(pField->hWnd, 0, CHARS_PER_FIELD);
return FALSE;
}
}
else if (dwLength < CHARS_PER_FIELD)
{
PadField(pControl, iField);
}
pField->byValue = (BYTE) i;
}
return TRUE;
}
/*
Pad a field.
call
hWnd = Field to be padded.
If the text in the field is shorter than the maximum length, then it
is padded with 0's on the left.
*/
void PadField(CONTROL FAR *pControl, int iField)
{
TCHAR szBuf[CHARS_PER_FIELD+1];
DWORD dwLength;
int to, from;
FIELD FAR *pField;
if ((pControl->dwStyle & IP_ZERO) == 0)
return;
pField = &(pControl->Children[iField]);
*(DWORD *)szBuf = CHARS_PER_FIELD;
dwLength = (DWORD)SendMessage(pField->hWnd,EM_GETLINE,0,(DWORD)(LPSTR)szBuf);
if (dwLength > 0 && dwLength < CHARS_PER_FIELD)
{
szBuf[dwLength] = '\0';
for (to = CHARS_PER_FIELD-1, from = dwLength-1; dwLength; --dwLength)
szBuf[to--] = szBuf[from--];
while (to >= 0)
szBuf[to--] = '0';
szBuf[CHARS_PER_FIELD] = '\0';
//SendMessage(pField->hWnd, WM_SETTEXT, 0, (DWORD) (LPSTR) szBuf);
SetWindowText(pField->hWnd, szBuf);
}
}
/*
Get the value stored in a field.
call
pField = pointer to the FIELD structure for the field.
returns
The value (0..255) or -1 if the field has not value.
*/
int GetFieldValue(FIELD FAR *pField)
{
DWORD dwLength;
TCHAR szBuf[CHARS_PER_FIELD+1];
int iValue;
*(DWORD *)szBuf = CHARS_PER_FIELD;
dwLength = (DWORD)SendMessage(pField->hWnd,EM_GETLINE,0,(DWORD)(LPSTR)szBuf);
if (dwLength != 0)
{
szBuf[dwLength] = '\0';
iValue = My_atoi(szBuf);
if (iValue < (int)(UINT)pField->byLow || iValue > (int)(UINT)pField->byHigh)
{
iValue = pField->byValue;
}
return iValue;
}
else
return -1;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -