There is some recognition built into the DxDesigner output window, based on the format of messages that were created by ViewPCB.
If you format your messages like this:
vdraw: Error 1234: Schematic1 com $1I66: This component has no part number
Then the message will automatically be formatted and the user can click the hyperlink to visit the component.
The error number has to be there, but it doesn't matter what number you use - this was used to link to online help, but that won't work in your case.
After the error number and a colon, provide the top-level schematic name, followed by the keyword "com" (for component) and the hierarchical UID.
There are similar formats for nets and pins, I don't have the full description handy but I can probably dig that up.
For an example of how to use the RegisterErrorExpression method, see the Rotated Component Clearance script
This script works in Expedition, but the same technique can be used in DxDesigner. Basically you define a regular expression that is used to match the string, then provide two functions, one for display and one for when the hyperlink is clicked.
The first option using the string format "vdraw: Error 1234: Schematic1 com $1I66: This component has no part number" works for simple designs that do not use instance values (aka OATs).
However, because the "hyperlink" jumps directly to the sheet without drilling down the design hierarchy, you cannot then edit instance/OAT level attributes. I tried modifying the string to be:
"vdraw: Error 1234: toplevel1 com Block\$1I66: This component has no part number" but this does not work at all.
It look's like I'll have to investigate the RegisterErrorExpression method.
As regards the using RegisterErrorExpression I have a number of questions.
Firstly I should say I am not using a VB script but an Addin DLL written in C++ (and loaded on start up using DLLS.ini). The reasons for using C++ are in part historic and stem from older versions of DxDesigner being painfully slow when dealing with large hierachical designs.
i) RegisterErrorExpression has a parameter LPDISPATCH Client . In the example VB script this is set to a Global, ScriptEngine. Under a C++ DLL what value shall I use here and how can I obtain it.
ii) What are the prototypes for the Visit and Format functions?
I am guessing that Format function take a string pointer to the text on the output window display and a LPDISPATCH pointer to a IHtmlLink object
For the Visit function is its single argument a pointer to a IHtmlLink object as well?
iii) Is there any formal documentation for IHtmlLink (and IHtmlControl)? I can probably guess sort of what's going on from the VB example but I'd rather have proper documentation.
I'm getting closer with RegisterErrorExpression.
In answer to my own questions from the last post:
i) For the client argument I can get the value by calling Windows function GetIDispatch(FALSE) - I was already doing this when installing new buttons on the toolbar!
iii) Documentation (albeit scant) for the Output Window can be found with the Expedition PCB Automation reference guide: http://supportnet.mentor.com/docs/201105004/docs/htmldocs/mgchelp.htm#context=expedition_pcb_auto&id=1&tab=0
I couldn't find this before because we are using PADS not Expedition.
ii) My guess for the prototype for the Format function was correct (agreeing with the above documentation) and I have successfully used it to change the error class of the message so that it is displayed in red rather than black.
My guess for the prototype for the Visit function also agreed with the documentation and when I click of the error my Visit function does indeed get called. BUT the LPDISPATCH pointer passed to the function is NOT a pointer to a HtmlLink object. It is a LPDISPATCH pointer of some sort as I can successfully call its QueryInterface function but it does not support IHtmlLink, (E_NOINTERFACE, 0x80004002 is returned).
I know VB Script hides a lot of the pain of using automation interfaces but I really cannot see how the Rotated Components example mentioned earlier can possibly work. Maybe there has been a change in the automation interface since that script was written, or the version of OutputWindow70.dll (220.127.116.11) that ships with PADS9.3 has bugs. Either way I'm stuck again.
Good detective work, I'm sorry I wasn't able to supply this information sooner.
The visit function takes a single dispatch pointer, that supports the IHTMLAnchorElement interface (defined in mshtml.dll)
From that interface, you can get the href property, which you set in the format function, and parse it up as needed (you can see that in the rotated components example).
The Visit function now works and I can get to the href parameter of the IHtmlAnchorElement.
However, in the Format function the href string is initially set to the full text written to the output display window. If I leave this alone then that same text appears in the Visit functions href string.
However if in the Format function I change the href value so that it just contains the component path e.g "CONTROLLER\$1I3425" then the Visit function passes a string of the format:
In short extracting the component path in the Format function is a waste of time as I'm going to have to do it again in the Visit function.
Ian, have you got an example you can share that works in DxDesigner? I've been unable to figure out how to use RegisterErrorExpression(). Any help would be greatly appreciated.
I've attached some example C++ code to exercise hyperlinks.
The viewdraw automation interfaces have been wrapped in classes derrived from COleDispatchDriver, but you should be able to see what's going on.
You will need to use regular expressions to set up and handle the hyperlinks - I used the boost libraries to help do this.
You will also notice a a reference to a CYieldDlg class. This is a dummy, modal dialog box that runs for 20ms then automatically exits. It was the only way I found of "suspending" my script and allowing DxDesigner to update the output window. I'm sure there must be a more elegant way of doing this.
Hopefully you'll find sufficient comments in the code to explain what its trying to do.
dx_hyperlink.txt.zip 2.8 KB
I know this is an old discussion but I really could use the hyperlink format for finding a net in the DxDesigner Output Window.
The format is:
Facility: Severity ErrNum: TopSchematicName ObjType ObjPath: rest of error message
Facility: Can be whatever you want, it is hidden from the user and only useful for navigating to help topic
Severity: Can be one of Status|Note|Warning|Error|Fatal|Internal Error
ErrNum: An error number (integer), again this is only useful for navigating to help topic
TopSchematicName: name (and sheet number if desired) of the top level schematic
ObjType: com or net or pin
ObjPath: path to object being navigated to (must use UID paths)
vdraw: Status 14: Schematic1 com $3I1891\$1I14: this component has something wrong
vdraw: Status 14: Schematic1 pin $3I1891\$1I14.P1: this pin has some problem too
vdraw: Status 14: Schematic1 net ABCD: this net should be pulled up
You can put these messages into the output window using the Application.AppendOutput method, and they will be recognized and turned into hyperlinks.
I had some problems with hierarchical nets, you may need to experiment a little. Basically the ObjPath string is passed to the SelectPath method.
This is excellent information.
I have one question. I'm trying to get to a specific net in the design. I've cobbled something together where the hyperlinks work but when I click on the link it goes to the first net and not the net I want it to go to. Is this an issue with not having the sheet specified in the hyperlink?
I'm not sure, you could try adding the sheet name (Schematic1.3, for example).
Adding the Sheet name doesn't work. I don't even get a link then.
I've also been trying to put text and links in the Output Window as describe above using the documentation in the PCB Automation Reference.
I'm getting an runtime error though when I try to run my script: Type mismatch: 'RegisterErrorExpression'
The code looks like this:
oOutputTab.RegisterErrorExpression sRCCPattern, ScriptEngine, "VisitRCC", "FormatRCC"
When you call RegisterErrorExpression, you need to define the Visit and Format functions, as shown in the Rotated Component Clearance script example.
Also, you need to set Scripting.DontExit = True to make sure the script is still running when the text is added to the output window and when the user clicks the link.
If you are calling RegisterErrorExpression from a script form (.efm), then use ScriptThis instead of ScriptEngine, and make sure the form is still running when the user clicks the link.