This post is a continuation of a previous one on how you might go about hiding pages within the Visio UI. While the previous post offered a possible ShapeSheet only approach, today I'm going to look at the problem from a code perspective...
An example document containing all of the code can be downloaded at the bottom of this post.
Issues with page hiding
I'm going to start with a quick recap on some of the issues with manipulating a page's UIVisibility cell:
- Visio appears to have two methods for cycling through pages: by name (a string) and by index
- Some commands utilise the name method (eg Edit / Go To), while others, the index (eg File / Print)
- Hiding pages via the UIVisibility cell still leaves access to those pages using Ctrl + Page Up / Down and the Drawing Explorer*
*Note - I mentioned in the previous post that UIVisibility effects the Drawing Explorer. However, through further testing I've discovered that this is only temporary. Closing and reopening the Drawing Explorer actually reveals the hidden pages, which I guess is not intended functionality.
We can deal with some of these issues with the following code solution. However, I should point out that this isn't a method for securing confidential information from users but, rather, for making your documents clearer by hiding information that's not directly required by the user.
The code solution
The code solution consists of three main activities:
- Add a form to manage pages visibility
- Change UI accelerator keys function (Ctrl + Page Up / Down)
- Add code to only allow navigation to visible pages
Rather than using a document user cell to store an array of 'visibility values' as we did in the previous post, this solution uses a form to directly interact with the UIVisibility cell.
The above form has an Initialize event (see below) within which we can cycle through the document's pages and add the details of each one to a listbox. The user can then select the visible pages and the subsequent Click event on the OK button cycles back through the listbox entries and sets the respective page's UIVisibility cell.
Adapting the UI
Now, to change the default behaviour of the Ctrl + Page Up / Down accelerator keys and to add a Drawing Explorer context menu item, I've chosen to use Visio's UIObject. If you're not familiar with this you can learn more about the UIObject in the SDK but, in essence Visio has two systems for changing the user interface: the CommandBars method and the UIObject.
While the preferred method these days is the CommandBars model, (in line with the rest of Office, but not the newer Ribbon system), the UIObject still has at least one ace up its sleeve and that is document level UI manipulation.
Under the ThisDocument module I've used two events (DocumentOpened and BeforeDocumentClosed) to add and remove the accelerator keys and context menu to the document UI only (ie the functionality will only be available to that document). There's no reason why you couldn't apply it to the Application Custom UI, but you'd then need to think about where you intend to store your code.
As the purpose of hiding pages is likely to be so that general users don't get to them I've chosen to hide the method of accessing the functionality - or, at least, not have it front and centre, so to speak. Hence, the only way of running the code is by right-clicking on the Document node in the Drawing Explorer.
Navigating only visible pages
Aside from the new context menu item, the main change is that I've reassigned the Ctrl + Page Up / Down shortcuts to run a procedure called SetNextVisiblePage(). This cycles through the pages until it finds a visible one and makes this the ActivePage.
Weighing up the options - Code or ShapeSheet
Usually, if you can achieve something just using the ShapeSheet then this is no bad thing, and if you or your users are operating in an environment where VBA isn't enabled then the ShapeSheet solution in the previous post may help.
However, as John Marshall pointed out in the comments, the ShapeSheet method doesn't really allow for users deleting pages (as this interferes with the sequence in the document's user cell array). Plus, of course, it can't deal with the default shortcut keys revealing the hidden pages. So code certainly appears to win the day here.
One final point regarding deleting pages: you might be wondering how this is being handled in this case. Well, it turns out that Visio automatically steps up (or down if that's not an option) to the next visible page, so there's no need to handle this in code.
You can download an example document (Download PageHidingWithVBA.vsd), which contains a complete version of the above code.