示例#1
0
void Contact::update() {
    std::string s=(nickname.empty())? jid.getBareJid():nickname;
    std::string resource=jid.getResource();
	clientIcon=0;	if(Config::getInstance()->confclient){/*
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"bombus-im.org/ng")!=NULL){clientIcon=icons::ICON_BOMBUS_NG;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"tkabber")!=NULL){clientIcon=icons::ICON_TKAB;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"bombusmod-qd")!=NULL){clientIcon=icons::ICON_BOMBUS_QD;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"gajim")!=NULL){clientIcon=icons::ICON_GAJIM;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"Siemens Native Jabber Client")!=NULL){clientIcon=icons::ICON_SJC;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"qip")!=NULL){clientIcon=icons::ICON_QIP;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"pidgin")!=NULL){clientIcon=icons::ICON_PIDGIN;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"miranda")!=NULL){clientIcon=icons::ICON_MIRANDA;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"kopete")!=NULL){clientIcon=icons::ICON_KOPET;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"bombus-im.org/java")!=NULL){clientIcon=icons::ICON_BOMBUS;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"psi")!=NULL){clientIcon=icons::ICON_PSI;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"bombusmod.net.ru")!=NULL){clientIcon=icons::ICON_BOMBUSMOD;}else{
	if(wcsstr(utf8::utf8_wchar(getClientIdIcon()).c_str(),L"bombusng-qd.googlecode.com")!=NULL){clientIcon=icons::ICON_BOMBUS_QD_NG;

	}else{
		clientIcon=0;

	}}}}}}}}}}}}}}*/
Skin * il= dynamic_cast<Skin *>(skin.get());
 std::string ClientI=getClientIdIcon();

 if(ClientI.length()>2 ){if (il) clientIcon=il->getKlientIndex((char*)ClientI.c_str());}else clientIcon=0;
	}
    if (resource.length()) { s+='/'; s+=resource; }
    wjid=utf8::utf8_wchar( s );
    init();
}
示例#2
0
int identifyTransport(const std::string &jid) {
    int serv=jid.find('@')+1;
    int dotsrv=jid.find('.', serv);
    if (dotsrv<0) return 0;

    Skin * il= dynamic_cast<Skin *>(skin.get());
    if (!il) return 0;
    return il->getBaseIndex(jid.substr(serv, dotsrv-serv));
}
示例#3
0
LRESULT CALLBACK ServiceDiscovery::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {
    PAINTSTRUCT ps;
    HDC hdc;
    ServiceDiscovery *p=(ServiceDiscovery *) GetWindowLong(hWnd, GWL_USERDATA);

    switch (message) {
    case WM_CREATE:
        {
            p=(ServiceDiscovery *) (((CREATESTRUCT *)lParam)->lpCreateParams);
            SetWindowLong(hWnd, GWL_USERDATA, (LONG) p );

            //p->nodeList=VirtualListView::ref(new VirtualListView(hWnd, std::string("disco")));
            DiscoListView * dlv = new DiscoListView(hWnd, std::string("disco"));
            //dlv->serviceDiscovery=p->thisRef;

            p->nodeList=VirtualListView::ref(dlv);
            p->nodeList->setParent(hWnd);
            p->nodeList->showWindow(true);
            //p->nodeList->wrapList=false;
            //p->nodeList->colorInterleaving=true;

            RECT rect;
            p->editWnd=DoCreateComboControl(hWnd);
            GetWindowRect(p->editWnd, &rect);
            p->editHeight=rect.bottom-rect.top+2;
            mru::readMru(MRU_DISCO_JIDS, p->editWnd, NULL);

            //p->msgList->bindODRList(p->contact->messageList);
            break;
        }

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);

        {
            //p->contact->nUnread=0;
            RECT rc = {0, 0, 200, tabHeight};
            SetBkMode(hdc, TRANSPARENT);
            //SetTextColor(hdc, p->contact->getColor());
            //p->contact->draw(hdc, rc);

            skin->drawElement(hdc, icons::ICON_CLOSE, p->width-2-skin->getElementWidth(), 0);
            skin->drawElement(hdc, icons::ICON_SEARCH_INDEX, p->width-4-skin->getElementWidth()*2, 0);

            

            /*SetBkMode(hdc, TRANSPARENT);
            LPCTSTR t=p->title.c_str();
            DrawText(hdc, t, -1, &rc, DT_CALCRECT | DT_LEFT | DT_TOP);
            DrawText(hdc, t, -1, &rc, DT_LEFT | DT_TOP);*/
        }

        EndPaint(hWnd, &ps);
        break;

    case WM_SIZE: 
        { 
            HDWP hdwp; 
            RECT rc; 

            int height=GET_Y_LPARAM(lParam);
            p->width=GET_X_LPARAM(lParam);

            // Calculate the display rectangle, assuming the 
            // tab control is the size of the client area. 
            SetRect(&rc, 0, 0, 
                GET_X_LPARAM(lParam), height ); 

            // Size the tab control to fit the client area. 
            hdwp = BeginDeferWindowPos(2);

            DeferWindowPos(hdwp, p->editWnd, NULL, 1, 1, 
                GET_X_LPARAM(lParam)-(tabHeight*2+2), p->editHeight, 
                SWP_NOZORDER 
                ); 


            DeferWindowPos(hdwp, p->nodeList->getHWnd(), HWND_TOP, 0, p->editHeight, 
                GET_X_LPARAM(lParam), height - p->editHeight, 
                SWP_NOZORDER 
                );

            EndDeferWindowPos(hdwp); 

            break; 
        } 

    case WM_COMMAND: 
        {
            switch (LOWORD(wParam)) {
            case IDOK:
                {
                    updateComboHistory(p->editWnd);
                    while (!p->nodes.empty()) p->nodes.pop();
                    p->nodeList->bindODRList(ODRListRef());
                    p->newNode.clear();
                    p->go();
                    break;
                }
            }
        }
        if (HIWORD(wParam)==CBN_DROPDOWN) {
            int nitems=SendMessage(p->editWnd, CB_GETCOUNT, 0, 0);
            if (nitems<=0) break;
            int h=SendMessage(p->editWnd, CB_GETITEMHEIGHT, 0, 0)*10;//+p->editHeight;
            RECT rc;
            GetWindowRect((HWND)lParam, &rc);
            int result=SetWindowPos((HWND)lParam, NULL, 0,0, rc.right-rc.left, h, SWP_NOZORDER | SWP_NOMOVE );
        }
        break;             

    case WM_LBUTTONDOWN:
        SetFocus(hWnd);
        if ((GET_Y_LPARAM(lParam)) > p->editHeight) break;
        if (GET_X_LPARAM(lParam) > p->width-2-skin->getElementWidth()) {
            mru::saveMru(MRU_DISCO_JIDS, p->editWnd);
            PostMessage(GetParent(hWnd), WM_COMMAND, TabsCtrl::CLOSETAB, 0);
            break;
        }
        if (GET_X_LPARAM(lParam) > p->width-2-2*skin->getElementWidth()) {
            SendMessage(hWnd, WM_COMMAND, IDOK, 0);
        }
        break;

    case WM_NOTIFY_BLOCKARRIVED:
        p->parseResult();
        return 0;

    case WM_DESTROY:
        //TODO: Destroy all child data associated eith this window

        return 0;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
示例#4
0
ProcessResult ProcessMuc::blockArrived(JabberDataBlockRef block, const ResourceContextRef rc){

    JabberDataBlockRef xmuc=block->findChildNamespace("x", "http://jabber.org/protocol/muc#user");
    if (!xmuc) return BLOCK_REJECTED;

    const std::string &from=block->getAttribute("from");
    const std::string &type=block->getAttribute("type");

    Jid roomNode;
    roomNode.setJid(from);

    std::string message;

    //1. group
    MucGroup::ref roomGrp;
    roomGrp=boost::dynamic_pointer_cast<MucGroup> (rc->roster->findGroup(roomNode.getBareJid()));

    if (!roomGrp) return BLOCK_PROCESSED; //dropped presence

    MucContact::ref c=getMucContactEntry(from, rc);

    MPA action=NONE;

    if (type=="error") {
        JabberDataBlockRef error=block->getChildByName("error");
        int errCode=atoi(error->getAttribute("code").c_str());

        //todo: if (status>=Presence.PRESENCE_OFFLINE) testMeOffline();
        action=LEAVE;
        
        //todo: if (errCode!=409 || status>=Presence.PRESENCE_OFFLINE)  setStatus(presenceType);

        std::string errText=error->getChildText("text");
        if (errText.length()>0) message=errText; // if error description is provided by server
        else // legacy codes
            switch (errCode) {
                case 401: message="Password required";
                case 403: message="You are banned in this room";
                case 404: message="Room does not exists";
                case 405: message="You can't create room on this server";
                case 406: message="Reserved roomnick must be used";
                case 407: message="This room is members-only";
                case 409: message="Nickname is already in use by another occupant";
                case 503: message="Maximum number of users has been reached in this room";
                default: message=*(error->toXML());
            }
    } else {
        JabberDataBlockRef item=xmuc->getChildByName("item");   

        MucContact::Role role = 
            getRoleIndex(item->getAttribute("role"));
        c->sortKey=MucContact::MODERATOR-role;
        
        MucContact::Affiliation affiliation = 
            getAffiliationIndex(item->getAttribute("affiliation"));

        boolean roleChanged= c->role != role;
        boolean affiliationChanged= c->affiliation !=affiliation;
    
        c->role=role;
        c->affiliation=affiliation;

        

        //setSortKey(nick);

        switch (role) {
        case MucContact::MODERATOR:
            c->transpIndex=icons::ICON_MODERATOR_INDEX;
            break;
        case MucContact::VISITOR:
            {
                Skin * il= dynamic_cast<Skin *>(skin.get());
                c->transpIndex=(il)? il->getBaseIndex("visitors") : 0;
                break;
            }
        default:
            c->transpIndex=0;
        }

        JabberDataBlockRef statusBlock=xmuc->getChildByName("status");
        int statusCode=(statusBlock)? atoi(statusBlock->getAttribute("code").c_str()) : 0; 

        message=c->jid.getResource(); // nick

        if (type=="unavailable") {
            action=LEAVE;
            std::string reason=item->getChildText("reason");

            switch (statusCode) {
            case 303:
                message+=" is now known as ";
                message+=item->getAttribute("nick");
                c->jid.setResource(item->getAttribute("nick"));
                c->rosterJid=c->jid.getJid(); //for vCard
                c->update();
                action=NONE;
                break;

            case 307: //kick
            case 301: //ban
                message+=(statusCode==307)?" was kicked " : " was banned ";
                message+="(";
                message+=reason;
                message+=")";

                if (c->realJid.length()>0){
                    message+=" - ";
                    message+=c->realJid;
                }
                break;

            case 321:
                message+=" has been unaffiliated and kicked from members-only room";
                break;

            case 322:
                message+=" has been kicked because room became members-only";
                break;

            default:
                {
                    message+=" has left the channel";
                    const std::string & status=block->getChildText("status");
                    if (status.length()) {
                        message+=" (";
                        message+=status;
                        message+=")";
                    }
                }
            }
        } else { //onlines
            action=ENTER;
            if (c->status>=presence::OFFLINE) {
                // first online
                std::string realJid=item->getAttribute("jid");
                if (realJid.length()) {
                    c->realJid=realJid;
                    message+=" (";
                    message+=realJid;  //for moderating purposes
                    message+=")";
                }
                message+=" has joined the channel as ";
                message+=roleName[role];

                if (affiliation!=MucContact::NONE) {
                    message+=" and ";
                    message+=affiliationName[affiliation-MucContact::OUTCAST];

                    const std::string & status=block->getChildText("status");
                    if (status.length()) {
                        message+=" (";
                        message+=status;
                        message+=")";
                    }
                }
            } else {
                //change status
                message+=" is now ";

                if ( roleChanged ) message+=roleName[role];
                if (affiliationChanged) {
                    if (roleChanged) message+=" and ";
                    message+=(affiliation==MucContact::NONE)? 
                        "unaffiliated" : affiliationName[affiliation-MucContact::OUTCAST];
                }
                if (!roleChanged && !affiliationChanged) {
                    const std::string &show=block->getChildText("show");
                    if (show.length()==0) message+="online";
                    else message+=show;

                    const std::string & status=block->getChildText("status");
                    if (status.length()) {
                        message+=" (";
                        message+=status;
                        message+=")";
                    }

                }
            }
        }
    }

    if (c.get()==roomGrp->selfContact.get()) {
        switch (action) {
            case ENTER:
                // room contact is online
                roomGrp->room->status=presence::ONLINE;
                break;
            case LEAVE:
                // room contact is offline
                roomGrp->room->status=presence::OFFLINE;
                // make all occupants offline
                rc->roster->setStatusByFilter(roomNode.getBareJid(), presence::OFFLINE);
                break;
        }
    }

    {
        ChatView *cv = dynamic_cast<ChatView *>(tabs->getWindowByODR(c).get());

        bool ascroll=(cv==NULL)? false: cv->autoScroll();

        c->processPresence(block);

        if (ascroll) {
            cv->moveEnd();
        }
        if (cv) if (IsWindowVisible(cv->getHWnd())) cv->redraw();
    }
    rc->roster->makeViewList();


    {
        Message::ref msg=Message::ref(new Message(message, from, false, Message::PRESENCE, Message::extractXDelay(block) ));

        Contact::ref room=roomGrp->room;

        ChatView *cv = dynamic_cast<ChatView *>(tabs->getWindowByODR(room).get());

        bool ascroll=(cv==NULL)? false: cv->autoScroll();
        room->messageList->push_back(msg);

        if (ascroll) {
            cv->moveEnd();
        }
        if (cv) if (IsWindowVisible(cv->getHWnd())) cv->redraw();
    }

    return BLOCK_PROCESSED;
}
示例#5
0
LRESULT CALLBACK ChatView::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {
    PAINTSTRUCT ps;
    HDC hdc;
    ChatView *p=(ChatView *) GetWindowLong(hWnd, GWL_USERDATA);

    switch (message) {
    case WM_CREATE:
        {
            p=(ChatView *) (((CREATESTRUCT *)lParam)->lpCreateParams);
            SetWindowLong(hWnd, GWL_USERDATA, (LONG) p );

            p->msgList=VirtualListView::ref(new VirtualListView(hWnd, std::string("Chat")));
            p->msgList->setParent(hWnd);
            p->msgList->showWindow(true);
            p->msgList->wrapList=false;
            p->msgList->colorInterleaving=true;

            p->editWnd=DoCreateEditControl(hWnd);
            p->calcEditHeight();

            p->msgList->bindODRList(p->contact->messageList);
            break;
        }

    case WM_PAINT:
        hdc = BeginPaint(hWnd, &ps);

        {
            //p->contact->nUnread=0;
            RECT rc = {0, 0, 200, tabHeight};
            SetBkMode(hdc, TRANSPARENT);
            SetTextColor(hdc, p->contact->getColor());
            p->contact->draw(hdc, rc);

            int iconwidth= skin->getElementWidth();
            skin->drawElement(hdc, icons::ICON_CLOSE, p->width-2-iconwidth, 0);
            skin->drawElement(hdc, icons::ICON_TRASHCAN_INDEX, p->width-2-iconwidth*2, 0);

            /*SetBkMode(hdc, TRANSPARENT);
            LPCTSTR t=p->title.c_str();
            DrawText(hdc, t, -1, &rc, DT_CALCRECT | DT_LEFT | DT_TOP);
            DrawText(hdc, t, -1, &rc, DT_LEFT | DT_TOP);*/
        }

        EndPaint(hWnd, &ps);
        break;

    //case WM_KILLFOCUS:
    //    p->contact->nUnread=0;
    //    break;

    case WM_SIZE: 
        { 
            HDWP hdwp; 
            RECT rc; 

            int height=GET_Y_LPARAM(lParam);
            p->width=GET_X_LPARAM(lParam);

            int ySplit=height-p->editHeight;

            p->calcEditHeight();

            // Calculate the display rectangle, assuming the 
            // tab control is the size of the client area. 
            SetRect(&rc, 0, 0, 
                GET_X_LPARAM(lParam), ySplit ); 

            // Size the tab control to fit the client area. 
            hdwp = BeginDeferWindowPos(2);

            /*DeferWindowPos(hdwp, dropdownWnd, HWND_TOP, 0, 0, 
            GET_X_LPARAM(lParam), 20, 
            SWP_NOZORDER 
            ); */


            DeferWindowPos(hdwp, p->msgList->getHWnd(), HWND_TOP, 0, tabHeight, 
                GET_X_LPARAM(lParam), ySplit-tabHeight, 
                SWP_NOZORDER 
                );
            /*DeferWindowPos(hdwp, rosterWnd, HWND_TOP, 0, tabHeight, 
            GET_X_LPARAM(lParam), height-tabHeight, 
            SWP_NOZORDER 
            );*/

            DeferWindowPos(hdwp, p->editWnd, NULL, 0, ySplit+1, 
                GET_X_LPARAM(lParam), height-ySplit-1, 
                SWP_NOZORDER 
                ); 

            EndDeferWindowPos(hdwp); 

            break; 
        } 

    case WM_COMMAND: 
        {
            if (wParam==IDS_SEND) {
                p->sendJabberMessage();
            }
            if (wParam==IDC_COMPLETE) {
                p->mucNickComplete();
            }

            if (wParam==IDC_COMPOSING) {
                p->setComposingState(lParam!=0);
            }
            break;             
        }
        /*case WM_CTLCOLORSTATIC:
        case WM_CTLCOLORLISTBOX:
        case WM_CTLCOLOREDIT: 
        {
        //HGDIOBJ brush= GetStockObject(GRAY_BRUSH);
        //HGDIOBJ pen= GetStockObject(WHITE_PEN);
        SetBkColor(hdc, 0x808080);
        SetTextColor(hdc, 0xffffff);
        //SelectObject((HDC)wParam, brush);
        //SelectObject((HDC)wParam, pen);
        return (BOOL) GetStockObject(GRAY_BRUSH);
        break;
        }*/

    case WM_LBUTTONDOWN:
        SetFocus(hWnd);
        if ((GET_Y_LPARAM(lParam))>tabHeight) break;
        
        if (GET_X_LPARAM(lParam) > (p->width)-2-(skin->getElementWidth()) ) {
            PostMessage(GetParent(hWnd), WM_COMMAND, TabsCtrl::CLOSETAB, 0);
            break;
        }
        if (GET_X_LPARAM(lParam) > (p->width)-2-(skin->getElementWidth())*2) {
            int result=MessageBox(
                p->getHWnd(), 
                L"Are You sure want to clear this chat session?", 
                L"Clear chat", 
                MB_YESNO | MB_ICONWARNING);
            if (result==IDYES) {
                p->contact->messageList->clear();
                p->msgList->moveCursorEnd();
            }
            break;
        }
        break;

    case WM_DESTROY:
        //TODO: Destroy all child data associated eith this window

        return 0;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}
示例#6
0
LRESULT CALLBACK HtmlView::WndProc( HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam ) {
    HtmlView *p=(HtmlView *) GetWindowLong(hWnd, GWL_USERDATA);

    switch (message) {
    case WM_CREATE:
        {
            p=(HtmlView *) (((CREATESTRUCT *)lParam)->lpCreateParams);
            SetWindowLong(hWnd, GWL_USERDATA, (LONG) p );


            RECT rc;

            GetClientRect (hWnd, &rc);

            p->htmlHWnd = CreateWindow (
                DISPLAYCLASS, 
                NULL, 
                WS_CHILD | WS_VISIBLE | /*WS_VSCROLL |*/ WS_CLIPSIBLINGS, 
                rc.left, rc.top,
                rc.right - rc.left, rc.bottom - rc.top, 
                hWnd, 
                0, //(HMENU)IDC_HTMLVIEW, 
                g_hInst, 
                NULL);

            SetFocus(p->htmlHWnd);

            HWND hwndHTML=p->htmlHWnd;
            bool   fFitToPage = TRUE;
            PostMessage(hwndHTML, DTM_ENABLESHRINK, 0, fFitToPage);

            SendMessage(hwndHTML, WM_SETTEXT, 0, (LPARAM)"");
            SendMessage(hwndHTML, DTM_ADDTEXT, FALSE, 
                (LPARAM)"<HTML><TITLE>Test</TITLE><BODY><P>Loading...<BR></BODY></HTML>");
            SendMessage(hwndHTML, DTM_ENDOFSOURCE, 0, (LPARAM)NULL);


            /*SendMessage(hwndHTML, WM_SETTEXT, 0, (LPARAM)"");
            SendMessage(hwndHTML, DTM_ADDTEXTW, FALSE, (LPARAM)TEXT("<HTML><TITLE>Test</TITLE>"));
            SendMessage(hwndHTML, DTM_ADDTEXTW, FALSE, (LPARAM)TEXT("<BODY><P>"));
            SendMessage(hwndHTML, DTM_ADDTEXTW, FALSE, (LPARAM)TEXT("<h1>Heading</h1>Normal Text<BR>"));
            SendMessage(hwndHTML, DTM_ADDTEXTW, FALSE, (LPARAM)TEXT("<A HREF=\"www.voscorp.com\"><IMG SRC=\"\\Pic.gif\"></A>"));
            SendMessage(hwndHTML, DTM_ADDTEXTW, FALSE, (LPARAM)TEXT("</BODY></HTML>"));
            SendMessage(hwndHTML, DTM_ENDOFSOURCE, 0, (LPARAM)NULL);*/

            break;

        }

    case WM_PAINT:

        {
            PAINTSTRUCT ps;
            HDC hdc;
            hdc = BeginPaint(hWnd, &ps);

            RECT rc = {0, 0, p->width, p->wt->getHeight()};

            SetBkMode(hdc, TRANSPARENT);
            SetTextColor(hdc, p->wt->getColor());
            p->wt->draw(hdc, rc,0);

            skin->drawElement(hdc, icons::ICON_CLOSE, p->width-2-skin->getElementWidth(), 0);


            EndPaint(hWnd, &ps);
            break;
        }

    case WM_SIZE: 
        { 
            //HDWP hdwp; 

            int height=GET_Y_LPARAM(lParam);
            int width=GET_X_LPARAM(lParam); p->width=width;

            int xHeight=tabHeight;/*p->wt->getHeight();*/
            // Calculate the display rectangle, assuming the 
            // tab control is the size of the client area. 
            SetRect(&(p->clientRect), 0, 0, width, height ); 

            if(IsWindow(p->htmlHWnd))
                SetWindowPos(p->htmlHWnd, 0, 0, xHeight, width, height-xHeight, SWP_NOZORDER );
            /*hdwp = BeginDeferWindowPos(1);

            DeferWindowPos(hdwp, p->listScrollHWND, HWND_TOP, width-SCROLLWIDTH, tabHeight, 
            SCROLLWIDTH, height-tabHeight, 
            SWP_NOZORDER 
            );
            EndDeferWindowPos(hdwp); */

            break; 
        } 

    case WM_NOTIFY:
        //if (wParam!=IDC_HTMLVIEW) break;
        {
            NM_HTMLVIEW* pnm = (NM_HTMLVIEW*)lParam;

            switch(pnm->hdr.code) 
            {
            case NM_INLINE_IMAGE:
                {
                    DWORD cookie=pnm->dwCookie;
                    HBITMAP bmp=p->getImage(pnm->szTarget, pnm->dwCookie);
                    p->setImage(bmp, cookie);
                    return TRUE;
                } // end case NM_INLINE_IMAGE:
            case NM_HOTSPOT:
                {
                    if (pnm->szTarget!=NULL)
                        p->onHotSpot((LPCSTR)pnm->szTarget, (LPCSTR)pnm->szData);
                    return TRUE;
                }
            } // end switch(pnm->hdr.code)
        } // End case IDC_HTMLVIEW:
        break;

    case WM_LBUTTONDOWN:
        SetFocus(hWnd);
        if ((GET_Y_LPARAM(lParam))>tabHeight) break;
        if (GET_X_LPARAM(lParam) > p->width-2-skin->getElementWidth()) {
            PostMessage(GetParent(hWnd), WM_COMMAND, TabsCtrl::CLOSETAB, 0);
        }
        break;

    case WM_HTML_UPDATE:
        {
            p->onWmUserUpdate();
            break;
        }
    case WM_DESTROY:
        //TODO: Destroy all child data associated eith this window
        //WARNING! do not place virtual member calls here - object is already destructed 
        return 0;

    default:
        return DefWindowProc(hWnd, message, wParam, lParam);
    }
    return 0;
}