支持直接粘贴IP字符串的CIPAddressCtrl控件

支持直接粘贴IP字符串的CIPAddressCtrl控件  

       标准的CIPAddreeeCtrl控件在输入IP地址时很不方便,四个字段要一个一个的输入,平时倒没怎么注意,今天多输了几次,觉得很不爽,所以就想做一个能直接粘贴IP字符串的CIPAddreeeCtrl控件。

       思路:
       这种问题当然是要拦截WM_PASTE消息了,只不过WM_PASTE并不是直接发给CIPAddreeeCtrl的,因为CIPAddreeeCtrl下面有4个edit子控件,WM_PASTE是发给它们的。
       接下来的工作就好办了。给edit控件定义一个消息处理函数:收到WM_PASTE时检查剪贴板的内容是不是一个合法的IP地址,如果是,就把IP地址设置到CIPAddreeeCtrl控件,否则就调用缺省的消息处理函数。   
       最后,将edit控件的消息处理函数设置成自定义的函数就可以了。
      
       注意一些细节:
       1. 设置edit控件的消息处理函数时,使用EnumChildWindows()+SetWindowLong();
       2. edit控件设置CIPAddreeeCtrl的IP地址是通过发送一个自定义消息实现的;
       3. 设置edit控件的消息处理函数的工作应放在CMyIPAddressCtrl::PreSubclassWindow()里,这样就不需要在使用CIPAddreeeCtrl的窗口里做什么别的操作了。
       4. 消息处理函数的功能可以加强一点:如果不是合法的IP地址,就再判断是不是合法的数字,不是的话,就忽略掉WM_PASTE消息。

 

MyIPAddressCtrl.h

#pragma once


// CMyIPAddressCtrl

class CMyIPAddressCtrl : public CIPAddressCtrl
{
 DECLARE_DYNAMIC(CMyIPAddressCtrl)

public:
 CMyIPAddressCtrl();
 virtual ~CMyIPAddressCtrl();

private:
 void SetEditWindowProc();
 LRESULT CMyIPAddressCtrl::OnSetAddress(WPARAM wParam, LPARAM lParam);

protected:
 DECLARE_MESSAGE_MAP()
 virtual void PreSubclassWindow();
};


MyIPAddressCtrl.cpp

// MyIPAddressCtrl.cpp : implementation file
//

#include "stdafx.h"
#include "MyIPAddressCtrl.h"
#include "./myipaddressctrl.h"

#define WM_USER_SET_ADDRESS WM_USER+1234
#ifdef STRICT
WNDPROC OldEditWindowProc = NULL;
#else
FARPROC OldEditWindowProc = NULL;
#endif
DWORD ConvertIPAddress( const char *sIP );
BOOL GetTextFromClipboard( HWND hWnd, CString &sText );
BOOL CALLBACK SetEditWindowLong( HWND hWnd, LPARAM param );
LRESULT CALLBACK NewEditWindowProc( HWND hwnd,UINT message,WPARAM wParam,LPARAM lParam );

// CMyIPAddressCtrl

IMPLEMENT_DYNAMIC(CMyIPAddressCtrl, CIPAddressCtrl)

CMyIPAddressCtrl::CMyIPAddressCtrl()
{
}

CMyIPAddressCtrl::~CMyIPAddressCtrl()
{
}

BEGIN_MESSAGE_MAP(CMyIPAddressCtrl, CIPAddressCtrl)
 ON_MESSAGE(WM_USER_SET_ADDRESS, OnSetAddress )
END_MESSAGE_MAP()

// CMyIPAddressCtrl message handlers

void CMyIPAddressCtrl::SetEditWindowProc()
{
 EnumChildWindows( m_hWnd, SetEditWindowLong,NULL );
}

LRESULT CMyIPAddressCtrl::OnSetAddress(WPARAM wParam, LPARAM lParam)
{
 SetAddress( (DWORD)wParam );
 return 0;
}

void CMyIPAddressCtrl::PreSubclassWindow()
{
 // TODO: Add your specialized code here and/or call the base class
 SetEditWindowProc();
 CIPAddressCtrl::PreSubclassWindow();
}

BOOL CALLBACK SetEditWindowLong( HWND hWnd, LPARAM param )
{
 OldEditWindowProc = (WNDPROC) SetWindowLong (hWnd, GWL_WNDPROC, (LONG)NewEditWindowProc );
 return TRUE;
}

LRESULT CALLBACK NewEditWindowProc( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
 if( WM_PASTE == message )
 {
  //::MessageBox(NULL,"click!","",MB_OK);
  CString sText;
  if( GetTextFromClipboard( hwnd, sText ) )
  {
   DWORD dwIPAddress = ConvertIPAddress( sText );
   HWND hParentWnd = ::GetParent( hwnd );
   if( dwIPAddress != -1 && hParentWnd != NULL )
   {
    ::SendMessage( hParentWnd, WM_USER_SET_ADDRESS, dwIPAddress, 0 );
    return 0;
   }
   else
   {
    UINT8 *p = (UINT8*)(LPCSTR)sText;
    BOOL nRet = TRUE;
    while( nRet && *p ) 
     nRet = isdigit( *p++ );
    if( !nRet )
     return 0;
   }
  }
 }
 
 //调用控件原来的消息处理函数
 return CallWindowProc(OldEditWindowProc,hwnd,message,wParam,lParam);
}

DWORD ConvertIPAddress( const char *sIP )
{
  DWORD dwIPAddress = -1;
  BOOL bRet = true;
  int ip[4] = { 0 };
  char tmp[2] = { 0 };
 
  bRet = sIP && *sIP && isdigit( *(UINT8*)sIP )
   && ( 4 == sscanf( sIP, "%d.%d.%d.%d%1s", &ip[0], &ip[1], &ip[2], &ip[3], tmp ) )
   && ( ip[0] >= 0 && ip[0] <= 255 )
   && ( ip[1] >= 0 && ip[1] <= 255 )
   && ( ip[2] >= 0 && ip[2] <= 255 )
   && ( ip[3] >= 0 && ip[3] <= 255 );

  if( bRet )
  {
   dwIPAddress = (ip[0]<<24) | (ip[1]<<16) | (ip[2]<<8) | ip[3];
  }
  return dwIPAddress;
}

BOOL GetTextFromClipboard( HWND hWnd, CString &sText )
{
 BOOL bRet = FALSE;
 if( OpenClipboard( hWnd ) )    
 {  
  HANDLE hData = GetClipboardData( CF_TEXT );  
  if( hData != NULL )
  {
   char *buffer = (char*)GlobalLock( hData );  
   sText = buffer;  
   GlobalUnlock( hData );
   bRet = TRUE;
  }
  CloseClipboard();  
 } 
 return bRet;
}

 

你可能感兴趣的:(callback,null,user,buffer,工作)