SOL9 Sample: SolIPAdapterAddressesWatcher

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * SolIPAdapterAddressesWatcher.cpp 
 * Copyright (c) 2015 Antillia.com TOSHIYUKI ARAI. ALL RIGHTS RESERVED. 
 */



// SOL++2000
// 2008/07/29

// 2009/09/07 Modified to show folder and string icons for items of a treeview.

#define COMMONCONTROLS_V6

#include <sol\ApplicationView.h>
#include <sol\TreeView.h>
#include <sol\Thread.h>
#include <sol\StatusBar.h>

#include <sol\net\IPAdapterAddresses.h>
#include <sol\FileVersionDialog.h>
#include <sol\Stdio.h>
#include "resource.h"


#include <process.h>

#pragma comment(lib, "ws2_32.lib")

#pragma comment(lib, "iphlpapi.lib")

namespace SOL {

/**
 * IPAdapterAddressesWatcherThread class. Detect address change by Windows API NotifyAddrChange
 * and show the addresses to ListView.
 */
class IPAdapterAddressesWatcherThread :public Thread {

private:
  IPAdapterAddresses info;
  TreeView&  treeView;
  StatusBar& statusBar;
  bool    looping;
      
  StringConverter converter;

  int    folderIndex;
  int    stringIndex;

public:
  /**
   * Constructor
   */
  IPAdapterAddressesWatcherThread(TreeView& tree,StatusBar& sbar)
  :treeView(tree),
   statusBar(sbar)
  {
    looping = true;
  }

public:
  //2009/09/07
  void setIconIndex(int fIndex, int sIndex)
  {
    folderIndex = fIndex;
    stringIndex = sIndex;
  }


private:
  void listup()
  {
    //Wait for 2 seconds.
    sleep(2000);

    treeView.deleteAllItems();

    info.listup();
    
    int count = 0;

    PIP_ADAPTER_ADDRESSES adpters = info.getAdaptersAddresses(count);
    TCHAR item[1024];

    for(PIP_ADAPTER_ADDRESSES adpt= adpters ; adpt!=NULL; adpt = adpt->Next){
      //Ignore data_link or loop_back
      /*
      if(adpt->PhysicalAddressLength == 0 ||  
      */
      if (adpt->IfType == IF_TYPE_SOFTWARE_LOOPBACK ) {
        //printf("Ignore loopback\n");
        continue;     // Ignore 
      }
      // 1 friendlyName :up/down

      //const char* friendlyName = converter.toMultiByte(adpt->FriendlyName);
      String friendlyName = adpt->FriendlyName;

      String operStatus;
      info.getNameOfOperStatus(adpt->OperStatus, operStatus);
      _stprintf_s(item, CountOf(item), _T("%s:%s"), 
        (const TCHAR*)friendlyName, (const TCHAR*)operStatus);
    //  delete [] friendlyName;

      HTREEITEM hAdapter = treeView.addItem(item, 0, folderIndex, folderIndex);
  
      // 1.1 Descirption(WCHAR*)
      String desc = adpt->Description;
      //char *desc = converter.toMultiByte(adpt->Description);
      _stprintf_s(item, CountOf(item), _T("Description:%s"), (const TCHAR*)desc);
      //delete [] desc;
      treeView.addItem(hAdapter, item, 0, stringIndex, stringIndex);

      // 1.1 AdapterName
      String cfname = adpt->AdapterName;
      _stprintf_s(item, CountOf(item), _T("AdaperName:%s"), (const TCHAR*)cfname);      
      treeView.addItem(hAdapter, item, 0, stringIndex, stringIndex);

      String nameType;
      info.getNameOfIfType(adpt->IfType, nameType);
      
      // 1.1 Type
      _stprintf_s(item, CountOf(item), _T("Type:%s"), (const TCHAR*)nameType);
      treeView.addItem(hAdapter, item, 0, stringIndex, stringIndex);

      // 1.1 PhysicalAddress
      if (adpt->PhysicalAddressLength>0) {
        ByteArray bytes;
        bytes.set(adpt->PhysicalAddress,
            adpt->PhysicalAddressLength);
         printf("PhysicalAddress:");
        bytes.dump();
        String hex = bytes.toStringWithSpace();

        _stprintf_s(item, CountOf(item), _T("PhysicalAddress:%s"), (const TCHAR*) hex);
        //delete [] hex;
        treeView.addItem(hAdapter, item, stringIndex, stringIndex);

      }

      PIP_ADAPTER_UNICAST_ADDRESS unicastAddress = adpt->FirstUnicastAddress;

      if (unicastAddress) {
        // 1.1 UnicastAddress
        HTREEITEM hUni = treeView.addItem(hAdapter, _T("UnicastAddress"), 0, folderIndex, folderIndex);

        while(unicastAddress) {
          String name;
          String prefix;
          String suffix;
          info.getNameInfo(unicastAddress, name, prefix, suffix);

          // 1.1.1 
          _stprintf_s(item, CountOf(item), _T("Address:%s prefix:%s suffix:%s"),
            (const TCHAR*)name,
            (const TCHAR*)prefix,
            (TCHAR*)(const TCHAR*)suffix);

          treeView.addItem(hUni, item, 0, stringIndex, stringIndex);

          unicastAddress = unicastAddress->Next;
        }
      }

      PIP_ADAPTER_ANYCAST_ADDRESS acAddress = adpt->FirstAnycastAddress;
      if (acAddress) {
        // 1.1 "AnycastAddress
        HTREEITEM hAny = treeView.addItem(hAdapter, _T("AnycastAddress"), 0, folderIndex, folderIndex);
        while(acAddress) {
          String name;
          info.getNameOfAddress(acAddress->Address, name);
          // 1.1.1
          _stprintf_s(item, CountOf(item), _T("Address:%s"), (const TCHAR*)name);

          treeView.addItem(hAny,  item, 0, stringIndex, stringIndex);
          acAddress = acAddress->Next;
        }
      }

      printf("Multicast:\n");
      PIP_ADAPTER_MULTICAST_ADDRESS mcAddress = adpt->FirstMulticastAddress;
      if (mcAddress) {
        // 1.1 
        HTREEITEM hMulti = treeView.addItem(hAdapter, _T("MulticastAddress"), 0, folderIndex, folderIndex);

        while(mcAddress) {
          String name;
          info.getNameOfAddress(mcAddress->Address, name);
          //1.1.1
          _stprintf_s(item, CountOf(item), _T("Address:%s"), (const TCHAR*)name);

          treeView.addItem(hMulti, item, 0, stringIndex, stringIndex);
          mcAddress = mcAddress->Next;

        }
      }

      printf("DnsServer:\n");

      PIP_ADAPTER_DNS_SERVER_ADDRESS dsAddress = adpt->FirstDnsServerAddress;
      if (dsAddress) {
        // 1.1
        HTREEITEM hDns = treeView.addItem(hAdapter, _T("DnsServer"), 0, folderIndex, folderIndex);

        while(dsAddress) {
          String name;
          info.getNameOfAddress(dsAddress->Address, name);
          // 1.1.1
          _stprintf_s(item, CountOf(item), _T("Address:%s"), (const TCHAR*)name);

          treeView.addItem(hDns, item, 0, stringIndex, stringIndex);
          dsAddress = dsAddress->Next;
        }
      }
       } //for
    treeView.update(NULL);
  }

public:
  /**
   * Thread procedure
   */
  void run() {
    //setTreeImageList();
    printf("WatcherThread,Started\n");

    listup();
    while (looping) {

      //printf("Waiting NotifyAddrChange\n");
      DWORD ret = NotifyAddrChange(NULL, NULL);
      if (ret == NO_ERROR) {
        listup();
      } else {
        printf("NotifyAddrChange:Error=%d\n", ret);
      }  
    }
  }
};
  
/**
 * SolIPAdapterAddressesWatcher UI class to watch change of ip addresses by using
 * IPAdapterAddressesThread class.
 */
class SolIPAdapterAddressesWatcher :public ApplicationView {

private:
  TreeView  treeView;
  StatusBar  statusBar;

  IPAdapterAddressesWatcherThread thread;
  FileVersionDialog fileVersion;
  
  //2009/09/07
  HIMAGELIST  hImageList;
  int    folderIndex;
  int    stringIndex;

public:
  /**
   * Constructor
   */
  SolIPAdapterAddressesWatcher(Application& applet, const TCHAR* name, Args& args)
    :ApplicationView(applet, name, args),
    thread(treeView, statusBar),
    hImageList(NULL),
    folderIndex(0),
    stringIndex(0)
  {
    Args ar;
    statusBar.create(this, NULL, ar);
    add(statusBar);

    ar.reset();
    ar.set(XmNstyle, TVS_HASBUTTONS|TVS_LINESATROOT);
    treeView.create(this, NULL, ar);
    
    add(treeView);
  
    fileVersion.create(this);

    addEventHandler(WM_CLOSE, this, 
        (Handler)&SolIPAdapterAddressesWatcher::close, NULL);

    addCallback(XmNmenuCallback, IDM_EXIT, this,
      (Callback)&SolIPAdapterAddressesWatcher::exit, NULL);

    addCallback(XmNmenuCallback, IDM_VERSION, this,
      (Callback)&SolIPAdapterAddressesWatcher::version, NULL);

    setTreeImageList();

    thread.setIconIndex(folderIndex, stringIndex);
    
    // Start the IPAdapterAddressesWatcher thread.
    thread.start();
    
    restorePlacement();
  }

private:
  long  size(Event& event)
  {
    int w, h;
    statusBar.getSize(w, h);
    int cw, ch;
    getClientSize(cw, ch);
    treeView.reshape(0, 0, cw, ch-h, 1);

    statusBar.reshape(0, ch-h, cw, h, 1);
    return 1;
  }

private:
  void  exit(Action& action)
  {
    savePlacement();
    if (hImageList) {
      ImageList_Destroy(hImageList);
    }
    destroyWindow();
  }

private:
  void  version(Action& action)
  {
    fileVersion.popupAt(action);
  }

private:
  long close(Event& event)
  {
    savePlacement();
    if (hImageList) {
      ImageList_Destroy(hImageList);
    }
    return defaultProc(event);
  }

private:
  void setTreeImageList()
  {
    if (hImageList == NULL) {
      HINSTANCE hInst = this->getInstanceHandle();
  
      createImageList(hInst);
      treeView.setImageList(hImageList,TVSIL_STATE);
      treeView.setImageList(hImageList,TVSIL_NORMAL);
    }
  }

private:
  bool createImageList(HINSTANCE hInst)
  {
    bool rc = false;  
    this->hImageList = ImageList_Create(16, 16, ILC_COLOR32|ILC_MASK, 10, 5);

    if (this->hImageList) {

      HICON hFolderIcon = (HICON)LoadIcon(hInst, MAKEINTRESOURCE(IDI_FOLDER));
      if (hFolderIcon) {
        this->folderIndex = ImageList_AddIcon(hImageList, hFolderIcon);
      }
      HICON hStringIcon = (HICON)LoadIcon(hInst, MAKEINTRESOURCE(IDI_STRING));
      if (hStringIcon) {
        this->stringIndex = ImageList_AddIcon(hImageList, hStringIcon);
      }
      rc = true;
    }
    return rc;
  }
};

}


// SolIPAdapterAddressesWatcher Main
void  Main(int argc, TCHAR** argv)
{
  //Resouce file (*.rc) the appClass should be a Menu Name and Icon Name

  ModuleFileName module(argv[0]);
  const TCHAR* name = module.getFileName();
  try {
    Application applet(name, argc, argv);
    
    Args args;
    //args.set(XmNclassName, appClass);

    SolIPAdapterAddressesWatcher watcher(applet, name, args);
    watcher.realize();

    applet.run();

  } catch (Exception& ex) {
    caught(ex);
  } catch (...) {
    caught(UnknownException());
  }
}


Last modified: 1 Feb 2017

Copyright (c) 2017 Antillia.com ALL RIGHTS RESERVED.