COM basic sample - visual-c++

I've been reading Essential COM, it is a very good book, very instructive and simple to understand. Now I want to speed things up and implement a simple COM object, compile it into a .dll and finally use it from a client application.
I would really appreciate if anybody could show the most basic sample of how to do that?
I've been trying with this step by step but, besides founding some errors, I could not make it work. The reason for this is that I've created a simple Win32 application, I started coding the COM from scratch (as the step by step shows) and fails to compile/link (lot of errors), I must be forgetting some configuration or some includes in stdafx.h or whatever.
I'm working in Visual C++ with Microsoft Visual Studio .Net 2003
Thanks in advance!

One of the most friction-free ways is to use one of the wizard-generated solutions, and in particular the "ATL Project" wizard in VS 2008 (not sure about 2003). You just select "DLL" when asked the server type you want, and you're left with a very usable COM DLL skeleton where to fill in your code.
Tip: to add a new COM interface and coclass, the easiest way is to go to Class View, right-click on the project, and select Add->Class..., then select "ATL Simple Object" and answer the wizard questions.
EDIT: to answer Toto's additional question in the comments (how to create a client to use the freshly-created COM DLL), the answer is "it depends on the language", as you have an enormous choice here. You can use VB ("add reference"), C#/VB.NET ("add reference", COM tab), VBScript (WScript.CreateObject), and of course C++ too. In a nutshell, from a C++ client you need to include the server's IDL and link to the server's LIB file.

Related

MFC ID_ vs IDM_ prefixes and their range

I have been working on cleaning an old project's resource.h.
In the project I am working on, I have some IDs which are in the form:
IDM_XXXX 32771
but are referred in code in ON_COMMAND and ON_UPDATE_COMMAND_UI statements.
So am I right in thinking that they are following the command architecture and ideally should be named as ID_XXX instead of IDM_XXXX?
I have read through TN022: Standard Commands Implementation and see that Microsoft says:
We recommend you use the standard "IDM_" prefix for menu items which
do not follow the command architecture and need menu-specific code to
enable and disable them.
I am not sure what is meant by menu-specific code here.
How are IDM_XXXX resources normally handled? Also what is the valid range range for IDM_XXXX? I have gone through TN020: ID Naming and Numbering Conventions but am confused.
ID_ and IDM_ are interchangeable because commands are accessible via command bars, menus or maybe ribbons. I never use IDM_, I only use ID_
Reserved by the MFC is 0xE000->0xEFFF and 0x7000->0x7FFF.
TN020 says that menu/command IDs must be in the range of 0x8000 and greater, but I found no reason why to do this. In the tooltip handling and command routing of the dialogs of the 16bit MFC version and AFAIK an old MFC4.x version, there was a specific code that looks for commands being greater than 0x8000.
By accident I had cases were an ID <0x8000 was created, but it worked.
I would resist not following the recommendations in the technical note. Microsoft does have undocumented messages that may interfere with your code if you violate their recommendations. And, debugging such an issue would be difficult. Additionally, following the recommendation allows you the extra benefit of...
following the MFC command architecture not only makes command handlers
more powerful (since they will work with toolbars) but makes the
command handler code reusable
This means MFC will use the same code to handle any menu and toolbar interactions that are linked together.

Simple mvvmcross monotouch with xib support (and monomac)

I tried the simpledroid with INotifyPropertyChanged and ICommand successfully.
I want to do the same with monotouch and xib designer,but without TouchDialog. Is there a way to implement without inheriting from mvx class as in monodroid?
Is it possible to do the same with MonoMac without Dialog as Portable Library in MonoMac or XaMac in supported now?
I understand what is your goal.
I think you want to start learning MvvmCross for Monotouch with a basic application example as you probably did with SimpleDroid. I tried to do the same without success.
Why ? Because SimpleDialogTouch is an "Advanced" example in my opinion. When you learn Monotouch, you use xib to design your view. But the sample tells you to learn a new tool "Monotouch Dialog" which is a way to display controls programmatically.
You get those errors because the sample implements the ViewModel only for Dialog and not for xib or classic binding.
Finally, you will have to dig into MvvmCross to build your own SimpleTouch implementation. The problem is that you don't have a lot of documentation, but Stuart is the best supporter for a beginner or you can switch to advanced Mvx features if you don't need to understand the underground of MvvmCross. There are a lot of samples, tutorials and posts to tweak Mvx.
Hope that helps.
Is there a way to implement without inheriting from mvx class as in monodroid?
I don't believe this is supported in the current source.
There is an effort underway to separate out the databinding code in MvvmCross so it can be used more easily with other frameworks - e.g. we might try porting MvvmLight across too. This is where my effort is currently focused.
If you need this now, then I think you could fairly easily create this simple binding yourself if you wanted to - but you'd have to take a look at what the SimpleDialog version does - it's not too big a code to copy across to the XIB version - https://github.com/slodge/MvvmCross/blob/vnext/Cirrious/Cirrious.MvvmCross.Dialog.Touch/Simple/MvxSimpleTouchDialogViewController.cs
But... why not just implement a proper portable MvxViewModel instead?
Is it possible to do the same with MonoMac without Dialog as Portable Library in MonoMac or XaMac in supported now?
Portable libraries are not supported in any release from Xamarin yet - there is an unofficial installer that Jeff very kindly provided - but it's not a release...
For MvvmCross MonoMac/XaMac support, there is one non-PCL version from #deapsquatter around, but I don't believe this has data-binding yet.
I will be working on a PCL and data-binding release for MonoMac or XaMac - but it's on a spare time basis - no-one's come forward with a customer project to fund that work yet. If you or anyone wants to assist with this port, then you are very welcome... but it will be quite technical work - there are changes I intend to make 'under the covers' - so the easiest place for others to help will probably be in later work - adding more views, more bindings, doing QA, making samples, etc.
Note: "Simple" bindings are not the future for MvvmCross and may get dropped from a future release. However, this will only happen after I've separated out the Binding code so that it can be used with other libraries - the first of which will probably be a simple binding example.
I personally don't see much difference or advantage in using these so-called Simple bindings... but maybe I'm missing something...

Text to Speech (TTS) software for Scripts WAV or MP3 ouput

I asked this question on SuperUser, but it's fallen on deaf ears. Hopefully I can get more of an audience here.
I'm looking for a low cost (or Free) solution like ScriptVox only with a better engine. That is, to read in a script and assign characters to voice. I've read the post here but even with those I'd have to concatenate wav files. It's not that I don't love Audacity, but it is time consuming. I am halfway thinking of writing my own, but I'm sure there has to be a solution out there. Any suggestions?
I would use Microsoft's Text-to-Speech engine. They have a simple example on how to do exactly what you're looking for:
http://msdn.microsoft.com/en-us/library/ms717065(v=vs.85).aspx
With that sample code, you can speak some text and have it dumped to a WAV file. From there, if you need to convert to a format such as MP3, you can use FFMPEG.
Brad's answer is pretty terrific, as it contains exactly what you're looking for. However, it's missing one fundament you'd expressed a preference for in the question errata: an implementation in C#.
Here's a full tutorial to gain access to the Speech API in managed code. With full credit to Blake Niemyjski and the appropriate teams at Microsoft, here's the salient bits, because the linkback to the original article is dead and this appears to be borrowed from Microsoft directly:
The following link (Giving Computers a Voice) will lead you to a
Microsoft site that will show you how to create a project and get a
basic text to speech application up and running in VB .Net or c# in no
time!
SAPI
SAPI is the speech API that gives applications access to speech
recognition and text-to-speech (TTS) engines. This article focuses on
TTS. For TTS, SAPI takes text as input and uses the TTS engine to
output that text as spoken audio. This is the same technology used by
the Windows accessibility tool, Narrator. Every version of Windows
since XP has shipped with SAPI and an English TTS engine.
TTS puts user's ears to work. It allows applications to send
information to the user without requiring the user's eyes or hands.
This is a very powerful output option that isn't often utilized on
PCs.
Three steps are needed to use TTS in a managed application:
Create an interop DLL
Since SAPI is a COM component, an interop DLL is needed to use it from
a managed app. To create this, open the project in Visual Studio.
Select the Project menu and click Add Reference. Select the COM tab,
select "Microsoft Speech Object Library" in the list, and click OK.
These steps add this reference to your project and create an
Interop.SpeechLib.dll in the same folder as your executable. This
interop DLL must always be in the same folder as your .exe to work
correctly.
Reference the interop namespace
Include this namespace in your application. In C#, add "using
SpeechLib;"; iIn VB, add “Imports SpeechLib”.
call Speak()
Create a SpVoice object and call Speak():
Visual C#
SpVoice voice = new SpVoice();
voice.Speak("Hello World!", SpeechVoiceSpeakFlags.SVSFDefault);
Visual Basic
voice = New SpVoice
voice.Speak("Hello World!", SpeechVoiceSpeakFlags.SVSFDefault)
I feel Brad's answer led me to the correct solution here (thus, he's more deserving of credit than I), but this should be the last piece you were missing. You should now be able to replicate the WAV-file writing from the C++ solution in managed code, and from there, transcode into your desired format.
If having the program access internet is acceptable, then you could use iSpeech.
You can use their API, but unfortunately it is limited to 200 uses/day.
Their API also allows appending format=(wav|mp3) following a query, allowing you to get your sound in both desired formats.
http://en.wikipedia.org/wiki/Comparison_of_speech_synthesizers
That's all I've got.
Google translate uses eSpeak http://support.google.com/translate/

What can I do to make my sub-derived custom control appear in the Blend Assets library?

I am creating a series of window mockup templates based on the excellent Mockups library available on CodePlex.
I'm using their BaseMockup as the base for my control as well, and I followed the same outline of the steps listed here for sub-deriving from existing controls (Create a new empty class, add your default style to /Themes/generic.xaml, etc.)
The control is working great - the only thing is that it doesn't show up in the Assets library. I think this is because it's sub-derived, or because I need some attribute (the equivalent of the ToolboxItemAttribute for WinForms controls? ... which didn't work) to get it hooked up.
When I modify the code to derive directly from Control, it shows up - no custom attribute necessary. Of course that defeats the purpose of what I'm trying to do though...
The only thing I can find are several articles telling me to muck with registry keys, and none of them are clear or suggest a definitive way to do this with Blend 4. That last one advertises as a Blend 4 tips article, but admits at the end that it plagiarizes the content from the other two (for Blend 3).
Is that my only option - register my DLL? Is there a better way to do this?
A while ago I wrote a blogpost about this. I've included a .reg file and a .bat file for setting up the register and some directories. I think that's what you are looking for.
I believe you do need to muck with registry keys. Specifically,
32 bit: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NET Framework\v4.0.30319\AssemblyFoldersEx
64 bit: HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\.NET Framework\v4.0.30319\AssemblyFoldersEx
Create a new key with the name of your control assembly. Then edit the Default string value under this key and set the value to the directory where the control assemblies are installed. See here for a full example (using the Silverlight paths).
Found it - there is an analogue attribute after all, it's ToolboxBrowsableAttribute.
You have to go through a little more rigmarole to get it set up, but it works great - no registry mucking necessary. It requires creating a designer metadata provider class, attributing your assembly so it's designer-discoverable, and then adding the attributes to your sub-derived controls inside your metadata provider.
Make sure you choose the appropriate version of the page for your version of Visual Studio, because the interface changes a good bit between 2008 and 2010.
This article on CodeProject has some good, real-world examples of setting this up. They're all in the 2008 style though, so bear that in mind if you're using 2010.

DoDataExchange VC++ 6.0

I inherited an very old application that I am in the process of updating it (I know, we should have rewrote it in VS 2008, but we purchased a company, which is how I was stuck with the relic). Using UpdateData(TRUE) to retrieve the changes made in the dialog controls, nothing is being updated. I have an edit control, with an integer variable, and an edit control with a string variable, assigned using the class wizard. Upon pressing the OK button, the UpdateData(TRUE) is executed to retrieve the new values from the disalog.
I seem to remember having a similar problem back when VS C++ 6.0 first came out, but have not used it since VS 2003 and C# became prevalent.
Thanks for any help in advance!
Bill
Check the DoDataExchange() method. It should have the logic for writing data to or reading it from the controls. If the programmers used the default implementastion, then there will be a DDX_... macro for each control that is being read/written. Just look at any other MFC dialogs (in your code or google) to see how the DDX commands should be written if they are missing.
Alternatively, if it's only 1 or 2 values you can easily just get the control and read it directly if you don't mind doing validation etc yourself. Get the ID of the control from the form designer and use something along the lines of:
CEditWnd *pWnd = GetDlgItem(ID_THECONTROL);
CString newValue = pWnd->GetWindowText();
...
You'll need to look at the content of the DoDataExchange method and see what it is doing. There is not sufficient information here to tell what could be going wrong other than that.

Resources