| /* | |
| * IP Address control | |
| * | |
| * Copyright 1999 Chris Morgan<cmorgan@wpi.edu> and | |
| * James Abbatiello<abbeyj@wpi.edu> | |
| * Copyright 1998, 1999 Eric Kohl | |
| * Copyright 1998 Alex Priem <alexp@sci.kun.nl> | |
| * | |
| * NOTES | |
| * | |
| * TODO: | |
| * -Edit control doesn't support the ES_CENTER style which prevents | |
| * this ipaddress control from having centered text look like the | |
| * windows ipaddress control | |
| * -Check all notifications/behavior. | |
| * -Optimization: | |
| * -include lpipsi in IPADDRESS_INFO. | |
| * -CurrentFocus: field that has focus at moment of processing. | |
| * -connect Rect32 rcClient. | |
| * -check ipaddress.cpp for missing features. | |
| * -refresh: draw '.' instead of setpixel. | |
| */ | |
| #include <ctype.h> | |
| #include <stdlib.h> | |
| #include <stdio.h> | |
| #include <string.h> | |
| #include "winbase.h" | |
| #include "commctrl.h" | |
| #include "heap.h" | |
| #include "debugtools.h" | |
| DEFAULT_DEBUG_CHANNEL(ipaddress); | |
| typedef struct | |
| { | |
| BYTE LowerLimit[4]; | |
| BYTE UpperLimit[4]; | |
| RECT rcClient; | |
| INT uFocus; | |
| } IPADDRESS_INFO; | |
| typedef struct | |
| { | |
| WNDPROC wpOrigProc[4]; | |
| HWND hwndIP[4]; | |
| IPADDRESS_INFO *infoPtr; | |
| HWND hwnd; | |
| UINT uRefCount; | |
| } IP_SUBCLASS_INFO, *LPIP_SUBCLASS_INFO; | |
| #define IPADDRESS_GetInfoPtr(hwnd) ((IPADDRESS_INFO *)GetWindowLongA (hwnd, 0)) | |
| static BOOL | |
| IPADDRESS_SendNotify (HWND hwnd, UINT command); | |
| static BOOL | |
| IPADDRESS_SendIPAddressNotify (HWND hwnd, UINT field, BYTE newValue); | |
| /* property name of tooltip window handle */ | |
| #define IP_SUBCLASS_PROP "CCIP32SubclassInfo" | |
| static LRESULT CALLBACK | |
| IPADDRESS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam); | |
| static VOID | |
| IPADDRESS_Refresh (HWND hwnd, HDC hdc) | |
| { | |
| RECT rcClient; | |
| HBRUSH hbr; | |
| COLORREF clr=GetSysColor (COLOR_3DDKSHADOW); | |
| int i,x,fieldsize; | |
| GetClientRect (hwnd, &rcClient); | |
| hbr = CreateSolidBrush (RGB(255,255,255)); | |
| DrawEdge (hdc, &rcClient, EDGE_SUNKEN, BF_RECT | BF_ADJUST); | |
| FillRect (hdc, &rcClient, hbr); | |
| DeleteObject (hbr); | |
| x=rcClient.left; | |
| fieldsize=(rcClient.right-rcClient.left) / 4; | |
| for (i=0; i<3; i++) { /* Should draw text "." here */ | |
| x+=fieldsize; | |
| SetPixel (hdc, x, 13, clr); | |
| SetPixel (hdc, x, 14, clr); | |
| SetPixel (hdc, x+1, 13, clr); | |
| SetPixel (hdc, x+1, 14, clr); | |
| } | |
| } | |
| static LRESULT | |
| IPADDRESS_Create (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| IPADDRESS_INFO *infoPtr; | |
| RECT rcClient, edit; | |
| int i,fieldsize; | |
| LPIP_SUBCLASS_INFO lpipsi; | |
| infoPtr = (IPADDRESS_INFO *)COMCTL32_Alloc (sizeof(IPADDRESS_INFO)); | |
| SetWindowLongA (hwnd, 0, (DWORD)infoPtr); | |
| GetClientRect (hwnd, &rcClient); | |
| fieldsize=(rcClient.right-rcClient.left) /4; | |
| edit.top =rcClient.top+2; | |
| edit.bottom=rcClient.bottom-2; | |
| lpipsi=(LPIP_SUBCLASS_INFO) GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP); | |
| if (lpipsi == NULL) { | |
| lpipsi = (LPIP_SUBCLASS_INFO) COMCTL32_Alloc (sizeof(IP_SUBCLASS_INFO)); | |
| lpipsi->hwnd = hwnd; | |
| lpipsi->uRefCount++; | |
| SetPropA ((HWND)hwnd, IP_SUBCLASS_PROP, (HANDLE)lpipsi); | |
| /* infoPtr->lpipsi= lpipsi; */ | |
| } else | |
| WARN("IP-create called twice\n"); | |
| for (i=0; i<=3; i++) | |
| { | |
| infoPtr->LowerLimit[i]=0; | |
| infoPtr->UpperLimit[i]=255; | |
| edit.left=rcClient.left+i*fieldsize+6; | |
| edit.right=rcClient.left+(i+1)*fieldsize-2; | |
| lpipsi->hwndIP[i]= CreateWindowA ("edit", NULL, | |
| WS_CHILD | WS_VISIBLE | ES_CENTER, | |
| edit.left, edit.top, edit.right-edit.left, edit.bottom-edit.top, | |
| hwnd, (HMENU) 1, GetWindowLongA (hwnd, GWL_HINSTANCE), NULL); | |
| lpipsi->wpOrigProc[i]= (WNDPROC) | |
| SetWindowLongA (lpipsi->hwndIP[i],GWL_WNDPROC, (LONG) | |
| IPADDRESS_SubclassProc); | |
| SetPropA ((HWND)lpipsi->hwndIP[i], IP_SUBCLASS_PROP, (HANDLE)lpipsi); | |
| } | |
| lpipsi->infoPtr= infoPtr; | |
| return 0; | |
| } | |
| static LRESULT | |
| IPADDRESS_Destroy (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| int i; | |
| IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); | |
| LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO) | |
| GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP); | |
| for (i=0; i<=3; i++) { | |
| SetWindowLongA ((HWND)lpipsi->hwndIP[i], GWL_WNDPROC, | |
| (LONG)lpipsi->wpOrigProc[i]); | |
| } | |
| COMCTL32_Free (infoPtr); | |
| SetWindowLongA (hwnd, 0, 0); | |
| return 0; | |
| } | |
| static LRESULT | |
| IPADDRESS_KillFocus (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| HDC hdc; | |
| TRACE("\n"); | |
| hdc = GetDC (hwnd); | |
| IPADDRESS_Refresh (hwnd, hdc); | |
| ReleaseDC (hwnd, hdc); | |
| IPADDRESS_SendIPAddressNotify (hwnd, 0, 0); /* FIXME: should use -1 */ | |
| IPADDRESS_SendNotify (hwnd, EN_KILLFOCUS); | |
| InvalidateRect (hwnd, NULL, TRUE); | |
| return 0; | |
| } | |
| static LRESULT | |
| IPADDRESS_Paint (HWND hwnd, WPARAM wParam) | |
| { | |
| HDC hdc; | |
| PAINTSTRUCT ps; | |
| hdc = wParam==0 ? BeginPaint (hwnd, &ps) : (HDC)wParam; | |
| IPADDRESS_Refresh (hwnd, hdc); | |
| if(!wParam) | |
| EndPaint (hwnd, &ps); | |
| return 0; | |
| } | |
| static LRESULT | |
| IPADDRESS_SetFocus (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| HDC hdc; | |
| TRACE("\n"); | |
| hdc = GetDC (hwnd); | |
| IPADDRESS_Refresh (hwnd, hdc); | |
| ReleaseDC (hwnd, hdc); | |
| return 0; | |
| } | |
| static LRESULT | |
| IPADDRESS_Size (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| /* IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); */ | |
| TRACE("\n"); | |
| return 0; | |
| } | |
| static BOOL | |
| IPADDRESS_SendNotify (HWND hwnd, UINT command) | |
| { | |
| TRACE("%x\n",command); | |
| return (BOOL)SendMessageA (GetParent (hwnd), WM_COMMAND, | |
| MAKEWPARAM (GetWindowLongA (hwnd, GWL_ID),command), (LPARAM)hwnd); | |
| } | |
| static BOOL | |
| IPADDRESS_SendIPAddressNotify (HWND hwnd, UINT field, BYTE newValue) | |
| { | |
| NMIPADDRESS nmip; | |
| TRACE("%x %x\n",field,newValue); | |
| nmip.hdr.hwndFrom = hwnd; | |
| nmip.hdr.idFrom = GetWindowLongA (hwnd, GWL_ID); | |
| nmip.hdr.code = IPN_FIELDCHANGED; | |
| nmip.iField=field; | |
| nmip.iValue=newValue; | |
| return (BOOL)SendMessageA (GetParent (hwnd), WM_NOTIFY, | |
| (WPARAM)nmip.hdr.idFrom, (LPARAM)&nmip); | |
| } | |
| static LRESULT | |
| IPADDRESS_ClearAddress (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| int i; | |
| HDC hdc; | |
| char buf[1]; | |
| LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO) | |
| GetPropA ((HWND)hwnd,IP_SUBCLASS_PROP); | |
| TRACE("\n"); | |
| buf[0]=0; | |
| for (i=0; i<=3; i++) | |
| SetWindowTextA (lpipsi->hwndIP[i],buf); | |
| hdc = GetDC (hwnd); | |
| IPADDRESS_Refresh (hwnd, hdc); | |
| ReleaseDC (hwnd, hdc); | |
| return 0; | |
| } | |
| static LRESULT | |
| IPADDRESS_IsBlank (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| int i; | |
| char buf[20]; | |
| LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO) | |
| GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP); | |
| TRACE("\n"); | |
| for (i=0; i<=3; i++) { | |
| GetWindowTextA (lpipsi->hwndIP[i],buf,5); | |
| if (buf[0]) | |
| return 0; | |
| } | |
| return 1; | |
| } | |
| static LRESULT | |
| IPADDRESS_GetAddress (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| char field[20]; | |
| int i,valid,fieldvalue; | |
| DWORD ip_addr; | |
| IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); | |
| LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO) | |
| GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP); | |
| TRACE("\n"); | |
| valid=0; | |
| ip_addr=0; | |
| for (i=0; i<=3; i++) { | |
| GetWindowTextA (lpipsi->hwndIP[i],field,4); | |
| ip_addr*=256; | |
| if (field[0]) { | |
| field[3]=0; | |
| fieldvalue=atoi(field); | |
| if (fieldvalue<infoPtr->LowerLimit[i]) | |
| fieldvalue=infoPtr->LowerLimit[i]; | |
| if (fieldvalue>infoPtr->UpperLimit[i]) | |
| fieldvalue=infoPtr->UpperLimit[i]; | |
| ip_addr+=fieldvalue; | |
| valid++; | |
| } | |
| } | |
| *(LPDWORD) lParam=ip_addr; | |
| return valid; | |
| } | |
| static LRESULT | |
| IPADDRESS_SetRange (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); | |
| INT index; | |
| TRACE("\n"); | |
| index=(INT) wParam; | |
| if ((index<0) || (index>3)) return 0; | |
| infoPtr->LowerLimit[index]=lParam & 0xff; | |
| infoPtr->UpperLimit[index]=(lParam >>8) & 0xff; | |
| return 1; | |
| } | |
| static LRESULT | |
| IPADDRESS_SetAddress (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); | |
| HDC hdc; | |
| LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO) | |
| GetPropA ((HWND)hwnd, IP_SUBCLASS_PROP); | |
| int i,ip_address,value; | |
| char buf[20]; | |
| TRACE("\n"); | |
| ip_address=(DWORD) lParam; | |
| for (i=3; i>=0; i--) { | |
| value=ip_address & 0xff; | |
| if ((value>=infoPtr->LowerLimit[i]) && (value<=infoPtr->UpperLimit[i])) | |
| { | |
| sprintf (buf,"%d",value); | |
| SetWindowTextA (lpipsi->hwndIP[i],buf); | |
| IPADDRESS_SendNotify (hwnd, EN_CHANGE); | |
| } | |
| ip_address/=256; | |
| } | |
| hdc = GetDC (hwnd); /* & send notifications */ | |
| IPADDRESS_Refresh (hwnd, hdc); | |
| ReleaseDC (hwnd, hdc); | |
| return TRUE; | |
| } | |
| static LRESULT | |
| IPADDRESS_SetFocusToField (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| /* IPADDRESS_INFO *infoPtr = IPADDRESS_GetInfoPtr (hwnd); */ | |
| LPIP_SUBCLASS_INFO lpipsi=(LPIP_SUBCLASS_INFO) GetPropA ((HWND)hwnd, | |
| IP_SUBCLASS_PROP); | |
| INT index; | |
| index=(INT) wParam; | |
| TRACE(" %d\n", index); | |
| if ((index<0) || (index>3)) return 0; | |
| SetFocus (lpipsi->hwndIP[index]); | |
| return 1; | |
| } | |
| static LRESULT | |
| IPADDRESS_LButtonDown (HWND hwnd, WPARAM wParam, LPARAM lParam) | |
| { | |
| TRACE("\n"); | |
| SetFocus (hwnd); | |
| IPADDRESS_SendNotify (hwnd, EN_SETFOCUS); | |
| IPADDRESS_SetFocusToField (hwnd, 0, 0); | |
| return TRUE; | |
| } | |
| static INT | |
| IPADDRESS_CheckField (LPIP_SUBCLASS_INFO lpipsi, int currentfield) | |
| { | |
| int newField,fieldvalue; | |
| char field[20]; | |
| IPADDRESS_INFO *infoPtr=lpipsi->infoPtr; | |
| if(currentfield >= 0 && currentfield < 4) | |
| { | |
| TRACE("\n"); | |
| GetWindowTextA (lpipsi->hwndIP[currentfield],field,4); | |
| if (field[0]) | |
| { | |
| field[3]=0; | |
| newField=-1; | |
| fieldvalue=atoi(field); | |
| if (fieldvalue < infoPtr->LowerLimit[currentfield]) | |
| newField=infoPtr->LowerLimit[currentfield]; | |
| if (fieldvalue > infoPtr->UpperLimit[currentfield]) | |
| newField=infoPtr->UpperLimit[currentfield]; | |
| if (newField >= 0) | |
| { | |
| sprintf (field,"%d",newField); | |
| SetWindowTextA (lpipsi->hwndIP[currentfield], field); | |
| return TRUE; | |
| } | |
| } | |
| } | |
| return FALSE; | |
| } | |
| static INT | |
| IPADDRESS_GotoNextField (LPIP_SUBCLASS_INFO lpipsi, int currentfield) | |
| { | |
| if(currentfield >= -1 && currentfield < 4) | |
| { | |
| IPADDRESS_CheckField(lpipsi, currentfield); /* check the fields value */ | |
| if(currentfield < 3) | |
| { | |
| SetFocus (lpipsi->hwndIP[currentfield+1]); | |
| return TRUE; | |
| } | |
| } | |
| return FALSE; | |
| } | |
| /* period: move and select the text in the next field to the right if */ | |
| /* the current field is not empty(l!=0), we are not in the */ | |
| /* left most position, and nothing is selected(startsel==endsel) */ | |
| /* spacebar: same behavior as period */ | |
| /* alpha characters: completely ignored */ | |
| /* digits: accepted when field text length < 2 ignored otherwise. */ | |
| /* when 3 numbers have been entered into the field the value */ | |
| /* of the field is checked, if the field value exceeds the */ | |
| /* maximum value and is changed the field remains the current */ | |
| /* field, otherwise focus moves to the field to the right */ | |
| /* tab: change focus from the current ipaddress control to the next */ | |
| /* control in the tab order */ | |
| /* right arrow: move to the field on the right to the left most */ | |
| /* position in that field if no text is selected, */ | |
| /* we are in the right most position in the field, */ | |
| /* we are not in the right most field */ | |
| /* left arrow: move to the field on the left to the right most */ | |
| /* position in that field if no text is selected, */ | |
| /* we are in the left most position in the current field */ | |
| /* and we are not in the left most field */ | |
| /* backspace: delete the character to the left of the cursor position, */ | |
| /* if none are present move to the field on the left if */ | |
| /* we are not in the left most field and delete the right */ | |
| /* most digit in that field while keeping the cursor */ | |
| /* on the right side of the field */ | |
| LRESULT CALLBACK | |
| IPADDRESS_SubclassProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
| { | |
| IPADDRESS_INFO *infoPtr; | |
| LPIP_SUBCLASS_INFO lpipsi = (LPIP_SUBCLASS_INFO) GetPropA | |
| ((HWND)hwnd,IP_SUBCLASS_PROP); | |
| CHAR c = (CHAR)wParam; | |
| INT i, l, index, startsel, endsel; | |
| infoPtr = lpipsi->infoPtr; | |
| index=0; /* FIXME */ | |
| for (i=0; i<=3; i++) | |
| if (lpipsi->hwndIP[i]==hwnd) index=i; | |
| switch (uMsg) { | |
| case WM_CHAR: | |
| if(isdigit(c)) /* process all digits */ | |
| { | |
| int return_val; | |
| SendMessageA(lpipsi->hwndIP[index], EM_GETSEL, (WPARAM)&startsel, (LPARAM)&endsel); | |
| l = GetWindowTextLengthA (lpipsi->hwndIP[index]); | |
| if(l==2 && startsel==endsel) /* field is full after this key is processed */ | |
| { | |
| /* process the digit press before we check the field */ | |
| return_val = CallWindowProcA (lpipsi->wpOrigProc[index], hwnd, uMsg, wParam, lParam); | |
| /* if the field value was changed stay at the current field */ | |
| if(!IPADDRESS_CheckField(lpipsi, index)) | |
| IPADDRESS_GotoNextField (lpipsi,index); | |
| return return_val; | |
| } | |
| if(l > 2) /* field is full, stop key messages */ | |
| { | |
| lParam = 0; | |
| wParam = 0; | |
| } | |
| break; | |
| } | |
| if(c == '.') /* VK_PERIOD */ | |
| { | |
| l = GetWindowTextLengthA(lpipsi->hwndIP[index]); | |
| SendMessageA(lpipsi->hwndIP[index], EM_GETSEL, (WPARAM)&startsel, (LPARAM)&endsel); | |
| if(l != 0 && startsel==endsel && startsel != 0) | |
| { | |
| IPADDRESS_GotoNextField(lpipsi, index); | |
| SendMessageA(lpipsi->hwndIP[index+1], EM_SETSEL, (WPARAM)0, (LPARAM)3); | |
| } | |
| } | |
| /* stop all other characters */ | |
| wParam = 0; | |
| lParam = 0; | |
| break; | |
| case WM_KEYDOWN: | |
| if(c == VK_SPACE) | |
| { | |
| l = GetWindowTextLengthA(lpipsi->hwndIP[index]); | |
| SendMessageA(lpipsi->hwndIP[index], EM_GETSEL, (WPARAM)&startsel, (LPARAM)&endsel); | |
| if(l != 0 && startsel==endsel && startsel != 0) | |
| { | |
| IPADDRESS_GotoNextField(lpipsi, index); | |
| SendMessageA(lpipsi->hwndIP[index+1], EM_SETSEL, (WPARAM)0, (LPARAM)3); | |
| } | |
| } | |
| if(c == VK_RIGHT) | |
| { | |
| SendMessageA(lpipsi->hwndIP[index], EM_GETSEL, (WPARAM)&startsel, (LPARAM)&endsel); | |
| l = GetWindowTextLengthA (lpipsi->hwndIP[index]); | |
| if(startsel==endsel && startsel==l) | |
| { | |
| IPADDRESS_GotoNextField(lpipsi, index); | |
| SendMessageA(lpipsi->hwndIP[index+1], EM_SETSEL, (WPARAM)0,(LPARAM)0); | |
| } | |
| } | |
| if(c == VK_LEFT) | |
| { | |
| SendMessageA(lpipsi->hwndIP[index], EM_GETSEL, (WPARAM)&startsel, (LPARAM)&endsel); | |
| if(startsel==0 && startsel==endsel && index > 0) | |
| { | |
| IPADDRESS_GotoNextField(lpipsi, index - 2); | |
| l = GetWindowTextLengthA(lpipsi->hwndIP[index-1]); | |
| SendMessageA(lpipsi->hwndIP[index-1], EM_SETSEL, (WPARAM)l,(LPARAM)l); | |
| } | |
| } | |
| if(c == VK_BACK) /* VK_BACKSPACE */ | |
| { | |
| CHAR buf[4]; | |
| SendMessageA(lpipsi->hwndIP[index], EM_GETSEL, (WPARAM)&startsel, (LPARAM)&endsel); | |
| l = GetWindowTextLengthA (lpipsi->hwndIP[index]); | |
| if(startsel==endsel && startsel==0 && index > 0) | |
| { | |
| l = GetWindowTextLengthA(lpipsi->hwndIP[index-1]); | |
| if(l!=0) | |
| { | |
| GetWindowTextA (lpipsi->hwndIP[index-1],buf,4); | |
| buf[l-1] = '\0'; | |
| SetWindowTextA(lpipsi->hwndIP[index-1], buf); | |
| SendMessageA(lpipsi->hwndIP[index-1], EM_SETSEL, (WPARAM)l,(LPARAM)l); | |
| } | |
| IPADDRESS_GotoNextField(lpipsi, index - 2); | |
| } | |
| } | |
| break; | |
| default: | |
| break; | |
| } | |
| return CallWindowProcA (lpipsi->wpOrigProc[index], hwnd, uMsg, wParam, lParam); | |
| } | |
| static LRESULT WINAPI | |
| IPADDRESS_WindowProc (HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam) | |
| { | |
| TRACE("hwnd=%x msg=%x wparam=%x lparam=%lx\n", hwnd, uMsg, wParam, lParam); | |
| if (!IPADDRESS_GetInfoPtr (hwnd) && (uMsg != WM_CREATE)) | |
| return DefWindowProcA (hwnd, uMsg, wParam, lParam); | |
| switch (uMsg) | |
| { | |
| case IPM_CLEARADDRESS: | |
| return IPADDRESS_ClearAddress (hwnd, wParam, lParam); | |
| case IPM_SETADDRESS: | |
| return IPADDRESS_SetAddress (hwnd, wParam, lParam); | |
| case IPM_GETADDRESS: | |
| return IPADDRESS_GetAddress (hwnd, wParam, lParam); | |
| case IPM_SETRANGE: | |
| return IPADDRESS_SetRange (hwnd, wParam, lParam); | |
| case IPM_SETFOCUS: | |
| return IPADDRESS_SetFocusToField (hwnd, wParam, lParam); | |
| case IPM_ISBLANK: | |
| return IPADDRESS_IsBlank (hwnd, wParam, lParam); | |
| case WM_CREATE: | |
| return IPADDRESS_Create (hwnd, wParam, lParam); | |
| case WM_DESTROY: | |
| return IPADDRESS_Destroy (hwnd, wParam, lParam); | |
| case WM_GETDLGCODE: | |
| return DLGC_WANTARROWS | DLGC_WANTCHARS; | |
| case WM_KILLFOCUS: | |
| return IPADDRESS_KillFocus (hwnd, wParam, lParam); | |
| case WM_LBUTTONDOWN: | |
| return IPADDRESS_LButtonDown (hwnd, wParam, lParam); | |
| case WM_PAINT: | |
| return IPADDRESS_Paint (hwnd, wParam); | |
| case WM_SETFOCUS: | |
| return IPADDRESS_SetFocus (hwnd, wParam, lParam); | |
| case WM_SIZE: | |
| return IPADDRESS_Size (hwnd, wParam, lParam); | |
| default: | |
| if (uMsg >= WM_USER) | |
| ERR("unknown msg %04x wp=%08x lp=%08lx\n", | |
| uMsg, wParam, lParam); | |
| return DefWindowProcA (hwnd, uMsg, wParam, lParam); | |
| } | |
| return 0; | |
| } | |
| void IPADDRESS_Register (void) | |
| { | |
| WNDCLASSA wndClass; | |
| ZeroMemory (&wndClass, sizeof(WNDCLASSA)); | |
| wndClass.style = CS_GLOBALCLASS; | |
| wndClass.lpfnWndProc = (WNDPROC)IPADDRESS_WindowProc; | |
| wndClass.cbClsExtra = 0; | |
| wndClass.cbWndExtra = sizeof(IPADDRESS_INFO *); | |
| wndClass.hCursor = LoadCursorA (0, IDC_ARROWA); | |
| wndClass.hbrBackground = (HBRUSH)(COLOR_3DFACE + 1); | |
| wndClass.lpszClassName = WC_IPADDRESSA; | |
| RegisterClassA (&wndClass); | |
| } | |
| VOID IPADDRESS_Unregister (void) | |
| { | |
| UnregisterClassA (WC_IPADDRESSA, (HINSTANCE)NULL); | |
| } |