[译]样式检查器
By robot-v1.0
本文链接 https://www.kyfws.com/applications/style-inspector-zh/
版权声明 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
- 10 分钟阅读 - 4963 个词 阅读量 0[译]样式检查器
原文地址:https://www.codeproject.com/Articles/9011/Style-Inspector
原文作者:Mircea Puiu
译文由本站 robot-v1.0 翻译
前言
Free tool (with source code) to inspect style.
免费工具(带有源代码)来检查样式.
介绍(Introduction)
**样式检查器(Style Inspector)**是一个简单的工具,专为团队中的工作人员开发当前的网页或基于HTML的文档而设计,这些团队中的才华横溢的人们每天都在利用他们的本机才能和知识来完成任务.通常,文档使用"行内"样式表,而一堆多页引用了大量样式表.突然,团队成员决定在他正在处理的页面内的各个项目上使用某些样式元素. “在一天结束时”,最接近元素的命令将成为影响文档外观的命令.为了使整个工作保持专业水平,团队中应该有一个(或多个)成员来检查结果并确保结果符合目标.(is a simple tool tailored to current needs of people working in teams to develop web pages or HTML based documentation, teams within which brilliant people use daily their native talent and knowledge to achieve the tasks. Frequently, documents make use of “in-line” style sheets while plenty of style sheets are referenced by a bunch of multiple pages. All of a sudden, a team member decides to use some style elements on individual items within the page he is working on. “At the end of the day”, the command closest to the element will be the one to affect the look of the document. To keep the whole work professional, there should be one (or more) members of the team dealing with checking the results and making sure the outcome fits to the target(s).)
最后但并非最不重要的一点是,有些人正在学习HTML,并愿意使用CSS来控制其页面.实现此目标的方法之一是查看其他人对此的处理方式.我敢打赌,那些人会喜欢这样的工具,它允许他们"浏览" HTML页面并"查看"超出场景的内容.(Last but not least, there are the people learning HTML and willing to use CSS to control their pages. One of the ways to do it is by looking at how others are dealing with that. I bet those people would appreciate a tool allowing them to “go” over an HTML page and “see” what is happening beyond the scene.)
使用样式检查器(Using the Style Inspector)
**样式检查器(Style Inspector)**主要包含两个窗口:(consists mainly of two windows: the)信息窗口(info window)和(and the)点击窗口(hit window),两者均设置了"最高"标志,因此它们始终位于屏幕上其他窗口的顶部.(, both created with the “top most” flag set, so that they stay always on top of the other windows on your screen.)
信息窗口跟踪打开的浏览器窗口.加载过程结束后,此窗口中会列出每个浏览器实例用于显示HTML内容的URL.(The info window keeps track of the opened browser windows. The URL used of each browser instance to display an HTML content is listed within this window as soon as the loading process is ended.)
如果仅存在一个浏览器窗口(也就是说,您在信息列表中仅获得一个项目),则会自动选择它所显示的文档.否则,您必须从信息列表中选择一个项目才能启用点击窗口的实际使用.(If only one browser window is present (meaning, you get only one item in the info list), the document displayed by it is automatically selected. Otherwise, you have to choose an item from the info list in order to enable the actual use of the hit window.)
您应该注意一件事:信息列表是指Internet浏览器的不同实例,而不是所显示的页面.因此,如果您使用浏览器进行浏览,则必须单击命中窗口的"更新"按钮才能检查最新文档.(You should pay attention to one important thing: the info list refers the different instances of your internet browser and not the displayed pages. So, should you navigate with your browser, you must click on the “Update” button of the hit window in order to inspect the latest document(s).)
从信息列表中选择一个项目后,命中窗口的"来源"按钮将变为活动状态,您可以开始检查已加载的文档.(Once you have selected an item from the info list, the “Origin” button of the hit window turns active and you may start inspecting the loaded document.)
抓住点击窗口中钻石的上半部分(实际上是窗口标题栏的一部分,允许您在屏幕上拖动窗口)并移动点击窗口,使其左上角指向浏览器"视图"区域的左上角.现在单击"来源"按钮.(Grab the upper half of the diamond within the hit window (that is actually part of the title bar of the window allowing you to drag the window over the screen) and move the hit window so that its top-left corner points to the top-left corner of the “view” area of your browser. Click now the “Origin” button.)
从现在开始,浏览器显示区域中的当前"命中"位置显示在命中窗口的底部.黄色指针(命中窗口的图标)将在移动命中窗口时指向HTML元素.悬浮元素的类型(HTML标记)及其位置,大小和样式将显示在信息窗口中.(From now on, the current “hit” position within the browser display area is shown at the bottom of the hit window. The yellow pointer (the icon of the hit window) will point to an HTML element while moving the hit window around. The type of the hovered element (the HTML tag) is displayed in the info window, along with its position, size and style.)
单个HTML元素可能会受嵌入式样式元素而不是跨接样式的影响.在这种情况下,与样式有关的信息在信息窗口内称为"本地".仅支持颜色和字体检查.(Individual HTML elements may be affected by in-line style elements, rather than spanned styles. In that case, the information related to the style is referred as “local” within the info window. Only inspection for color and font is supported.)
您可以在检查页面时标记匹配位置和HTML元素显示的位置之间的差异.完全可以!命中点是相对于浏览器"视图"区域的左上角,而HTML元素位置是相对于整个文档(可在浏览器中滚动的文档)的左上角计算的.只要不要忘记,只要浏览器在屏幕上的位置(而不是文档滚动)发生变化,就可以再次设置原点.(You may remark differences between the hit position and the position displayed for an HTML element while inspecting the page. That is entirely OK! The hit point is relative to the top-left corner of the “view” area of your browser, while an HTML element position is computed relative to the top-left corner of the entire document (document which can be scrolled within the browser). Just do not forget to set again the origin whenever the browser’s position (and not the document scroll) changes on the screen.)
注意(Note):(:)自定义浏览器的外观时,您还应该重复设置原点的过程(这也会影响屏幕上"视图"区域的位置)(you should also repeat the process of setting the origin when you customize the appearance of your browser (this also affects the position of the “view” area on the screen)).(.)
如何运作(How this works)
注意(Note):(:)与源代码相比,本文中的代码块得到了简化,并对一些变量名进行了调整,以更好地理解其解释.(The code blocks within the article are simplified and some of the variable names are adjusted for a better understanding of the explanation, when compared to the source code).(.)
一开始(At start,)**样式检查器(Style Inspector)**利用(makes use of a) SHDocVw::IShellWindowsPtr m_pInterface
创建ShellWindows可连接对象实例的指针.如果成功,它将通过使用以下方式"询问"有关其传出接口的对象(pointer to create an instance of a ShellWindows connectable object. In case of success, it “asks” the object about its outgoing interface by using) QueryInterface()
上(on) IID_IConnectionPointContainer
.如果对象支持传出接口,则应用程序将获得指向连接点容器的有效指针.阅读更多(. If the object supports the outgoing interface, the application gets a valid pointer to the connection point container. Read more on) 如何使用可连接对象(how to use connectable objects) 在Microsoft的帮助和支持网站上.使用该指针,它可以找到特定的事件接收器接口并检索指向连接点对象的指针.如果成功,它将在接收器和连接点对象之间建立连接,并检索cookie值以稍后终止连接.这一点,(on the help and support site of Microsoft. With that pointer, it finds the specific event sink interface and retrieves a pointer to the connection point object. In case of success, it establishes the connection between the sink and the connection point object, and retrieves a cookie value for terminating the connection later. At this point,)**样式检查器(Style Inspector)**使用其专门创建的功能,创建一个打开的浏览器窗口列表,并在信息窗口内填充相应文档URL的列表(creates a list of open browser windows and fills the list of corresponding document URLs within the info window, using its specially created function) UpdateListOfWindows()
.(.)
for (long i=0; i<m_pInterface->GetCount(); i++)
{
_variant_t va(i, VT_I4);
IDispatchPtr lpDisp = m_pInterface->Item(va);
SHDocVw::IWebBrowser2Ptr lpBrowser(lpDisp);
if ( lpBrowser != NULL )
{
// Get location name
.....
// Get location URL
.....
// Decide if dealing with a html/htm/shtml page
.....
// Add URL as new item to the list
.....
// Set the item data pointer to the value of lpBrowser;
.....
lpBrowser->AddRef();
}
}
如果生成的URL列表仅包含一个项目,则该项目会在列表中自动选择,一个布尔值(If the resulted list of URLs contains only one item, that item is automatically selected within the list, a boolean) m_bPageIsLoadedAndSelected
标志设置为(flag is set to) FALSE
和(, and)**样式检查器(Style Inspector)**开始使用100毫秒计时器轮询选定浏览器的繁忙状态(否则,用户必须进行选择).只要浏览器忙于查找和加载文档,命中窗口的"来源"按钮就保持禁用状态.(starts polling the busy status of the selected browser using a 100 ms timer (otherwise, the user must make a selection). As long as the browser is busy finding and loading the document, the “Origin” button of the hit window stays disabled.)
的(The) UpdateListOfWindows()
每次通过以下调度机制在浏览器窗口内注册或吊销浏览器窗口实例时,都会调用此函数:(function is called each time a browser window instance is registered or revoked, through the following dispatch mechanism, within the) IsRegistered()
和(and) IsRevoked()
功能分别:(functions respectively:)
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()
一旦浏览器不再繁忙,“来源"按钮将变为活动状态,并且用户可以按照本文前面所述执行设置原点的过程.在幕后(Once the browser is no longer busy, the “Origin” button turns active and the user can perform the process of setting the origin as described earlier in this article. Behind the scene,)**样式检查器(Style Inspector)**在设置样式之前,收集有关已加载文档样式的所有信息.(collects all the information on style(s) for the loaded document before setting the) m_bPageIsLoadedAndSelected
标记为true.假设(flag to true. Assuming) IWebBrowser2 *lpSelBrowser
指向当前所选浏览器实例的指针,并且(to be the pointer to the currently selected browser instance and) lpDispatch
指向的指针(a pointer to the) IDispatch
接口,(interface,)**样式检查器(Style Inspector)**获取指向已加载文档的指针:(obtains a pointer to the loaded document:)
lpSelBrowser->get_Document(&lpDispatch);
lpDispatch->QueryInterface(IID_IHTMLDocument2, (void**)&lpHtmlDocument);
并致电(and calls the) FindStyleClasses()
功能:(function:)
if ( lpHtmlDocument ) FindStyleClasses(lpHtmlDocument);
哪里(where) lpHtmlDocument
是(is of) IHTMLDocument2*
类型.在此功能内,它使用(type. Within this function, it uses the) lpHtmlDocument->get_styleSheets()
函数检索指向文档使用的元素集合的指针,然后遍历该集合:(function to retrieve a pointer to the collection of elements used by the document and then iterates through that collection:)
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();
// where m_listElements is the list of used syles (css)
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();
}
样式检查过程完全在内部完成(The style inspection process is entirely achieved within the) OnMove()
点击窗口的功能.通过点击获取点击窗口的屏幕坐标(function of the hit window. Having the screen coordinates of the hit window obtained through the) GetWindowRect()
函数和在设置原点的过程中获得的x和y轴上的偏移值,(function and the offset values on x and y axes obtained in the process of setting the origin,)**样式检查器(Style Inspector)**通过以下操作获取指向命中窗口左上角下方的HTML元素的指针:(obtains a pointer to the HTML element under the top-left corner of the hit window through:)
lpHtmlDocument->elementFromPoint(xPos, yPos, &lpElement)
哪里(where) lpElement
是(is of) IHTMLElement*
类型.大多数情况下,用户看到的HTML元素包含在另一个HTML元素中,并且该容纳可能会发生多次.这就是为什么由指向的元素的left,top,width和height值的原因(type. Most of the time, an HTML element which a user sees is contained within another, and the containment may occur multiple times. That is why the left, top, width and height values of element pointed to by) lpElement
可能不代表其绝对位置(从文档的左上角考虑).(may not represent its absolute position (considered from the top-left corner of the document).)
让(Let) lLeft
,(,) lTop
,(,) lWidth
和(and) lHeight
是由指向的元素的几何元素(be the geometrical elements of the element pointed to by) lpElement
.类似于以下代码的代码块有助于获取真实值:(. A block of code like the following one helps getting the real values:)
IHTMLElement *lpElement, *lpContainer;
long lValue, lTop, lLeft, lWidth, lHeight;
lpElement->get_offsetTop(&lValue); lTop = lValue;
lpElement->get_offsetLeft(&lValue); lLeft = lValue;
lpElement->get_offsetWidth(&lValue); lWidth = lValue;
lpElement->get_offsetHeight(&lValue); lHeight = lValue;
lpElement->get_offsetParent(&lpContainer);
while ( lpContainer )
{
lpContainer->get_offsetLeft(&lValue); lLeft += lValue;
lpContainer->get_offsetTop(&lValue); lTop += lValue;
lpContainer->get_offsetParent(&lpContainer);
}
呼叫(Calling the) lpElement->get_tagName()
和(and) lpElement->get_className()
功能,(functions,)**样式检查器(Style Inspector)**分别检索HTML元素的标签名称和与之关联的样式表中的特定样式规则(类).然后,(retrieves the tag name of the HTML element and the particular style rule (class) within the style sheet associated with it, respectively. Then,)**样式检查器(Style Inspector)**在设置样式之前,在构建的样式元素列表中为该类"查找”(“looks” for that class within the list of style elements it built before setting the) m_bPageIsLoadedAndSelected
标记为true,并在信息窗口中显示样式信息.之后,(flag to true, and displays the style information within the info window. After that,)**样式检查器(Style Inspector)**检查是否存在本地(或内联)样式元素,并显示是否存在:(checks for the presence of local (or in-line) style elements and displays them if any:)
IHTMLStyle *pStyle;
CString strInfo;
VARIANT vtValue;
lpElement->get_style(&pStyle);
if ( pStyle )
{
// Color
if ( pStyle->get_color(&vtValue) == S_OK )
{
_bstr_t bstrA(vtValue.bstrVal);
strInfo.Format(_T(", local color:%s"), (LPCTSTR)bstrA);
// Add this information to the already displayed information
// ..........
}
// Font
if ( pStyle->get_font(&bstrInfo) == S_OK )
{
_bstr_t bstrB(bstrInfo);
strInfo.Format(_T(", local font:%s"), (LPCTSTR)bstrB);
// Add this information to the already displayed information
// ..........
}
}
而不是结论(Instead of conclusions)
在被"(Before being “)**C(c)**是不是),工具必须是(ool” or not, a tool must be a)****哦这意味着,工具应为您提供执行所需功能的手段.(ool. That means, a tool should provide you the means to perform what you need to.)
玩笑(Joke):为什么C ++加号和VB没有?因为C ++还有其他功能:本地颜色是黑色:-))(: Why has C++ pluses and VB not? Because C++ has something more: the local color is black :-)))
历史(History)
- 发表:2004年12月10日.(Posted: Dec. 10, 2004.)
- 添加了"如何工作"部分:2004年12月12日.(Section “How this works” added: Dec. 12, 2004.)
许可
本文以及所有相关的源代码和文件均已获得The Code Project Open License (CPOL)的许可。
C++ HTML VC6 WinXP Windows Win2K Visual-Studio Dev 新闻 翻译