上一篇的IP控件存在一个大的问题,就是创建多个控件的时候,每个控件的IP值都会是一样的。原因是我只保存了四个变量,就是一个IP地址。
这篇文章里就已经解决了这问题, 主要是利用minigui 给控件预留的两个附加值, 可以用GetWindowAdditionalData SetWindowAdditionalData GetWindowAdditionalData2 SetWindowAdditionalData2 来访问,参数第一个是窗口,第二个是DWORD值,一般都是结构体的地址。
源代码。 头文件------------
/2012/9/13 15:27:47
//IPSpinBox header file
#define CLASS_CTRL_IPSPINBOX "IPSpinBox"
#define IDC_SPINBOX_IP 200
struct _IPDATA{
int iAddr1;
int iAddr2;
int iAddr3;
int iAddr4;
int iCursor;
};
typedef _IPDATA IPDATA;
HWND CreateIPSpinBoxWindow(const char* spCation,int id,int x,int y,int w,int h,HWND hParentWnd,DWORD dwAddData);
/ define my IPSpinBox control
/2012/9/13 15:26:32
/
#include "SystemMenu.h"
#include "IPSpinBox.h"
static int iAddr1,iAddr2,iAddr3,iAddr4;
static int iCursor = 0;
static WNDPROC old_spinbox_proc;
static RECT rect;
static RECT rcIP1,rcIP2,rcIP3,rcIP4;
static PLOGFONT logFont;
/计算鼠标点击在那个区域
static int ParseClickRect(int x,int y)
{
if(x > rcIP1.left && x < rcIP1.right)
{
iCursor = 1;
}
else if(x > rcIP2.left && x < rcIP2.right)
{
iCursor = 2;
}
else if(x > rcIP3.left && x < rcIP3.right)
{
iCursor = 3;
}
else if(x > rcIP4.left && x < rcIP4.right)
{
iCursor = 4;
}
return iCursor;
}
static int DrawIPAdress(HDC hdc,HWND hwnd)
{
char buf[20];
SelectFont(hdc,logFont);
SetTextCharacterExtra(hdc,2);
if(iCursor == 0 )
{
sprintf(buf,"%3d.%3d.%3d.%3d",iAddr1,iAddr2,iAddr3,iAddr4);
SetBkColor(hdc,RGB2Pixel(hdc,63,72,204));
TextOut(hdc,20,10,buf);
}
else if(iCursor == 1)
{
sprintf(buf,"%3d",iAddr1);
SetBkColor(hdc,RGB2Pixel(hdc,106,116,216));
TextOut(hdc,20,10,buf);
int x = strlen(buf)*(GetSysCharWidth()+GetTextCharacterExtra(hdc)) + 20 ;
SetCaretPos(hwnd,x,10);
sprintf(buf,".%3d.%3d.%3d",iAddr2,iAddr3,iAddr4);
SetBkColor(hdc,RGB2Pixel(hdc,63,72,204));
TextOut(hdc,x,10,buf);
}
else if(iCursor == 2)
{
sprintf(buf,"%3d.",iAddr1);
SetBkColor(hdc,RGB2Pixel(hdc,63,72,204));
TextOut(hdc,20,10,buf);
int x = strlen(buf)*(GetSysCharWidth()+GetTextCharacterExtra(hdc)) + 20;
sprintf(buf,"%3d",iAddr2);
SetBkColor(hdc,RGB2Pixel(hdc,106,116,216));
TextOut(hdc,x,10,buf);
x += strlen(buf)*(GetSysCharWidth() + GetTextCharacterExtra(hdc));
SetCaretPos(hwnd,x,10);
sprintf(buf,".%3d.%3d",iAddr3,iAddr4);
SetBkColor(hdc,RGB2Pixel(hdc,63,72,204));
TextOut(hdc,x,10,buf);
}
else if(iCursor == 3)
{
sprintf(buf,"%3d.%3d.",iAddr1,iAddr2);
SetBkColor(hdc,RGB2Pixel(hdc,63,72,204));
TextOut(hdc,20,10,buf);
int x = strlen(buf)*(GetSysCharWidth()+GetTextCharacterExtra(hdc)) + 20;
sprintf(buf,"%3d",iAddr3);
SetBkColor(hdc,RGB2Pixel(hdc,106,116,216));
TextOut(hdc,x,10,buf);
x += strlen(buf)*(GetSysCharWidth()+GetTextCharacterExtra(hdc));
SetCaretPos(hwnd,x,10);
sprintf(buf,".%3d",iAddr4);
SetBkColor(hdc,RGB2Pixel(hdc,63,72,204));
TextOut(hdc,x,10,buf);
}
else
{
sprintf(buf,"%3d.%3d.%3d.",iAddr1,iAddr2,iAddr3);
SetBkColor(hdc,RGB2Pixel(hdc,63,72,204));
TextOut(hdc,20,10,buf);
int x = strlen(buf)*(GetSysCharWidth()+GetTextCharacterExtra(hdc)) + 20 ;
sprintf(buf,"%3d",iAddr4);
SetBkColor(hdc,RGB2Pixel(hdc,106,116,216));
TextOut(hdc,x,10,buf);
x += strlen(buf)*(GetSysCharWidth()+GetTextCharacterExtra(hdc));
SetCaretPos(hwnd,x,10);
}
ShowCaret(hwnd);
}
static int BackSpaceValue(int num)
{
if(num > 100)
{
int x = num/100;
int y = (num - x*100)/10;
return x*10+y;
}
else if(num >10)
{
int x = num/10;
return x;
}
else
{
return 0;
}
}
static int IPSpinboxControlProc(HWND hwnd,int message,WPARAM wParam,LPARAM lParam)
{
switch(message)
{
case MSG_CREATE:
{
logFont = CreateLogFont ("type1", "arial", "GB2312",
FONT_WEIGHT_BOOK | FONT_WEIGHT_BOLD,
FONT_SLANT_ROMAN, FONT_FLIP_NIL,
FONT_SPACING_CHARCELL, FONT_UNDERLINE_NONE, FONT_STRUCKOUT_NONE,
28, 0);
break;
}
case MSG_PAINT:
{
HDC hdc = BeginPaint(hwnd);
RECT rect;
GetClientRect(hwnd,&rect);
SetBrushColor(hdc,RGB2Pixel(hdc,63,72,204));
FillBox(hdc,rect.left,rect.top,rect.right,rect.bottom);
///取出窗口的数据///
IPDATA *ipdata = (IPDATA*)GetWindowAdditionalData(hwnd);
iAddr1 = ipdata->iAddr1;
iAddr2 = ipdata->iAddr2;
iAddr3 = ipdata->iAddr3;
iAddr4 = ipdata->iAddr4;
iCursor = ipdata->iCursor;
DrawIPAdress(hdc,hwnd);
EndPaint(hwnd,hdc);
break;
}
case CB_SPIN:
{
IPDATA *ipdata = (IPDATA*)GetWindowAdditionalData(hwnd);
if(iCursor <= 1)
{
if(wParam == 0)
{
if(iAddr1 >= 255) iAddr1 = -1;
++iAddr1;
}
else
{
if(iAddr1 <= 0) iAddr1 = 256;
--iAddr1;
}
}
else if(iCursor == 2)
{
if(wParam == 0)
{
if(iAddr2 >= 255) iAddr2 = -1;
++iAddr2;
}
else
{
if(iAddr2 <= 0) iAddr2 = 256;
--iAddr2;
}
}
else if(iCursor == 3)
{
if(wParam == 0)
{
if(iAddr3 >= 255) iAddr3 = -1;
++iAddr3;
}
else
{
if(iAddr3 <= 0) iAddr3 = 256;
--iAddr3;
}
}
else if(iCursor ==4)
{
if(wParam == 0)
{
if(iAddr4 >= 255) iAddr4 = -1;
++iAddr4;
}
else
{
if(iAddr4 <= 0) iAddr4 = 256;
--iAddr4;
}
}
ipdata->iAddr1 = iAddr1;
ipdata->iAddr2 = iAddr2;
ipdata->iAddr3 = iAddr3;
ipdata->iAddr4 = iAddr4;
SetWindowAdditionalData(hwnd,(DWORD)ipdata);
SendMessage(hwnd,MSG_PAINT,wParam,lParam);
return 0;
}
case MSG_KEYDOWN:
{
if(wParam == SCANCODE_BACKSPACE)
{
switch(iCursor)
{
case 0:
case 1:
{
iAddr1 = BackSpaceValue(iAddr1);
break;
}
case 2:
{
iAddr2 = BackSpaceValue(iAddr2);
break;
}
case 3:
{
iAddr3 = BackSpaceValue(iAddr3);
break;
}
case 4:
{
iAddr4 = BackSpaceValue(iAddr4);
break;
}
}
}
IPDATA *ipdata = (IPDATA*)GetWindowAdditionalData(hwnd);
ipdata->iAddr1 = iAddr1;
ipdata->iAddr2 = iAddr2;
ipdata->iAddr3 = iAddr3;
ipdata->iAddr4 = iAddr4;
SetWindowAdditionalData(hwnd,(DWORD)ipdata);
SendMessage(hwnd,MSG_PAINT,wParam,lParam);
return 0;
}
case MSG_CHAR:
{
if((wParam >= 'A' && wParam <= 'Z' && wParam) || (wParam >= 'a' && wParam <= 'z')) return 0;
else if(wParam >= '0' && wParam <= '9')
{
switch(iCursor)
{
case 0:
case 1:
{
if(iAddr1 >100)
{
return 0;
}
if((iAddr1 = iAddr1*10+(int)wParam - 48) > 255)
iAddr1 = 255;
break;
}
case 2:
{
if(iAddr2 >100)
{
return 0;
}
if((iAddr2 = iAddr2*10+(int)wParam - 48) > 255)
iAddr2 = 255;
break;
}
case 3:
{
if(iAddr3 >100)
{
return 0;
}
if((iAddr3 = iAddr3*10+(int)wParam - 48) > 255)
iAddr3 = 255;
break;
}
case 4:
{
if(iAddr4 >100)
{
return 0;
}
if((iAddr4 = iAddr4*10+(int)wParam - 48) > 255)
iAddr4 = 255;
break;
}
}
IPDATA *ipdata = (IPDATA*)GetWindowAdditionalData(hwnd);
ipdata->iAddr1 = iAddr1;
ipdata->iAddr2 = iAddr2;
ipdata->iAddr3 = iAddr3;
ipdata->iAddr4 = iAddr4;
SetWindowAdditionalData(hwnd,(DWORD)ipdata);
}
SendMessage(hwnd,MSG_PAINT,wParam,lParam);
return 0;
}
case MSG_LBUTTONDOWN:
{
int pos_x,pos_y;
pos_x = LOWORD(lParam);
pos_y = HIWORD(lParam);
IPDATA *ipData = (IPDATA*)GetWindowAdditionalData(hwnd);
ipData->iCursor = ParseClickRect(pos_x,pos_y);
SetWindowAdditionalData(hwnd,(DWORD)ipData);
CreateCaret(hwnd,NULL,1,GetSysCharHeight());
SendMessage(hwnd,MSG_PAINT,wParam,lParam);
break;
}
case MSG_MOUSEMOVEIN:
{
HideCaret(hwnd);
DestroyCaret(hwnd);
IPDATA *ipData = (IPDATA*)GetWindowAdditionalData(hwnd);
ipData->iCursor = iCursor = 0;
SetWindowAdditionalData(hwnd,(DWORD)ipData);
SendMessage(hwnd,MSG_PAINT,wParam,lParam);
break;
}
case MSG_DESTROY:
{
IPDATA *ipdata = (IPDATA*)GetWindowAdditionalData(hwnd);
free(ipdata);
DestroyLogFont(logFont);
}
}
return (*old_spinbox_proc)(hwnd,message,wParam,lParam);
}
HWND CreateIPSpinBoxWindow(const char* spCation,int id,int x,int y,int w,int h,HWND hParentWnd,DWORD dwAddData)
{
IPDATA *ipdata;
ipdata = (IPDATA*)malloc(sizeof(IPDATA));
ipdata->iAddr1 = ipdata->iAddr2 = ipdata->iAddr3 = ipdata->iAddr4 = 255;
ipdata->iCursor = 0;
HWND hwnd = CreateWindow(CTRL_COMBOBOX,spCation,WS_VISIBLE | WS_CHILD | CBS_AUTOSPIN | CBS_AUTOLOOP,id,x,y,w,h,hParentWnd,dwAddData);
SetWindowAdditionalData(hwnd,(DWORD)ipdata);
HDC hdc;
HWND hwnd_edit,hwnd_list;
SendMessage(hwnd,CB_GETCHILDREN,(WPARAM)&hwnd_edit,(LPARAM)&hwnd_list);
EnableWindow(hwnd_edit,false);
hdc = GetClientDC(hwnd_edit);
GetClientRect(hwnd_edit,&rect);
rcIP1.top = rcIP2.top = rcIP3.top = rcIP4.top = rect.top;
rcIP1.bottom = rcIP2.bottom = rcIP3.bottom = rcIP4.bottom = rect.bottom;
rcIP1.left = rect.left;
rcIP1.right = rect.right/4;
rcIP2.left = rect.right/4;
rcIP2.right = rect.right/2;
rcIP3.left = rect.right/2;
rcIP3.right = rect.right - rect.right/3;
rcIP4.left = rect.right - rect.right/3;
rcIP4.right = rect.right;
SetWindowBkColor(hwnd_edit,RGB2Pixel(hdc,63,72,204));
old_spinbox_proc = SetWindowCallbackProc(hwnd,IPSpinboxControlProc);
ReleaseDC(hdc);
return hwnd;
}
使用方法还是很简单哈,直接调用 CreateIPSpinBoxWindow函数就可以,参数没有类名了,其他跟CreateWindow一样。
结构体就是保存IP值的关键数据。 其实这个还有个问题就是如果你创建多个IP控件大小不一样的时候,你会发现数据也会存在异常,原因跟保存IP值是一样的,这里就不解决了,有需要的可以自己去改就是。 也很简单,直接把4个RECT 加到IPDATA里面,然后在初始化的时候赋值,在要用的时候取出来就可以了。
至此,改IP控件已经实现了一个IP控件应有的功能,就到此结束了。
用鼠标点击要修改的字节,可以用右边的spin按钮改变IP值,也可以输入。