SOL9 2.0 Sample: SolIPAdapterAddressesWatcher

SOL9 2.0 Samples

1 Screenshot


2 Source code

/*
 * SolIPAdapterAddressesWatcher.cpp 
 * Copyright (c) 2009 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.

#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, SizeOf(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, SizeOf(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, SizeOf(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, SizeOf(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, SizeOf(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, SizeOf(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, SizeOf(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, SizeOf(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, SizeOf(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

    const String appClass = "SolIPAdapterAddressesWatcher";
    try {
        Application applet(appClass, argc, argv);
        
        Args args;
        //args.set(XmNclassName, appClass);

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

        applet.run();
    } catch (...) {

    }
}


Last modified: 11 Nov 2009

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