Monday, September 13, 2010

Setting Up an Application for Dragon Naturally Speaking

What this covers:
 Setting up a new project with all the correct settings to integrate Dragon Naturally Speaking into it 

You will need:
- Dragon Naturally Speaking SDK installed on your computer
- Visual Studio (I'll be working from Visual Studio 2005)
- optional: the DragonTools class I wrote. You can also just do Dragon SDK calls but it helps me to have things separated out into a class so that I can reuse things easily and not have to go digging through the SDK documentation to figure things out.

 How it's done:

1) Open up Visual Studio. Begin a new project. Start a project of type "MFC Application".



2) A wizard will come up. Follow the wizard as shown in the images below, and I'll explain what we're doing:
 In this step we're telling it that we're making a "Dialog Based" application, which basically means we're not loading documents into it or anything. We just want a project that's going to be based on a Windows Form so that we can have controls like buttons and text fields. We're also saying to not use Unicode libraries because in a lot of the libraries we use for other things, Unicode character sets will cause problems that are infuriating and impossible to debug.



In the next box you can choose whatever you want. If you want it to be possible to have the traditional drop down style menus and for a person to be able to minimize and maximize your applications, you need to set that up now. I've highlighted the options that make those things possible.
Next we need to make sure that ActiveX components are enabled since Dragon is an ActiveX component.
You can then finish out that wizard however you like.

3) When you're finished, you get a new shiny project. If you go to your Solution Explorer, you'll see something like this. I've labeled the diagram to explain.

You'll be working mostly in the Dialog source file (in this case VirtualPatientDialog.cpp).

4) Optional step. I really hate precompiled headers. To me they don't make compiling any quicker and they only get in my way when I'm trying to add in other classes. I'm going to outline how to disable them because I always do.

Go ahead and open up stdafx.h. The only crucial things that we need for this project are these three lines:

#include <afxwin.h>         // MFC core and standard components
#include <afxext.h>         // MFC extensions
#include <afxdisp.h>        // MFC Automation classes

Copy them. Paste them in the overall application header file (for me, that's Virtual Patient.h). Now, comment out all of stdafx.h and compile. It should compile clean. It might not if you did settings different than I did, so in that case you'll have to figure it out yourself.

Now, go to your Project Settings>Configuration Properties>C/C++>Precompiled Headers and change the first option to "Not using precompiled headers".
Go to your Solution Explorer, highlight stdafx.h and stdafx.cpp, and press the Delete button. It will ask you if you want to remove or delete them. Go ahead and delete.

Compile. Your compiler will tell you anywhere that #includes stdafx, since we just deleted it. Go to those lines and delete them.

5) Now we need to tell the project where to find the Dragon include files. Go to Project Settings> Configuration Properties>C/C++>General. On the top setting, add the path to the Dragon include files. For my computer, it is: C:\Program Files\Nuance\Dragon SDK Client Edition10\SDK\include

Now. This is where it gets confusing, and I don't fully understand what is going on. I am going to guide you through things step by step but I won't be able to explain all of it because I don't understand all of it.

The complexity comes because the Dragon engine is really an ActiveX control. In order to use it in our project, we have to connect through COM, which stands for Component Object Model. It's a standard, not an implementation, but Microsoft has implemented it and that's what we're using. Dragon has already generated "wrapper classes", which translate between our C++ code and the internal ActiveX that Dragon uses, and that's what we're calling in the Dragon include files. But, to make this work we have to do a bunch of weird function calls to start "listening" for those kinds of messages. A lot of that I've already implemented in my DragonTools class, so I won't go into it here. If you have questions, e-mail me.

6) I will assume here that you are going to use my DragonTools class. Go ahead and bring it into your project. It should compile clean if you compile it at this point. Its header contains all the necessary headers.

7) Go to your dialog header file (in my case, Virtual PatientDialog.h). Include the DragonTools header. Make an object of type DragonTools inside of that class. I'm going to call mine Dragon, so in my class variables, I will add:

DragonTools dragon;

8)Go to your main program's .cpp file (in my case, Virtual Patient.h). This is the part I can't quite explain to you, but it has to do with initializing the COM stuff your program needs. At the top right under the includes, declare an object of type CComModule. MSDN tells me that this type is obsolete, but I will keep using it because I'm not sure what to replace it with. I have named my object _Module, so my declaration line is:

CComModule _Module;

9) Scroll down to your InitInstance() function. Under the SetRegistryKey call, paste the following two lines:

::CoInitialize(NULL);
_Module.Init(NULL,m_hInstance);

This somehow associates the COM model to your program. m_hInstance is kind of like a pointer to your application so you're initializing a COM module to your application.

10) Scroll past the modal dialog stuff. There should be a call to dlg.doModal(); and then an if statement to handle responses. Right after that if-statement, paste these two lines:

_Module.Term();
::CoUninitialize();

This will unassociate the COM module and uninitialize it from your program after you close it.

After all this, you should be good to go! You should be able to call Dragon functionality from the DragonTools class from anywhere in your dialog box source file.

No comments:

Post a Comment