Wednesday, August 30, 2006

 

Hierarchy Scope versus Node Type

I was just about to call this post A Look at GetHierarchy() III but I think two posts named the "same" is enough. The previous posts I demonstrated how you can get access to content from OneNote using GetHierarchy() using the startNodeID and the HierarchyScope enumeration. I hope you took a few minutes to play with and view the different outcomes based on the startNode and the HierarchyScope. In this post I am covering how the startNodeID type and the HierarchyScope parameters effect the Xml returned.

In this post the actual startNodeID is not as important as the type of node startNodeID refers to. The startNodeID does signifies the "starting node" or what the top-level element in the retuned hierarchy will be. It also determines what element nodes are returned to the caller when reviewed in conjunction with the HierachyScope element.

For example for any given node type and a scope of hsSelf the returned Xml will include a single node of that type with attributes defined for the specific node based on the object ID. Here are examples of resultant Xml based on the node type referenced by the startNodeID

Notebook / hsSelf:
<?xml version="1.0"?>
<one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/12/2004/onenote" name="OneNote Guide Beta 2" nickname="OneNote Guide Beta 2" ID="{674B715E-9A47-4A2C-9D11-5B7325B27D4B}{1}{B0}" path="C:\Documents and Settings\OneNoteGuy\My Documents\OneNote Notebooks\OneNote Guide Beta 2" lastModifiedTime="2006-08-25T12:13:41.000Z" color="none"/>


Section Group / hsSelf:
<?xml version="1.0"?>
<one:Folder xmlns:one="http://schemas.microsoft.com/office/onenote/12/2004/onenote" name="Test" ID="{20476F31-4276-4DC7-ADBE-A50D4F54D711}{1}{B0}" path="C:\Documents and Settings\OneNoteGuy\My Documents\OneNote Notebooks\OneNote Guide Beta 2\Test" lastModifiedTime="2006-08-30T18:42:22.000Z"/>


Section / hsSelf:
<one:Section xmlns:one="http://schemas.microsoft.com/office/onenote/12/2004/onenote" name="More Cool Features" ID="{AD8C801C-F573-0C63-1AC6-624F5676F284}{1}{B0}" path="C:\Documents and Settings\OneNoteGuy\My Documents\OneNote Notebooks\OneNote Guide Beta 2\More Cool Features.one" lastModifiedTime="2006-06-19T18:15:48.000Z" color="#FFD869"/>

Page / hsSelf:
<?xml version="1.0" encoding="utf-16"?>
<one:Page xmlns:one="http://schemas.microsoft.com/office/onenote/12/2004/onenote" ID="{68B0DC18-EC17-0B54-1699-913646F56278}{1}{B0}" name="1. Get a Quick Feel for OneNote" dateTime="2006-06-19T18:15:41.000Z" lastModifiedTime="2006-06-19T18:15:45.000Z" />


The value hsSelf will always return a single element of that type with attributes for the specific instance of the node determined by the startNodeID.

The hsSelf value is self explanatory. hsChildren is just about as self explanatory as hsSelf. Depending on the node type you will see the major nodes below it. hsChildren generally does not recurse below the immediate child node. For example if you use a startNodeId that references a Notebook element and the hsChildren scope the returned Xml will contain the root Notebook element and the immediate children elements which based on the schema include Folder and Section elements. You will not see Page elements nested within the Section element. Apparently the singular exception to this "immediate child only" scope is when the startNodeID references a Page node. In this instance you will get all node contained within the Page node element. This includes nodes that nested within other nested nodes.

Below is a table that displays the resultant Xml for node type versus scope. Where the element is referred to in the singular form it means only one element. Elements referred to in the plural form means zero or more. Elements include all the elements attributes in the Xml result. Error indicates that the node type/scope is not applicable and you will receive a COM exception.

I should mention I am running OneNote 2007 Beta2 so things might change. Also note that a Section Group is defined in Xml as a Folder element.



As always if you find anything contrary to this info please post a comment. I just dont have the time to test every scenerio possible and appreciate a critical eye so we have the most accurate information available to the community.


Friday, August 25, 2006

 

A Look at GetHierarchy() Part II

The GetHierarchy method has three parameters, startNodeId, hsScope and pbstrHierarchyXmlOut. In part I of A Look at GetHierarchy() I posted some demo code that allowed the user to select the hsScope value and dump OneNote data to the console as Xml. If you compiled and ran the demo app you should have seen different console output based on the scope selected. In this post we will cover the startNodeID.

The startNodeID parameter is type string and represents the ID of an object in OneNote 2007. Each unique object in OneNote 2007 contains a unique ID. If you complied and ran the demo app from the first GetHierarchy post you can see more IDs in the console output then you care to see.

An object id in OneNote 2007 must be unique throughout all objects in OneNote. I have not investigated Live Sharing Sessions to see if "shared" objects are unique, but that's for another post. So what is the best way to create globally unique identifier? Well a GUID of course. Well, that and them some.

Here is an example of an object ID:

{68E92C8A-2C70-434E-8721-5257C952B8D8}{1}{B0}

It is probably pretty obvious to a developer that the first portion of this ID is a GUID in "registry format". Tacked on is two other pieces of the id that are "undefined" to the developer but an eagle-eyed developer can see a pattern that associates the second bracketed set in the example ({1}) with page-level objects. For those really into Object IDs you can find it defined in the OneNote 2007 Schemas as a simple type of type string with a defined pattern. Hopefully you have something better to do then read Xml schema's for fun.

So now that we know what an object Id is we can start to use it in our calls to GetHierarchy. To get the OneNote "hierarchy" from the very top you pass in a null value as the first demo app in the original A Look at GetHierarchy() post. If you want to start at some node other than the root node simple pass in the appropriate object ID.

For example I used the GetHierarchy demo, passing in null for the startNodeId. Searching in the Xml results I found the Notebook element with the name attribute equal to "OneNote Guide Beta 2". The id attribute for my OneNote installation is {674B715E-9A47-4A2C-9D11-5B7325B27D4B}{1}{B0}. Your OneNote Guide Beta 2's id attribute will be different.

Now I can modify the original demo. I change the startNodeID from null to " {674B715E-9A47-4A2C-9D11-5B7325B27D4B}{1}{B0}". For your demo insert your specific OneNote Guide Beta 2 id. Quotes are required as this is a string value. Below is the modified line in the original demo:

_AppClass.GetHierarchy("{68E92C8A-2C70-434E-8721-5257C952B8D8}{1}{B0}", hs, out oneNoteAsXml);

Now you can run the demo and choose different HierarchyScope values relative to the OneNote Guide Beta 2 Notebook.

Here is an example of using myOneNote Guide Beta 2 Notebook ID and a HierarchyScope of hsSections (Sections in the demo program):


<?xml version="1.0"?>
<one:Notebook xmlns:one="http://schemas.microsoft.com/office/onenote/12/2004/onenote" name="OneNote Guide Beta 2" nickname="OneNote Guide Beta 2" ID="{674B715E-9A47-4A2C-9D11-5B7325B27D4B}{1}{B0}" path="C:\Documents and Settings\OneNoteGuy\My Documents\OneNote Notebooks\OneNote Guide Beta 2" lastModifiedTime="2006-08-25T03:04:48.000Z" color="none"><one:Section name="Getting Started with OneNote" ID="{BDD843A3-B7E2-0FAB-37B6-C7A9F317F049}{1}{B0}" path="C:\Documents and Settings\OneNoteGuy\My Documents\OneNote Notebooks\OneNote Guide Beta 2\Getting Started with OneNote.one" lastModifiedTime="2006-08-25T03:04:48.000Z" color="#D5A4BB"/><one:Section name="More Cool Features" ID="{AD8C801C-F573-0C63-1AC6-624F5676F284}{1}{B0}" path="C:\Documents and Settings\OneNoteGuy\My Documents\OneNote Notebooks\OneNote Guide Beta 2\More Cool Features.one" lastModifiedTime="2006-06-19T18:15:48.000Z" color="#FFD869"/></one:Notebook>

Wednesday, August 23, 2006

 

Brendon Wilson Gets It

It doesn't take a genius or even a completed MBA to see the value in OneNote. Take a look at what Brendon Wilson has to say about it.

OneNote: PM Super Tool

Tuesday, August 22, 2006

 

A look at GetHierarchy()

GetHierarchy is the key to gaining programmatic access to your OneNote information. Prior to OneNote 12 you were limited to importing data the SimpleImport API. OneNote 2007 gives you the ability to import and export data as Xml using OneNote 2007 APIs.

The GetHierarchy method takes three parameters, the startNode Id as a string, hsScope as HierarchyScope enumeration and pbstrHierarchyXmlOut as a string to contain the Xml representation of the OneNote information.

StartNodeId parameter lists the starting node of the export. Passing in null will start the export at the top of the hierarchy. You can start the export from a lower node by passing a OneNote node id. For this post I am only going to pass in a null value for the StartNodeId parameter.

The second parameter hsScope is a enumerated type named HierarchyScope. This enumeration contains five values Children, Notebooks, Pages, Sections and Self. We will look at the difference of the exported data based on the HierarchyScope value.

The third parameter pbstrHierarchyXmlOut is an string parameter that is used to pass back the requested OneNote information as Xml. This is an out parameter and needs to be defined with the out attribute.

Instead of trying to visually explain what each HierarchyScope values do I have created a simple console application that will pass in a null for the StartNodeId and ask for a HierarchyScope. After you provide the scope the code will call GetHierachy and dump the results to the console. You will need VS to compile this simple console app. Make sure you include a reference to the OneNote interop dll. Check my previous post to see how to reference the OneNote interops.

//Start Code -------------------------------------------------------------------------------

//Make sure your project adds the OneNote API reference
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Office.Interop.OneNote;

namespace OneNoteDemo
{
class OneNote_DemoApp
{
ApplicationClass _AppClass;

static void Main(string[] args)
{
OneNote_DemoApp app = new OneNote_DemoApp();
app.Run();
}

private void Run()
{
//create a new OneNote ApplicationClass
_AppClass = new ApplicationClass();
DumpOneNoteHierarhcy();
Console.WriteLine("\nDone");
Console.ReadLine();
}

private void DumpOneNoteHierarhcy()
{
string oneNoteAsXml;
string result;
HierarchyScope hs;
Console.WriteLine("Dump OneNote Hierarchy");
Console.WriteLine("Select a HierarchyScope:");
Console.WriteLine("Children");
Console.WriteLine("Notebooks");
Console.WriteLine("Pages");
Console.WriteLine("Sections");
Console.WriteLine("Self");
result = Console.ReadLine();

switch (result.ToUpper())
{
case "CHILDREN": { hs = HierarchyScope.hsChildren; break; }
case "NOTEBOOKS": { hs = HierarchyScope.hsNotebooks; break; }
case "PAGES": { hs = HierarchyScope.hsPages; break; }
case "SECTIONS": { hs = HierarchyScope.hsSections; break; }
case "SELF": { hs = HierarchyScope.hsSelf; break; }
default: { hs = HierarchyScope.hsSelf; break; }
}

Console.WriteLine("Scope = " + hs.ToString());

//The key function call is here!
_AppClass.GetHierarchy(null, hs, out oneNoteAsXml);
Console.Write(oneNoteAsXml);
}

~OneNote_DemoApp()
{
//ON Interops call into unmanaged code
//So make sure we destroy it
_AppClass = null;
}
}
}
//End Code ---------------------------------------------------------------------------------

This is a 'fun" little demo app. The xml results are dumped to the console so the reults maybe a little difficult to read. To get a better look at the results I suggest running this application from the console and piping the results to a .xml file and viewing in IE.


I created the code in C#. If there is a request for VB.Net let me know and I will see what I can do. Of course the demo code should not be interpreted as well designed and robust code. It’s demo code.




Sunday, August 20, 2006

 

Referencing the OneNote 2007 APIs in Visual Studio

OneNote 2007 APIs are COM-based APIs. Luckily OneNote like other Office-based apps installs an interop dll into the GAC for .Net developers. Before we can start working with OneNote in Visual Studio we need to create a reference to the OneNote interop dll which will take care of the marshaling of data between managed .Net code and unmanaged COM code.

Creating a VS .Net references is simple. In a Visual Studio 2005 you can access the references from the Solution Explorer. If the Solution Explorer is not visible you can access it from the View menu or use the shortcut Ctrl-W, S. Figure 1 shows my Visual Studio's Solution Explorer.

Figure 1: VS Solution Explorer

To create a reference to the OneNote interop dll right click the reference node in the Solution Explorer , and select Add Reference to bring up the Add Reference Dialog as shown in Figure 2.

Figure 2: Add Reference Dialog

Select Microsoft.Office.Interop.OneNote and click the Ok button. You should see the reference listed under the Reference node in the Solution Explorer as shown in Figure 3.


Figure 3: VS Solution Explorer with OneNote reference

You can now access the OneNote API. Check back later as we work our way though the OneNote 2007 API.





Thursday, August 17, 2006

 

OneNote 2007 Beta 2 Object Model

Not real complex but here it is. See something not correct? Post a comment.


OneNote 2007 API

 

Taking notes - that’s the easy part

It seems most everyone I talk to now knows about OneNote. It usually goes something like this "yes I heard of OneNote. Its that note taking app from MS." Many friends and acquaintances have loaded and tried OneNote, took a few notes, clicked around, made a few folders and pages. Maybe they actually open it once later in the week and try it all over again. "You know it just doesn't click for me. It's easier to take my notes by hand."

It's no surprise that OneNote does not overwhelm everyone with it's note-taking abilities. Come on its just notes. You know how easy it is to take a note on a scrap piece of paper and shove it in your pocket. Just take a look at my desk, notes and scraps all over. Check my car, more notes - hey is that my appointment card for my dentist? Wait there's a few lunches I was supposed to expense last month. Three pads of paper each with various client design notes. Check my dresser where I empty out my pockets at the end of the day. There's a napkin with a design for a OneNote PowerToy - got to remember to put that someplace and not accidently throw it away.

Yes taking notes is easy, just grab a business card, napkin, back side of a bank statement and you are in business. And if OneNote was only good for creating electronic versions of these notes well then there just isn't much sense in losing my notes in a computer. If you think OneNote is just about taking notes then you my friend have not figured it out yet.

The problem with notes is that notes come in all forms and from everywhere. I have "notes" on scraps of paper, whiteboards and even on occasion the back of my hand. I once had a job where the most common place to find your notes was on pieces of medical tape stuck to your pants leg. On the road? Well a call to my office and a "note" left on my voice mail works real nice when I have good idea I know I will forget before I get to where I am going. Like I said "notes" come in all forms - paper like a business card, audio like my voice mail, images like the picture I took of a white board.

And lets not forget the subjects of the notes. I have notes on clients, notes on policies, notes to go to the dentist and doctors. I got a note to remember to get some trim for the house, and don’t forget to call whoever about such and such after Tech Ed. And remember to call about brakes for the car.

When you look at the simple concept of "taking notes" it is suddenly not so simple. As a matter of fact taking notes is the easy part. Organizing them, finding them and working on them is the hard part. Ever spend a day looking for that scrap of paper that has that all important phone number? Or have you moved your desk to find a note written months before reminding you to submit your PowerToy to certain contest? And that is why you need OneNote. Not as another place to lose your notes but a place where you can capture, organize, find and use your notes.

So have you figured it out yet? Start capturing your notes in all their forms into OneNote. Along the way organize them, search for them and actually use them. I wish I would have started using OneNote earlier- I could use the thirty dollars for those lunches I forgot to expense, or one of those slick tablets.


 

OneNote 2007 Extensibility DevCon Video

For all you dev types out there Daniel's DevCon session on OneNote extensiblity is available.

CD310—OneNote 2007: Introducing OneNote Programmability and How To Develop Solutions and Extensions

This time around OneNote will let us import and export infomration. This is a BIG gain for organizing and integrating your information. This is a BIG gain for OneNote PowerToys. No longer will PowerToys be always moving content into OneNote. We can now create Power Toys that send from OneNote.

If you are not a dev type watch the intro of the vid and you will get a quick look into the new features of OneNote 2007. Daniel's session is using Beta1 TR and we are now on Beta2 and waiting for B2TR but you will still get a good view into OneNote 2007's features and extensibilty options.

Wednesday, August 16, 2006

 

Welcome

Welcome to my OneNote blog.


The Unknown OneNote Guy.

This page is powered by Blogger. Isn't yours?



website statistics