Welcome to MSDN Blogs Sign in | Join | Help

Some updates to the OneNote Calendar/Planner powertoy

 

Well, my "well tested" calendar/planner had an easy to fix but obvious problem - it always sent the calendar pages to Unfiled Notes.  I had copied and pasted code from my text importer and that was the cause.  The text importer application used the name of the folder which held the text files as a new section name, so only returned the name of the notebook in which to add a new section and new pages.  This application needs a section in which to put the pages (pages cannot be created directly into a notebook - they need a section) and the tree list was only giving a notebook name.

 

It was a one line fix.

 

Change this:

 

onApp.GetHierarchy(System.String.Empty, OneNote.HierarchyScope.hsNoteBooks , out strHierarchy);

 

To this:

 

onApp.GetHierarchy(System.String.Empty, OneNote.HierarchyScope.hsSections , out strHierarchy);

 

I bold faced the part I changed.  Now the tree control shows you the notebook name and the section name, and returns the section name when you select one.  What had been happening was the tree control was returning the name of a notebook, which caused an error.  I had to deal with this error for this scenario:

 

You have a shared notebook.  When you start the application, the notebook has 2 sections, and the tree view loads them and shows them.  While you are running the application, the section you want to use is deleted by a different user.  I decided to deal with this by defaulting to use Unfiled Notes, since it is always available.

 

Since the notebook name the control was giving was causing an error, the Unfiled Notes section automatically got used instead.  That particular error doesn't get logged either.

 

I was also thinking of making a new section for each month name, but quickly ran into design problems.  Since the original request from "SubSeaGuy" was for a full year, making 12 sections seemed somewhat reasonable.  But since I allowed for a given number of pages to be 1 or more, a whole section to hold a week's worth of pages didn't seem reasonable.  The more I thought about it, the more I thought of other uses that made no sense for a section to be named for each month chosen.  Some people will want weekly agendas.  Some want quarterly.  In the end, I talked myself into a simpler implementation. 

 

My only tool to create this was Visual Studio Express.  That particular version does not include the capability to build a setup project.  That's why I just have the .EXE file (which I also just zipped instead of making you rename it) by itself.  

 

Again, sorry for the initial problems, but they seem to be worked out now.

 

Question, comments, concerns and criticisms always welcome,

John

 

Posted by JohnGuin | 3 Comments
Filed under: ,

A Calendar/Planner powertoy for OneNote!

    I was reading the newsgroups again the other night and "SubSeaGuy" made this post:

    "I want to create a custom calendar.  Rather than typing in the date on each page of which there would be 365, is there a way to import the page name.  The example would be to create the dates (day, dd-mon-yyyy) in say excel, and then import that data as page names."

    Time for a new Powertoy! I've been itching to write another (where does the time go?), and this looked like a great reason. I started with my text importer, stripped out the stuff I did not need and added in a routine to account for the dates to use as page titles. Here's what it looks like on a Windows XP computer:

    clip_image001

    It was pretty simple. It let you pick a start date and a number of days to create. For instance, it looks like SubSeaGuy would want to start on January 1, 2009 and go for 365 days. You can control the date format the page title will get as well. A long format looks like this:

    Monday, October 06, 2008

    And the short format would be

    10/6/2008.

    These settings can be changed in the Windows Control Panel \ Regional Settings application if you want.

    I added the agenda settings after the first iteration. More on that process later. For now, just select whether you want an agenda view, the start and stop times for it and the time increment.

    After making these choices, choose the notebook and section where you want the pages created and press "Make Calendar." Since the pages are blank, it runs pretty quick. On my trusty HP, it took 18 seconds to make a year's worth of pages. Not too shabby, I think.

    I liked this application for a couple of reasons. One, it let me reuse some of my code, so it was pretty easy to write :). Two, it spawned some great ideas for features and test cases. For instance, I did not know whether to let you choose how many days worth of pages to create, or use two date pickers to let you set a start and end date. I decided on the simple number of days since it is a little easier to test, and has a little less code to write.

    I hope you get some use out of this. I can see it being used to save a little time here and there.

    And there is no setup for this. Just copy the file (link below), unzip it and rename it to .EXE and start it. Remember, you will need the .NET framework and OneNote must have the .NET programmability component installed. To check it, look in Control Panel | Programs (or Add/Remove Programs), change the Office install, and look under the OneNote tree to see that the component is installed:

    clip_image002

    You can get the source code here: OneNote Calendar Source Code

    The link for the powertoy is below.

    Let me know what you think!

    Question, comments, concerns and criticisms always welcome,

    John

Posted by JohnGuin | 25 Comments
Filed under: ,

Attachment(s): oncal.zip

Rediscovering the reason we have automation in OneNote

I told the true story last October about a customer who was trying to use an internal modem outside of his computer. The lesson I mentioned is everyone who makes software should have to do tech support for a year before being allowed to do any other work in the computer or software realm. There is a second lesson there that I re-learned this week: don't overlook the obvious.

I've been investigating an automation script which was failing almost 100% of the time. For what it is worth, the script has to do with optimizing OneNote files. The real world use is this - if you delete a few pages from a section, or delete a large enough attachment, OneNote will NOT immediately delete the information from the file. We give you a small period of time to "undo" the operation and delay updating the file on the hard drive until your computer goes idle. You can imagine how this delay could save "thrashing" the hard drive as the file is shrunk and save a little battery life too. You can alter these settings (how big the change must be to cause the optimization and how long to wait until optimizing) by opening Tools | Options | Save:

clip_image001

Back to the automation script. In one method, the script was hitting an error when trying this. Starting too long ago to admit, I started adding more logging to help see where the problem may be in the script, double checking the value of the variables the script was using, diving into the MOTIF framework which actually runs our scripts in the lab, trying to track down if it was only failing on 32 or 64 bit Windows, etc… I was getting nowhere. Then Lin (author of the Journal Importer) came by, took one look and said, "It's probably a new bug in OneNote." Sigh. It was. I had assumed the script was to blame instead of thinking the product had changed. After that, I got a memory dump, callstack, system information, etc… and handed the bug over to developers to fix. Testing the fix should be fairly easy in some ways - the automation script should definitely pass.  After all, that's why we have automation in the first place.

And the lesson I will hopefully remember this time is to check the obvious solutions first.

Questions, comments, concerns and criticisms always welcome,

John

Posted by JohnGuin | 2 Comments

A quick update on the OneNote Accessibility pass (which hasn’t happened yet)

    The accessibility focus effort got moved. I mentioned that we were going to be completing this task a few weeks ago and have received a few emails and comments wanting a follow up. I don't want to keep anyone hanging and figured I should let you know it just hasn't happened yet. I'll let you know when it does.

    Some of the tasks for the week I really look forward to. Personally, running at 120 DPI (dots per inch) simply makes the screen more readable for me. I bought my first laptop in 2003 and remember noticing it was the first machine I had ever seen that had this setting as the default. Office does not stop at 120 DPI, though. For Office 2007, we tested all the way to 192 DPI. And as a general rule, applications get very hard to use past 150 DPI or so. In case you haven't changed these settings yourself, here is what a typical Options page in OneNote looks like at 96 DPI:

    clip_image001

    And here is what the dialog looks like at 192 DPI:

    clip_image002

    The text and buttons obviously larger. Check out http://www.microsoft.com/enable for more information about high DPI. Things to look for (ie, "bugs") would be truncated text, captions that do not fit in labels, buttons that draw off screen and which simply cannot be displayed - even with scroll bars, text that does not resize, etc…

    The automation time we are focusing on is going well. We're getting the last of the automation scripts which were based on the UI converted to "white box" style tests and are completing some other tasks that have built up over the last few months. If I can just get caught up on these tasks, I feel another powertoy coming on…

    Questions, comments, concerns and criticisms always welcome,

    John

Posted by JohnGuin | 2 Comments
Filed under: ,

OneNote Test is hiring!

We have a position open for a Software Development Engineer in Test.  Check out the details at http://members.microsoft.com/careers/search/details.aspx?JobID=CCDDBD6B-E2F5-450F-BAE3-40FE30DF53AE

It's a great job - feel free to shoot any questions my way.

John 

 

Posted by JohnGuin | 1 Comments
Filed under:

Using asserts to help find bugs in OneNote

 

    Of the many different types of bugs testers find in products, "asserts" seem to be the most obvious.  Vastly simplified, an "assert" is a piece of code that checks for some unexpexted condition before continuing, and pops up a dialog if those conditions are not met.  A simple example would be checking for a denominator of zero before dividing, and in C# the code would look something like this:

     

    double numerator = 1;

    #if DEBUG

    {

    Assert (denominator !=0)

    MessageBox.Show("denominator = 0");

    //skip the rest of the code

    }

    #endif

    double result = numerator  / denominator;

     

     

    The #if DEBUG tells the compiler to only add this section of code if a debug build is being compiled.  Debug builds have a lot of this type of code in them, and are used for internal use only - they run much slower than builds we ship that they are useful only for troubleshooting and because they include so much error checking, are much larger file-size wise.  And you can imagine how annoying it is to have pop ups interrupting your work flow. 

     

    The Assert command works like English: "I assert the following statement is true: the value of the denominator is not zero."  If that statement is true, the code continues to run.  If it is not true, then I know I am in an unexpected state, and need to find out why before trying to continue running the code.

     

    So what happens, if you are running a debug build, is that the code in the #if statement gets compiled and executed.  In this case, the denominator value may be zero, so the system will pop up a message box to let me know we are in an error state, and break out of the code before trying to divide by zero.  This would be more useful if the value of denominator were set somewhere else - for instance, if some other function had called this divide function and passed in a zero value of a denominator, the assert will point out the error before trying to divide by zero.  When debugging the code, I can more easily tell that I am in an error state.  How I got into the error state may still be a mystery, but at least I have a starting point.

     

    (Purists can point out that I really could use an "if" statement to check for a zero denominator and avoid the Assert functionality, but  I'm trying to keep it simple with this example).

     

    Another use for the #if DEBUG statement can be seen in my table sums addin.  I have a statement that opens a pop up message immediately after the toolbar button is clicked, but only in debug builds.  This made it easier to attach a debugger to a running process, and let me step through my code as I was troubleshooting.  The version of the addin I released, though, was the Ship version, and the compiler ignored those three lines. 

     

    So bugs that we enter regarding asserts are usually pretty simple:

  1. Click the button I'm testing for this made up test
  2. Point to a zero byte file
  3. Click OK
  4.  

    Result: Assert fires: "File size is zero bytes!"

     

    And the expectation in this case is that since zero byte files are allowed to exist, we need to take that into account in whatever routine is being called from step 2. 

     

    There is much more to be said about asserts.  This just scratches the surface... 

     

    Questions, comments, concerns and criticisms always welcome,

    John

     

     

Posted by JohnGuin | 1 Comments
Filed under: ,

A better fix for the failing OneNote automation script

 

    I did not like my code fix for the error detection routine when  trying to detect which file OneNote had loaded twice.  To refresh my memory, here was what I initially checked in:

     

  1. SortedList<string, string> loadedModules =
  2. new SortedList<string, string>(StringComparer.InvariantCulture);

     

  3. System.Diagnostics.Process onenote = System.Diagnostics.Process.GetProcessesByName("onenote")[0];
  4.  

  5. int i = 0;
  6. Console.WriteLine("There are this many module loaded: " + onenote.Modules.Count);
  7. foreach (System.Diagnostics.ProcessModule loadedModule in onenote.Modules)
  8. {

  9. Console.WriteLine ("Trying to add module " + i + " named " + loadedModule.ModuleName.ToString());
  10. loadedModules.Add(loadedModule.ModuleName.ToLower(), loadedModule.FileName);
  11. i++;
  12. }

     

     

    So what happens with this code is that the first time a module is detected as being loaded twice, the script will log the name of the module and then fail (exit).  This is a decent fix, but has a big limitation from a test point of view.

     

    Consider this list of animals:

    Ant

    Bat

    Cat

    Dog

    Ant

    Bat

    Emu

     

    Clearly, "ant" and "bat" are duplicated.  If my logic was applied to detecting the duplicates, I would find out "ant" was duplicated, but not "bat" (since I error out after the first duplicate detected).  So what would happen is I would spend time tracking down why I had a duplicated "ant," presumably come up with a fix and try to test the fix.  If the same logic error was causing the "bat" problem, and if I had known about that extra error, I could fix the "bat" problem at the same time.  But that is not what will happen here.  After I fix the "ant" error, my test would notice "bat" was also duplicated.  I could potentially need to restart my investigation for this new error and spend time recreating my fix.

     

    There are differences in the two logging calls also - the first call which I added only tells me the name of the duplicated module, but the second also tells me the location from where the module was loaded.  I'd like to have that information available each time a potential duplicate is being tested.

     

    Investigating this problem is now becoming a bit harder.  Since I did not know the "bat" duplication existed, I would need to spend some time determining if my recent changes to fix the "ant" problem had caused the "bat" problem, or if the "bat" problem had already existed.  (On a tangent, if my "ant" fix caused the "bat" module to be duplicated, we call this a regression). 

     

    Clearly, a list of ALL duplicated files from the beginning would have helped.

     

    So here is a much better fix for the loop:

     

     

    foreach (System.Diagnostics.ProcessModule loadedModule in onenote.Modules)

    {

    Console.WriteLine ("Trying to add module " + i + " named " + loadedModule.ModuleName.ToString() +

    "\nfrom location " + loadedModule.FileName );

    try

    {

    loadedModules.Add(loadedModule.ModuleName.ToLower(), loadedModule.FileName);

    }

    catch (Exception e)

    {

    Console.WriteLine("Detected a duplicate module name with " +

    loadedModule.ModuleName +

    "load from location " +

    loadedModule.FileName +

    "\nThe error reported was " + e.ToString());

    }

    i++;

    }

     

    Now I know all modules that get duplicated and the location from which they were loaded.

     

    Hard core coders will not like the try/catch commands, which is why I called this a "better" fix.  A more optimal (from a speed point of view) could be checking the sorted list before trying to add the new element to see if it contains the element already.  Quite frankly, though, that had not occurred to me, and I am not going to worry about the extra milliseconds this loop will consume.  This code works, tells me what I need to know and helps me identify bugs.  It is reliable, easy to read and easy to maintain.  Optimizing for performance is not critical for this test, but would be the "best" fix.

     

    Questions, comments, concerns and criticisms always welcome,

    John

Posted by JohnGuin | 1 Comments
Filed under:

OneNote Favorites updated with user requested feature

 

Shu Chen updated his Favorites addin again.  You can get the updated version at the bottom of this page.  He updated his addin based on these comments from Richard:

 

"...MOVING the OneNote Folder from its position in IE Favorites into Links stops it working properly because the program seems to lose track of its path. If you go to OneNote itself and go to Favorites it tells you that it is empty.

....  I would love to have my OneNotes Favorites folder on my IE toolbar. Must be solvable - can you help!"

 

So now the OneNote favorites bar is shown in IE.    Again, this is one of my favorite addins (no pun intended).  If you haven't installed it yet, please give it a try.  The link for it is at the bottom of this entry.  For what it is worth, I'll try to upload the files from now on the to the MSDN site.  The other ISPs haven't been as reliable as I had hoped.

 

Questions, comments, concerns and criticisms always welcome,

John

Posted by JohnGuin | 1 Comments
Filed under: ,

Attachment(s): onfavorites.zip

Investigating an automation failure

One of the automated tests we had failed last week and I got the chance to investigate the failure. The first level of investigation was determining if the test script had failed or if there was a new bug that had crept into OneNote. Here's what happened.

The first I noticed was an automated email I received about a test failing. Since we have moved from UI based testing to UI-Less, this happened a lot at first, but now is more rare. I looked at the error the test found and this is what I saw:

Error: Test method threw an exception. System.ArgumentException: An entry with the same key already exists.    at System.ThrowHelper.ThrowArgumentException(ExceptionResource resource)    at System.Collections.Generic.SortedList`2.Add(TKey key, TValue value)

Hmm. At first glance, this had nothing to do with OneNote and looked like the test script itself was faulty. Since OneNote was booting and otherwise functioning (this was the only failing test), I disabled the test while I continued the investigation into what was failing.

Here's what the code looked like that was throwing the error, with line numbers added for clarity (go BASIC!):

  1. SortedList<string, string> loadedModules = new SortedList<string, string>(StringComparer.InvariantCulture);
  2. System.Diagnostics.Process onenote = System.Diagnostics.Process.GetProcessesByName("onenote")[0];
  3. foreach (System.Diagnostics.ProcessModule loadedModule in onenote.Modules)
  4. {
  5. loadedModules.Add(loadedModule.ModuleName.ToLower(), loadedModule.FileName);
  6. }

I left out the logging commands which log results to a text file (there were none, by the way).

Here's what was happening. Line 1 creates a list of items which, when new items get added, get added into alphabetical order. This turns out to be critical.

Line 2 gets a handle to the running instance of OneNote. Since the test had progressed past this line, I was reassured OneNote had actually started and was running (in fact, if OneNote is not running, this line gives an array index out of bounds type of error).

Line 3 starts looping through the list of all the DLLs ("modules") OneNote has loaded.

Line 5 adds the name of the loaded module to the alphabetically sorted list.

I ran this a few times and line 4 kept giving me the error I had seen before. Hmm. A quick check on MSDN for SortedList showed me this line of information: "Every key in a SortedList<(Of <(TKey, TValue>)>) must be unique." And if a key with one name already exists, the CLR will throw an ArgumentException. This sounded like exactly what was happening to me.

 

For instance, if OneNote were loading a module named “onmain.dll” twice, the first time the sorted list would add it between “main.dll” and “sps.dll” since it adds the names in alphabetical order.  The next time the sorted list tries to add this name it gives an error since the name already exists in the list. 

I figured the problem was we were loading a DLL twice which would be a bug in OneNote. Since there was no way to tell from the way the test code was written, there was no way to tell which module was being loaded a second time, which means there is also a bug in the test code. Here are the changes I made to discover which module was loaded twice:

  1. SortedList<string, string> loadedModules =new SortedList<string, string>(StringComparer.InvariantCulture);
  2. System.Diagnostics.Process onenote = System.Diagnostics.Process.GetProcessesByName("onenote")[0];
  3. int i = 0;
  4. Console.WriteLine("There are this many module loaded: " + onenote.Modules.Count);
  5. foreach (System.Diagnostics.ProcessModule loadedModule in onenote.Modules)
  6. {
  7. Console.WriteLine ("Trying to add module " + i + " named " + loadedModule.ModuleName.ToString());
  8. loadedModules.Add(loadedModule.ModuleName.ToLower(), loadedModule.FileName);
  9. i++;
  10. }

Maybe it's not obvious, but we do not log to the console - I just added that to make this a little easier to read. We have our own logging class which is quite robust.

Anyway, I checked in my changes and the script will now fail the next time it is run, but now I will know which module is being loaded twice.  And the script will still fail when it detects a module already loaded, and I want the script to fail to alert me to the problem.

And I'm not sold that my changes are the best possible fix. I can still see some room for improvement, which I may try to implement this week. Stay tuned.

Question, comments, concerns and criticisms are always welcome,

John

Posted by JohnGuin | 2 Comments

Using OMSpy to “fix” the bug with the image rotator

    I wanted to show the output of OMSpy in case someone wants to get very bold and use it to update the XML on a OneNote page to work around the limitations I mentioned on Monday with the image rotator.

    Let's start with a simple image to use for testing:

    clip_image001

    And if I right click on the image and select "Copy Text from Image," this is the text I get:

     

    ---------------

    pride and Prejudice

    by ane Austen

    chapter 1

    It is a truth universally acknowledged, that a single man in

    possession of a good fortune, must be In want of a wife. However little known the feelings or views of such a man may

    be on his first entering a neighbourhood, this truth is so well fixed in the minds of the surrounding families, that he is

    considered the rightful property of some one or other of their daughters.

     

    --------------

    This is pretty good. The first "p" needs to be capitalized, and poor Jane lost her "J." The rest of the text looks accurate to me (but the fonts are a little off).

    If I use OMSpy to look at the data on the page, I first start OMSpy and use the tree control to open the page I want to modify. Here's what that looked like to me:

    clip_image002

    <one:OCRData lang="en-US">

    <one:OCRText>

    <![CDATA[pride and Prejudice

    by ane Austen

    chapter 1

    It is a truth universally acknowledged, that a single man in

    possession of a good fortune, must be In want of a wife. However

    little known the feelings or views of such a man may

    be on his first entering a neighbourhood, this truth is so well

    fixed in the minds of the surrounding families, that he is

    considered the rightful property of some one or other of their

    daughters.]]>

    </one:OCRText>

    I broke up the XML to make it a bit easier to read. The first node just tells me this is OneNote's OCR data using English (and more specifically, my system is set to use US English, as opposed to the Queen's English, for instance). The next tag specifies that the actual text OneNote found is coming. It's contained in the CDATA[ ] element found next.

    Then a closing tag and that's it for the text. For images that are upside down

    Next up are a whole slew of lines that look like this:

    <one:OCRToken startPos="0" region="0" line="0" x="1.5" y="2.25" width="30.0" height="8.25" />

    <one:OCRToken startPos="6" region="0" line="0" x="39.75" y="2.25" width="17.25000190734863" height="8.25" />

    <one:OCRToken startPos="10" region="0" line="0" x="65.25" y="2.25" width="55.50000381469727" height="10.5" />

    These track the (x,y) coordinates of each word OneNote. A quick example might help explain what these are for. If I search for Prejudice, I see this in the first image above:

    clip_image003

    The word "prejudice" is highlighted based on the (x,y) coordinates specified here. In this case, the word is the third word found in line 0, so OneNote moved over 62.25 pixels to the right, then down 2.25 pixels to draw a rectangle 55.5 pixels wide and 10.5 pixels tall. The "region" attribute corresponds to the "paragraph" where the word occurs, with "paragraph" being loosely defined since the text you are extracting may not use paragraphs as we typically expect them. The details of the XML schema can be found here. Since even this small bit of text has many words in it, the list of words and (x,y) coordinates here is quite long.

    Anyway, since the image is going to be flipped, rotated and otherwise skewed, this data will soon be NA.

    So to delete all the OCR data with OMSpy, I selected everything from the oneOCRData tag to its close - this includes all the OCRToken data. Then I deleted it from OMSpy. Then I clicked UpdateContent and the XML, which no longer has the OCR data for the image, was put onto the page replacing everything that had been there. Here's what the page data looked like at that point:

    clip_image004

    To me as a user, nothing on the page looked different after I updated the content. When I right clicked the rotated image and selected to extract the text from the image, OneNote triggered its OCR code to recreate the index for the words in the image. Had I performed a search immediately for "pride," though, nothing would have been found since I had just deleted the index.

    Note: If you don't delete exactly the OCRData node and its closing node, you will get error number

    HRESULT: 0x80042000

    Which means you have invalid XML and the API won't let you update the page. Double check the XML structure and try again! In my first image above you can see I did not delete the opening XML tag for OCRData so this is the error I got when I tried to apply my changes after deleting the highlighted information.

    Have fun and remember to back up your notebooks before modifying them!

    Questions, comments, concerns and criticisms always welcome,

    John

Posted by JohnGuin | 1 Comments

This should be an interesting talk to hear in September

    Remember back in June I mentioned Mark Russinovich had talked about his experience starting at Microsoft? I still keep up with his blog (and any tester should keep an eye on it as well) so this notice I received stood out to me. Mark is giving an online talk about Vista performance on September 24. I've already marked my calendar and recommend you do the same.

    Here's the official marketing spiel (which doesn't include the link they included in the email notice - https://ms.istreamplanet.com/springboard. ):

    Springboard Series Virtual Roundtable

    Under the Hood: Windows Vista Performance...Need Answers?

    clip_image001

    Join Mark Russinovich and a panel of industry experts for a LIVE virtual roundtable to explore your top of mind performance issues, common misconfigurations, and tips on how to fix them. From boot times and applets to disk performance and battery life, find out how to optimize Windows Vista and what you can do to improve overall system performance. 

    Submit your performance questions live during the event or send them in advance to vrtable@microsoft.com.

    Save the date!

    Wednesday, September 24, 2008

    9:00am Pacific Standard Time

    -----

    There is a calendar item you can open attached at the bottom of this entry to add to Outlook or any other ical application.

    Questions, comments, concerns and criticisms always welcome,

    John

Using a TRS-80 to find a bug with the image rotator in OneNote

    One of my hobbies which I never have time for is playing around with my old TRS-80 Color Computer. For those that remember this old machines, the majority of software was distributed in magazines and books, and you had to type the code in yourself to run the programs. If the author wrote good code, you learned quite a bit, and if not, you had fun debugging…

    A few days ago an email request came in to the Coco mailing list for a copy of an old program the writer of the email remembered as being named "JOT" and was a three letter word guessing game. Derek, the fellow looking for the program, mentioned he wanted to update the game to use a speech pack or something similar. I had never heard of this, but checked one of my old "TRS-80 Color Programs" books from Radio Shack and found it. I sent Derek a scan of the pages and then decided to see if I could get the program up and running myself. MESS is a fantastic emulator for these old 8 bit machines and newer builds let you paste text into the emulator instead of typing. I decided to scan the pages of the book, let OneNote perform its Optical Character Recognition (OCR) on the text and see how well it converted old BASIC code to text. I figured I could clean up the code in OneNote since its editor is much better than the old TRS-80 and paste away.

    Scanning the book was relatively simple. I had one snag when the cover of the book accidentally hit the power button on my HP-5280 scanner. Since I was only scanning one page at a time, I flipped the book upside down every other scan knowing I could use the image rotator to flip the scan back. Here are the first two scans after I flipped the second image around:

    clip_image001

    The text for the first image wasn't too bad (an excerpt):

    330 PRINT”(THIS TAKES ME A WHILE ...)“

    340 FOR A=N TO 100 STEP —1

    350 B:RN0cA)COSUB fi000;NEXT

    360 PRINT:O=RND(N)

    370 PRINT”I’VE ALMOST GOT IT ..“

    38!) FOR A—99 TO 2 STEP —i

    390 E:=RND(A:COSuB 4000:NExT

    400 lls=As(a):PRINT

    410 PRINT”OK DO YOU WANT TO “

    420 INPUT”GO FIRST”Q$

    430 O$LEFT$(Q$,1)

    Image for the flipped page:

    clip_image002

    But the text for the second (flipped) image was a complete mess:

    1sd 009Z ..a.oii ]V331INI&#62;d 0901
    OLOZ 0601 NJH.L 0&#60;&#62;4 dl OSOT
    •ld 090Z oooc snsoj
    Iid 0S0 $dt.ajg !33 &#18;IflOA S,1LHM,.1fldNI OCOT
    D J 00 1NI ooi
    I 0C0 •.; 3No&#18; SINIHWOS1N1J 0101
    =sc 0Z0Z NId 0001
    OIOZ NJfl1 066
    Id 000Z 0fr6 N3H.L r=&#60;i dl 086
    X3N OIfrI 0001 NH T&#62; dl

    Here's what happened. When I scanned the second image, OneNote ran the image through its OCR logic and generated the text it thought was in the image. Then I rotated it, but for performance reasons, OneNote doesn't send the image through OCR again. (If you've ever copied text from an image and had to wait while OneNote shows the "Recognizing text in pictures" dialog, you'll know how long your computer takes to analyze the image).

    So this is a design flaw in the image rotator. When an image is rotated, the code should remove the list of words associated with the image and let OneNote re-analyze the image after rotation. I verified this would work by using OMSpy to remove the OCR data from an image and updating the page, if you want to follow along with it. Simply copying the image within OneNote also copies the OCR index, so that doesn't work around the image rotation.

    An easier workaround for the time being is to use the screen clipper to capture the rotated image and paste it right back into place. Or, you can cut the image, paste into Paint, then copy and paste right back into OneNote. Using either method works well and this is what the text looked like after using the screen clipper to re-create the image:

    550 IF P$<> THEN 580

    560

    570 H1(CI)=9:GOTO 5000

    588 COSU8 3000

    590 IF F=1 THEN 630

    óco PRIHT”THAT’S NOT A LECAL WORD “

    610 PRIt4r” —- TRY ACAIN

    621 COla 500

    630 OP1$2GOSUB l200:Q.p

    640 ‘ooo

    650 PRINr• OF HITS ISt0

    Which is much better.

    Of the three things to do to work around the problem (use OMSpy, use the screen clipper, or re-write the addin), I prefer the screen clipper since it lets me fine tune the scans. We can also look at the code and try to work in a fix in between testing OneNote.

    Let me know what you think!

    Questions, concerns, comments and criticisms always welcome,

    John

Posted by JohnGuin | 5 Comments

Saying “goodbye to our intern” leads to a reason why a bug did not get fixed in Office 97

    Anirudh Saraf is winding up his internship this week. He's been pretty busy while here - diving into the subtleties of Hyper-V, learning how to get machines working on our network domain, moving into Windows Server 2008, learning our automation system and some of the tools we have, getting some of our automation running in those virtual images he learned about with Hyper-V and working on new features for OneNote! Whew - that's a lot of work for ten weeks. I expect now that he will get back to his blog he'll let us all know what he really thinks… :)

    He and I met yesterday and he had some paperwork which I also needed but had not had time to print. As we went to the photocopier to make me a copy, for no particular reason I was reminded about a bug I found in an addin for Excel way back in Office 97.

    --------------

    I had only been here a few weeks at the time, and Office 97 was in the final stages of shipping. We were looking for the core "ship stopping" bugs and staying focused only on the most severe problems. I was working with the Solver addin for Excel and wanted to print the sample (solvsamp.xls) which came with it. I printed the sample and went to the printer to pick up my copy. The printer was busy printing my copy, then another, and another, and another and so on… I didn't think I had selected multiple copies but went back to my computer to make sure. In the print dialog, the default number of copies which I had assumed was 1 was actually 12334. Yikes! I tried cancelling the print job, but that failed. I went running back to the printer and powered it down simply to save paper, called our helpdesk to let them know why the printer was off and went back to my office to file a bug. I was pretty nervous since I had only been here a few weeks and was wasting paper and unplugging printers. I had no idea what the policies were so I made sure I entered the bug ASAP.

    Here's what the print dialog I had blindly clicked OK on looked like:

    clip_image001

    The bug came back to me resolved as Postponed. To Office, that means the bug is important and we will fix it, but won't be fixed for the release. In this case, it meant Office 97 would ship with this bug and we would fix it in a future release. Considering the panic I had just been through, I disagreed at first. I fought a little to get the bug fixed (after all, it's only changing a single value in the code). I lost my fight, and here's why:

    • First, further testing showed it was only the second sheet of the sample workbook which had this error. There were seven sheets total (although one of the other sheets had -1 as the number of copied to print. If you tried to print it, Clippy would make you choose a valid number.
    • The Solver addin was an optional component and did not install by default. This means the likelihood of a large number of users hitting this is small.
    • Solver is a technically deep addin, and those users who do install it typically know something about linear optimization to begin with. Again, the number of people noticing the sample spreadsheet number of copies is bogus is small.
    • It had been in the product for the entire development cycle and no one had noticed, found or complained about it. Again, the number of users hitting this will be small, and is getting smaller the more I thought about this.
    • There is no data loss. This is limited to printing that one sample spreadsheet, so no one will lose any work.
    • There is no crash in Excel. Since we were in ship stopper mode, crashes and data loss were the most serious bugs.
    • A simple workaround is to type "1" in the number of copies field of the form. The number of copied was already highlighted. If I had been paying attention, I might have noticed it before I printed.

    For all of these reasons, we decided not to attempt a fix before releasing Office 97. It was just too late to try something as risky as "just one number being changed. What could go wrong?" We shipped and as far as I could tell, no one ever called PSS to report this. We eventually did fix the problem, though, so the bug is no longer there.

    --------------

    Kind of a long winded story about a bug, but it serves as an example of a minor bug that we don't want to fix since it puts the entire product at risk. Fixing any bug is a balancing act, and in this case, I think we made the right decision.

    Good luck to Ani as he heads back to school. Keep an eye on his blog for more addins for OneNote and his point of view for how the summer went.

    Questions, comments, concerns and criticisms always welcome,

    John

Posted by JohnGuin | 2 Comments
Filed under: ,

How To Modify OneNote toolbar buttons for installed addins

    Rainald Tassler, one of OneNote's MVPs, had contacted me a while back asking to have the Table of Contents powertoy tweaked to show a button on the toolbar rather than a text string. The text strings tend to take up too much horizontal space on the toolbar and he wanted to replace it with his own image. Fortunately, there is a way to replace that command in the toolbar without writing code and only tweaking the registry. Here's how:

    1. Exit OneNote.
    2. First, create the image if you want to replace a string with an image. It needs to be a 16x16 BMP format image.
    3. Save it in the same folder as the location into which you installed the addin. For instance, if you installed the addin to c:\program files\ microsoft\on table of content setup, copy your bitmap there. It doesn't really matter where you put it, just make note of where it is.
    4. Now it gets a little tricky. Run regedit and open HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\OneNote\Addins
    5. Highlight the addins key and right click it. Select "Export" and save the file to any location you want. This is now your backup in case the next few steps go awry.
    6. You will see a bunch of GUIDS like {806AD7E…} and so on. For the table of contents addin, look for this GUID: {4FE3B6DF-28B8-41d0-A4F5-7010E236B4A2}. Expand its branch
    7. On the right, you will see a string entry for "ButtonText" with a value of Table of Contents. Delete that key:

    clip_image001

8.  Now add a new string value named "IconPath". For its value, enter the path you copied from step 2 and be sure to add the name of the file. Here's what mine looked like:

    clip_image002

9.  Now exit regedit.

10.  Start OneNote. The "Table of Contents" button should be gone and replaced with the icon you created and pointed to!

    You can also reverse these steps and make text strings show for any icons you want.

    I followed the directions on page 11 of the "How to create toolbar addins for OneNote" PDF to come up with routine. Feel free to browse through it. You can even change which toolbar addin buttons appear on in addition to changing the icon. For instance, the task request addin I wrote for Outlook puts the icon for the addin on the Outlook toolbar (value == 9 in this case).

    And if you want to change one of these values and get to step 4 and cannot find the addin you want to modify, be sure to look in HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER. Some addins install their keys there so all users can get the same experience.

    Have fun tweaking the addins for OneNote!

    Questions, comments, concerns and criticisms always welcome,

    John

Posted by JohnGuin | 0 Comments
Filed under:

Code for image rotator and some upcoming work for test

I got a request a few days ago to see about posting the code for the image rotator powertoy. Gary agreed to go ahead and release his code and you can get it here now. The link is at the bottom of this entry.

Another request that comes up every so often on the newsgroups is to restore the sample notebooks that come with OneNote. They are typically created in the \My Documents\OneNote Notebooks folder, but some people go ahead and clean them out from there as well. I've posted the Guide here. You can recreate the Work and Personal Notebooks by selecting File | New Notebook and choosing either Work or Personal from the template list. Oh, and this notebook today is in English. I'll also see about getting it uploaded to the www.microsoft.com/office site as well. The tester in me really wonders why so many users delete the Guide. I have no idea - disk cleanup and optimizer programs? I know the UI of OneNote can get crunched if you have many notebooks open, so closing it is easy to imagine. It's just the deletion I cannot understand.

In other testing news, we will be focused on Accessibility testing next week. We have a "bug bash" scheduled. Bug bashes are usually a lot of fun. Everyone gets turned loose for a day or two to push and stretch features in new ways and our planned testing is largely ignored for the bash. This is the time we get to answer "what if ?" Normally, we know the expected answer. For instance, with napkin math, if I type 6+4= and then hit the space key, I would expect 10 to get added right after the equal sign. With accessibility, I would check the font sizing matches, the screen readers could read it to me and font color as well. Once I started looking at font color, I would start playing with font colors, high contrast screen modes and seeing if I could somehow get the font to be invisible. Then I would start playing with the fonts of the 6, the + sign, the 4 and the = sign and setting them to be different sizes. I would expect the font of the 10 to be the same size (and font!) as the = sign, but maybe it should be the average of the font sizes used in the equation…

If you haven’t seen OneNote in high contrast mode, here is a quick sample:

image

I know that is a little hard to follow, but it is also a creative way to have some fun with testing. I'm looking forward to this upcoming bash.

Questions, comments, concerns and criticisms always welcome,

John

Posted by JohnGuin | 3 Comments
Filed under: ,

Attachment(s): Imagetools.zip
More Posts Next page »
 
Page view tracker