Click here to Skip to main content
15,892,298 members
Articles / Web Development / HTML

Style Inspector

Rate me:
Please Sign up or sign in to vote.
4.86/5 (41 votes)
12 Dec 2004CPOL7 min read 112.7K   2.4K   59  
Free tool (with source code) to inspect style.
// Author:		Dr. Puiu
// Creation:	2004

// StyleInspectorDlg.cpp : implementation file
//

#include "stdafx.h"
#include "StyleInspector.h"
#include "StyleInspectorDlg.h"

#include <mshtml.h>
#include <atlbase.h>

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

/////////////////////////////////////////////////////////////////////////////
static SHDocVw::IShellWindowsPtr m_pInterface; 

// CAboutDlg dialog used for App About

class CAboutDlg : public CDialog
{
public:
	COLORREF m_colorBkGnd;
	CBrush m_brushBkGnd;
	CAboutDlg();

// Dialog Data
	//{{AFX_DATA(CAboutDlg)
	enum { IDD = IDD_ABOUTBOX };
	//}}AFX_DATA

	// ClassWizard generated virtual function overrides
	//{{AFX_VIRTUAL(CAboutDlg)
	protected:
	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support
	//}}AFX_VIRTUAL

// Implementation
protected:
	//{{AFX_MSG(CAboutDlg)
	afx_msg HBRUSH OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor);
	//}}AFX_MSG
	DECLARE_MESSAGE_MAP()
};

CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD)
{
	//{{AFX_DATA_INIT(CAboutDlg)
	//}}AFX_DATA_INIT
	m_colorBkGnd = 0xB19165; // BB-GG-RR
	m_brushBkGnd.CreateSolidBrush(m_colorBkGnd);
}

void CAboutDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CAboutDlg)
	//}}AFX_DATA_MAP
}

HBRUSH CAboutDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	if ( nCtlColor != CTLCOLOR_EDIT)
	{
		hbr = (HBRUSH)m_brushBkGnd.GetSafeHandle();
		pDC->SetBkColor(m_colorBkGnd);
	}
	
	// TODO: Return a different brush if the default is not desired
	return hbr;
}

BEGIN_MESSAGE_MAP(CAboutDlg, CDialog)
	//{{AFX_MSG_MAP(CAboutDlg)
	ON_WM_CTLCOLOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStyleInspectorDlg dialog

CStyleInspectorDlg::CStyleInspectorDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CStyleInspectorDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CStyleInspectorDlg)
	//}}AFX_DATA_INIT
	// Note that LoadIcon does not require a subsequent DestroyIcon in Win32
	m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
	m_dlgInfo.Create(IDD_DIALOG_INFO, NULL);
	m_lOriginLeft = 0;
	m_lOriginTop = 0;
	m_colorBkGnd = 0xB19165; // BB-GG-RR
	m_brushBkGnd.CreateSolidBrush(m_colorBkGnd);
	// ============================================
	EnableConnections();
	EnableAutomation();
	m_bPageIsLoadedAndSelected = false;
	m_bOriginIsSet = false;
}

void CStyleInspectorDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CStyleInspectorDlg)
	//}}AFX_DATA_MAP
}

BEGIN_MESSAGE_MAP(CStyleInspectorDlg, CDialog)
	//{{AFX_MSG_MAP(CStyleInspectorDlg)
	ON_WM_SYSCOMMAND()
	ON_WM_PAINT()
	ON_WM_QUERYDRAGICON()
	ON_WM_TIMER()
	ON_BN_CLICKED(IDC_BUTTON_REFRESH, OnButtonRefresh)
	ON_WM_MOVE()
	ON_BN_CLICKED(IDC_BUTTON_SET_DOC_ORIGIN, OnButtonSetDocOrigin)
	ON_WM_CTLCOLOR()
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

BEGIN_DISPATCH_MAP(CStyleInspectorDlg, CCmdTarget)
	DISP_FUNCTION_ID(CStyleInspectorDlg, "WindowRegistered",0x000000C8,IsRegistered,VT_EMPTY,VTS_I4)
	DISP_FUNCTION_ID(CStyleInspectorDlg, "WindowRevoked",0x000000C9,IsRevoked,VT_EMPTY,VTS_I4)
END_DISPATCH_MAP()

/////////////////////////////////////////////////////////////////////////////
// CStyleInspectorDlg message handlers

BOOL CStyleInspectorDlg::OnInitDialog()
{
	CDialog::OnInitDialog();

	// Add "About..." menu item to system menu.

	// IDM_ABOUTBOX must be in the system command range.
	ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX);
	ASSERT(IDM_ABOUTBOX < 0xF000);

	CMenu* pSysMenu = GetSystemMenu(FALSE);
	if (pSysMenu != NULL)
	{
		CString strAboutMenu;
		strAboutMenu.LoadString(IDS_ABOUTBOX);
		if (!strAboutMenu.IsEmpty())
		{
			pSysMenu->AppendMenu(MF_SEPARATOR);
			pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu);
		}
	}

	// Set the icon for this dialog.  The framework does this automatically
	//  when the application's main window is not a dialog
	SetIcon(m_hIcon, TRUE);			// Set big icon
	SetIcon(m_hIcon, FALSE);		// Set small icon

	// Show the info dialog
	CRect screenRect, rcInfo;
	SystemParametersInfo(SPI_GETWORKAREA, 0, &screenRect, 0);
	m_dlgInfo.GetWindowRect(&rcInfo);
	m_dlgInfo.SetWindowPos(CWnd::FromHandle(HWND_TOPMOST), screenRect.right - rcInfo.Width(), 
						   0, 0, 0, 
						   SWP_SHOWWINDOW | SWP_NOSIZE);

	// Set window's region
	CRect wndRect, wndButton1, wndButton2, wndIE;
	CRgn rgnAux;
	CPoint pt[4];
	CButton *pB1 = (CButton *)GetDlgItem(IDC_BUTTON_SET_DOC_ORIGIN);
	CButton *pB2 = (CButton *)GetDlgItem(IDC_BUTTON_REFRESH);
	CStatic *pIE = (CStatic *)GetDlgItem(IDC_STATIC_IE);
	// |------------------------------------------------------------------------------------------------
		// 1) title bar
		GetWindowRect(&wndRect);
		m_rgnWnd.CreateRectRgn(wndRect.left, wndRect.top, wndRect.right, wndRect.bottom);
		rgnAux.CreateRectRgn(wndRect.left + 21, wndRect.top + 4, 
							 wndRect.left + wndRect.right - 24, wndRect.top + 19);
		m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_DIFF);
		rgnAux.DeleteObject();
		// 2) client area
		rgnAux.CreateRectRgn(wndRect.left + 3, wndRect.top + 22, wndRect.right - 3, wndRect.bottom - 24);
		m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_DIFF);
		rgnAux.DeleteObject();
		// 3) rhomb 
		pt[0].x = wndRect.Width() / 3;		pt[0].y = wndRect.top + 19;
		pt[2].x = pt[0].x + 20;				pt[2].y = pt[0].y;
		pt[3].x = (pt[0].x + pt[2].x) / 2;	pt[3].y = wndRect.top + 9;
		pt[1].x = pt[3].x;					pt[1].y = wndRect.top + 29;
		rgnAux.CreatePolygonRgn(pt, 4, ALTERNATE);
		m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
		rgnAux.DeleteObject();
		// 4) "set origin" button
		if ( pB1 )
		{
			pB1->GetWindowRect(&wndButton1);
			rgnAux.CreateRectRgn(wndRect.left + wndButton1.left, wndRect.top + wndButton1.top, 
								 wndRect.left + wndButton1.right, wndRect.top + wndButton1.bottom);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
		// 5) "refresh" button
		if ( pB2 )
		{
			pB2->GetWindowRect(&wndButton2);
			rgnAux.CreateRectRgn(wndRect.left + wndButton2.left, 
								 wndRect.top + wndButton2.top, 
								 wndRect.left + wndButton2.right, 
								 wndRect.top + wndButton2.bottom);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
		// 6.1) routing
		if ( pB1 )
		{
			rgnAux.CreateRectRgn(wndRect.left + 10, 
								 wndRect.top + 19, 
								 wndRect.left + 13, 
								 wndRect.top + (wndButton1.top + wndButton1.bottom) / 2 + 2);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
		// 6.2) routing
		if ( pB1 )
		{
			rgnAux.CreateRectRgn(wndRect.left + 13, 
								 wndRect.top + (wndButton1.top + wndButton1.bottom) / 2 - 1, 
								 wndRect.left + wndButton1.left, 
								 wndRect.top + (wndButton1.top + wndButton1.bottom) / 2 + 2);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
		// 6.3) routing
		if ( pB2 )
		{
			rgnAux.CreateRectRgn(wndRect.left + (wndButton2.left + wndButton2.right) / 2 - 1, 
								 wndRect.top + 19, 
								 wndRect.left + (wndButton2.left + wndButton2.right) / 2 + 2, 
								 wndRect.top + wndButton2.top);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
		// 6.4) routing
		if ( pB1 && pB2 )
		{
			rgnAux.CreateRectRgn(wndRect.left + (wndButton1.left + wndButton1.right) / 2 - 2, 
								 wndRect.top + (wndButton2.top + wndButton2.bottom) / 2 - 1, 
								 wndRect.right, 
								 wndRect.top + (wndButton2.top + wndButton2.bottom) / 2 + 2);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
		// 6.5) routing
		if ( pB1 && pB2 )
		{
			rgnAux.CreateRectRgn(wndRect.left + (wndButton1.left + wndButton1.right) / 2 - 2, 
								 wndRect.top + (wndButton2.top + wndButton2.bottom) / 2 - 1, 
								 wndRect.left + (wndButton1.left + wndButton1.right) / 2 + 1, 
								 wndRect.bottom);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
		// 7) IE symbol
		if ( pIE )
		{
			pIE->GetWindowRect(&wndIE);
			rgnAux.CreateRectRgn(wndRect.left + wndIE.left - 2, 
								 wndRect.top + wndIE.top - 2, 
								 wndRect.left + wndIE.right + 2, 
								 wndRect.top + wndIE.bottom + 2);
			m_rgnWnd.CombineRgn(&m_rgnWnd, &rgnAux, RGN_OR);
			rgnAux.DeleteObject();
		}
	// |------------------------------------------------------------------------------------------------
	// Set the finally resulted region for this window
	SetWindowRgn((HRGN)m_rgnWnd.GetSafeHandle(), TRUE);

	// TODO: Add extra initialization here
	SetWindowPos(CWnd::FromHandle(HWND_TOPMOST), 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE);
	GetConnectedToShellWindows();
	UpdateListOfWindows();

	return TRUE;  // return TRUE  unless you set the focus to a control
}

void CStyleInspectorDlg::OnSysCommand(UINT nID, LPARAM lParam)
{
	if ((nID & 0xFFF0) == IDM_ABOUTBOX)
	{
		CAboutDlg dlgAbout;
		dlgAbout.DoModal();
	}
	else
	{
		CDialog::OnSysCommand(nID, lParam);
	}
}

// If you add a minimize button to your dialog, you will need the code below
//  to draw the icon.  For MFC applications using the document/view model,
//  this is automatically done for you by the framework.

void CStyleInspectorDlg::OnPaint() 
{
	if (IsIconic())
	{
		CPaintDC dc(this); // device context for painting

		SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0);

		// Center icon in client rectangle
		int cxIcon = GetSystemMetrics(SM_CXICON);
		int cyIcon = GetSystemMetrics(SM_CYICON);
		CRect rect;
		GetClientRect(&rect);
		int x = (rect.Width() - cxIcon + 1) / 2;
		int y = (rect.Height() - cyIcon + 1) / 2;

		// Draw the icon
		dc.DrawIcon(x, y, m_hIcon);
	}
	else
	{
		CDialog::OnPaint();
	}
}

// The system calls this to obtain the cursor to display while the user drags
//  the minimized window.
HCURSOR CStyleInspectorDlg::OnQueryDragIcon()
{
	return (HCURSOR) m_hIcon;
}

void CStyleInspectorDlg::IsRegistered(long lCookie) 
{
	UpdateListOfWindows();
	SetTimer(1111, 1000, NULL); // Give the document a chance to load :-))
}

void CStyleInspectorDlg::IsRevoked(long lCookie) 
{
	UpdateListOfWindows();
}

void CStyleInspectorDlg::GetConnectedToShellWindows()
{
	LPCONNECTIONPOINTCONTAINER pContainer;
	LPCONNECTIONPOINT pXConnection = NULL;
	DWORD dwCookie = 0;

	CoInitialize(NULL);
	if(m_pInterface == 0) 
	{
		if(m_pInterface.CreateInstance(__uuidof(SHDocVw::ShellWindows)) == S_OK) 
		{
			if ((m_pInterface != NULL) &&
				SUCCEEDED(m_pInterface->QueryInterface(IID_IConnectionPointContainer,
					(LPVOID*)&pContainer)))
			{

				if (SUCCEEDED(pContainer->FindConnectionPoint(__uuidof(SHDocVw::DShellWindowsEvents), &pXConnection)))
				{
					ASSERT(pXConnection != NULL);
					pXConnection->Advise( GetIDispatch(FALSE), &dwCookie);
					pXConnection->Release();
				}
				pContainer->Release();
			}
		}
		else 
		{
			AfxMessageBox("Shell interface not avilable!\nApplication will abort.",
						  MB_OK | MB_ICONSTOP);
			exit(0);
		}
	}
}

void CStyleInspectorDlg::OnTimer(UINT nIDEvent) 
{
	// TODO: Add your message handler code here and/or call default
	CButton *pB = (CButton *)GetDlgItem(IDC_BUTTON_SET_DOC_ORIGIN);
	int nCurSel;
	IWebBrowser2 *lpSelBrowser;
	VARIANT_BOOL shBusy;
	IDispatchPtr lpDispatch;
	IHTMLDocument2 *lpHtmlDocument;

	switch ( nIDEvent )
	{
		case 1111: /* the chance for document to load */
			KillTimer(1111);
			UpdateListOfWindows();
			break;
		case 2222: /* poll the busy status of the browser  */
			if ( m_bPageIsLoadedAndSelected ) 
			{ 
				KillTimer(2222); 
				if ( pB ) pB->EnableWindow(TRUE);
				// Get the list of sheet styles
				nCurSel = m_dlgInfo.m_lbWindows.GetCurSel();
				if ( nCurSel != LB_ERR )
				{
					lpSelBrowser = (IWebBrowser2 *)m_dlgInfo.m_lbWindows.GetItemDataPtr(nCurSel);
					if ( lpSelBrowser )
					{
						lpSelBrowser->get_Document(&lpDispatch);
						lpDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&lpHtmlDocument);
						if ( lpHtmlDocument ) FindStyleClasses(lpHtmlDocument);
					}
				}
				break;
			}
			else
			{
				if ( pB ) pB->EnableWindow(FALSE);
				m_bOriginIsSet = false;
			}
			nCurSel = m_dlgInfo.m_lbWindows.GetCurSel();
			if ( nCurSel == LB_ERR ) 
			{ 
				KillTimer(2222); 
				if ( pB ) pB->EnableWindow(FALSE);
				m_bOriginIsSet = false;
				break; 
			}
			lpSelBrowser = (IWebBrowser2 *)m_dlgInfo.m_lbWindows.GetItemDataPtr(nCurSel);
			if ( lpSelBrowser != NULL )
			{
				lpSelBrowser->get_Busy(&shBusy);
				if ( shBusy == 0 ) m_bPageIsLoadedAndSelected = true;
				else m_bPageIsLoadedAndSelected = false;
			}
			break;
	}
	
	CDialog::OnTimer(nIDEvent);
}

void CStyleInspectorDlg::OnButtonRefresh() 
{
	// TODO: Add your control notification handler code here
	UpdateListOfWindows();
}

int CStyleInspectorDlg::FindClassNameInString(CString &strContainer, CString &strToLookFor)
{
	// It looks for the strToLook substring within the strContainer string and
	// returns a position different of -1 if strToLookFor is not followed within the
	// strContainer by a character in range: [48, 57] U [65, 90] U [97, 122]
	int nPos, nLSub;
	TCHAR chNext;

	nPos = strContainer.Find(strToLookFor.GetBuffer(0));
	if ( nPos != -1)
	{
		nLSub = strToLookFor.GetLength();
		if ( (nPos + nLSub ) < strContainer.GetLength() )
		{
			chNext = strContainer.GetAt(nPos + nLSub);
			if ( ((47 < chNext) && (chNext < 58)) ||
				 ((64 < chNext) && (chNext < 91)) ||
				 ((96 < chNext) && (chNext < 123)) ) nPos = -1;
		}
	}
	return nPos;
}

void CStyleInspectorDlg::OnMove(int x, int y) 
{
	CDialog::OnMove(x, y);
	CMyHTMLElement HE;
	long xPos, yPos;
	bool bElementFound = false;
	CStatic *pShortInfo = (CStatic *)GetDlgItem(IDC_STATIC_SHORT_INFO);
	char chValue[1024];
	CRect rc;
	int nXOffset = m_lOriginLeft;
	int nYOffset = m_lOriginTop;
	IWebBrowser2 *lpBrowser;
	IDispatchPtr lpDispatch;
	IHTMLDocument2 *lpHtmlDocument;
	IHTMLElement *lpElement, *lpContainer;
	long lValue;
	IHTMLStyle *pStyle;
	CString strConverted, strAux, strAttrib;
	BSTR bstrInfo;
	POSITION pos;
	CString strStyleClass, strClass1, strClass2, strThisStyle;
	int nTokenPos, nPosEnd;
	char chByte[2];
	unsigned char ucK;
	VARIANT vtValue;
	
	// TODO: Add your message handler code here
	chByte[1] = 0;
	GetWindowRect(&rc);
	xPos = rc.left-nXOffset;
	yPos = rc.top-nYOffset;
	sprintf(chValue, "x = %d, y = %d", 	xPos, yPos);
	if ( pShortInfo ) 
	{
		if ( m_bOriginIsSet ) 
		{
			pShortInfo->SetWindowText(chValue);
			int nCurSel = m_dlgInfo.m_lbWindows.GetCurSel();
			if ( nCurSel != CB_ERR )
			{
				lpBrowser = (IWebBrowser2 *)m_dlgInfo.m_lbWindows.GetItemDataPtr(nCurSel);
				lpBrowser->get_Document(&lpDispatch);
				lpDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&lpHtmlDocument);
				if ( lpHtmlDocument ) 
				{
					if (lpHtmlDocument->elementFromPoint(xPos, yPos, &lpElement) == S_OK )
					{
						lpElement->get_offsetTop(&lValue); HE.lTop = lValue;
						lpElement->get_offsetLeft(&lValue); HE.lLeft = lValue;
						lpElement->get_offsetWidth(&lValue); HE.lWidth = lValue;
						lpElement->get_offsetHeight(&lValue); HE.lHeight = lValue;
						lpElement->get_offsetParent(&lpContainer);
						while ( lpContainer )
						{
							lpContainer->get_offsetLeft(&lValue); HE.lLeft += lValue;
							lpContainer->get_offsetTop(&lValue);  HE.lTop += lValue;
							lpContainer->get_offsetParent(&lpContainer);
						}
						lpHtmlDocument->Release();
						sprintf(chValue, "position x = %d, y = %d, width = %d, height = %d", 
								HE.lLeft, HE.lTop, HE.lWidth, HE.lHeight);
						m_dlgInfo.m_strLink = chValue;
						//-------------------------------
						strConverted = "";
						if ( lpElement->get_tagName(&bstrInfo) == S_OK )
						{
							_bstr_t bstr1(bstrInfo);
							strConverted.Format(_T("<%s>"), (LPCTSTR)bstr1);
						}
						if ( !m_listElements.IsEmpty() )
						{
							if ( lpElement->get_className(&bstrInfo) == S_OK )
							{
								_bstr_t bstr2(bstrInfo);
								strAux.Format(_T("%s"), (LPCTSTR)bstr2);
								strClass1.Format(_T(".%s"), (LPCTSTR)bstr2);
								strClass2.Format(_T("#%s"), (LPCTSTR)bstr2);
								if ( strAux != "" )
								{
									// Look for this style class in the list of elements (of style)
									pos = m_listElements.GetHeadPosition();
									while (pos)
									{
										strStyleClass = m_listElements.GetNext(pos);
										nTokenPos = FindClassNameInString(strStyleClass, strClass1);
										if ( nTokenPos == -1 ) 
											nTokenPos = FindClassNameInString(strStyleClass, strClass2);
										if ( nTokenPos != -1 )
										{
											nPosEnd = strStyleClass.Find("}", nTokenPos);
											if ( nPosEnd == -1 ) nPosEnd = strStyleClass.GetLength() - 1;
											// Get the appropriate substring
											strThisStyle = strStyleClass.Mid(nTokenPos, nPosEnd - nTokenPos + 1);
											// Take out the non-printable characters
											for (ucK=1; ucK<32; ucK++) 
											{
												chByte[0] = ucK;	
												strThisStyle.Replace(chByte, "");
											}
											strConverted += ": Style class ";
											strConverted += strThisStyle;
											break;
										}
									}
								}
							}
						}
						// Get some of the locally used style
						lpElement->get_style(&pStyle);
						if ( pStyle )
						{
							// Color
							pStyle->get_color(&vtValue);
							_bstr_t bstr3(vtValue.bstrVal);
							strAux.Format(_T(", local color:%s"), (LPCTSTR)bstr3);
							if (strAux.Find("null") == -1) strConverted += strAux;
							// Font
							if ( pStyle->get_font(&bstrInfo) == S_OK )
							{
								_bstr_t bstr4(bstrInfo);
								strAux.Format(_T(", local font:%s"), (LPCTSTR)bstr4);
								if (strAux != ", local font:") strConverted += strAux;
							}
						}
						//-------------------------------
						// Update the information
						m_dlgInfo.m_strStyleClass = strConverted;
						m_dlgInfo.UpdateData(FALSE);
					}
				}
			}
		}
		else pShortInfo->SetWindowText("Set the origin !");
	}
}

void CStyleInspectorDlg::FindStyleClasses(IHTMLDocument2 *lpHtmlDocument)
{
	IHTMLStyleSheetsCollection *pElemCollection;
    IUnknown *lpUnknown;
    IEnumVARIANT *lpNewEnum;
    IHTMLStyleSheet *lpElement;
    VARIANT varElement;
	BSTR bstrStyleSheet;
	CString strStyle;

	if ( lpHtmlDocument->get_styleSheets(&pElemCollection) != S_OK ) return;
	if ( pElemCollection == NULL ) return;

	if ( !m_listElements.IsEmpty() ) m_listElements.RemoveAll();
    if (SUCCEEDED(pElemCollection->get__newEnum(&lpUnknown)) && lpUnknown != NULL)
    {
        lpUnknown->QueryInterface(IID_IEnumVARIANT,(void**)&lpNewEnum);
        if (lpNewEnum == NULL) return;

        while (lpNewEnum->Next(1, &varElement, NULL) == S_OK)
        {
            if (varElement.vt != VT_DISPATCH) { VariantClear(&varElement); break; }
            varElement.pdispVal->QueryInterface(IID_IHTMLStyleSheet,(void**)&lpElement);
            if (lpElement)
            {
				lpElement->get_cssText(&bstrStyleSheet);
				_bstr_t bstr1(bstrStyleSheet);
				strStyle.Format(_T("%s"), (LPCTSTR)bstr1);
				m_listElements.AddTail(strStyle);
            }
            VariantClear(&varElement);
        }
		if ( lpNewEnum ) lpNewEnum->Release();
    }
}

void CStyleInspectorDlg::UpdateListOfWindows()
{
	CButton *pB = (CButton *)GetDlgItem(IDC_BUTTON_SET_DOC_ORIGIN);
	IDispatchPtr lpDisp;
	int nIndex;
	TCHAR szStr[255];
	_bstr_t bStr;
	CString strName, strURL;
	long nCount = m_pInterface->GetCount();
	bool bIsPage;
	int nItemCount;

	m_dlgInfo.m_lbWindows.SetRedraw(FALSE);
	m_dlgInfo.m_lbWindows.ResetContent();
	for (long i = 0; i < nCount; i++)
	{
		_variant_t va(i, VT_I4);
		lpDisp = m_pInterface->Item(va);
		SHDocVw::IWebBrowser2Ptr lpBrowser(lpDisp);
		if (lpBrowser != NULL)
		{
			bStr = lpBrowser->GetLocationName();
			_stprintf(szStr, _T("%s"), (LPCTSTR)bStr);
			strName = szStr;
			bStr = lpBrowser->GetLocationURL();
			_stprintf(szStr, _T("%s"), (LPCTSTR)bStr);
			strURL = szStr;
			if (strName != "StyleInspector")
			{
				while (strURL.Find("%20") != -1) {strURL.Replace("%20", " ");}
				bIsPage = false;
				if ( strURL.Find(".html") != -1 ) bIsPage = true;
				else if ( strURL.Find(".htm") != -1 ) bIsPage = true;
				else if ( strURL.Find(".shtml") != -1 ) bIsPage = true;
				else if ( strURL.ReverseFind('.') != -1 )
				{
					if ( strURL.Find("http://") != -1 ) bIsPage = true;
					else if ( strURL.Find("www.") != -1 ) bIsPage = true;
				}
				if ( bIsPage )
				{
					nIndex = m_dlgInfo.m_lbWindows.AddString(strURL.GetBuffer(0));
					m_dlgInfo.m_lbWindows.SetItemDataPtr(nIndex,lpBrowser);
					lpBrowser->AddRef();
				}
			}
		}
	}
	m_dlgInfo.m_lbWindows.SetRedraw(TRUE);
	PostMessage(WM_MOVE);
	m_bPageIsLoadedAndSelected = false;
	m_bOriginIsSet = false;
	if ( pB ) pB->EnableWindow(FALSE);
	nItemCount = m_dlgInfo.m_lbWindows.GetCount();
	if ( nItemCount != LB_ERR )
	{
		if (nItemCount == 1 )
		{
			// It's only one item, so select that item
			m_dlgInfo.m_lbWindows.SetCurSel(0);
			m_dlgInfo.ActOnSelchangeListWindows();
		}
	}
}

void CStyleInspectorDlg::OnButtonSetDocOrigin() 
{
	// TODO: Add your control notification handler code here
	CRect rc;

	GetWindowRect(&rc);
	m_lOriginLeft = rc.left;
	m_lOriginTop = rc.top;
	m_bOriginIsSet = true;
	PostMessage(WM_MOVE);
}

void CStyleInspectorDlg::WinHelp(DWORD dwData, UINT nCmd) 
{
}

HBRUSH CStyleInspectorDlg::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor) 
{
	HBRUSH hbr = CDialog::OnCtlColor(pDC, pWnd, nCtlColor);
	
	// TODO: Change any attributes of the DC here
	if ( nCtlColor != CTLCOLOR_EDIT)
	{
		hbr = (HBRUSH)m_brushBkGnd.GetSafeHandle();
		pDC->SetBkColor(m_colorBkGnd);
	}
	
	// TODO: Return a different brush if the default is not desired
	return hbr;
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Europe Europe
More than 30 years of software development experience.
(also playing the SCRUM Master role depending on the project)

Comments and Discussions