sabato 24 dicembre 2011

Handling events in VB6 exposed on a C# class library through COM

In order to create a .NET class library that can be called by a VB6 client make ComVisible the class and add the interop tags as in the following code

namespace MyClassLibraryNamespace
{

    // The delegate type for our custom event.
    [ComVisible(false)]
    public delegate void MyEventHandler(object sender, EventArgs e);

    [InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
    [ComVisible(true)]
    public interface IMyEvents
    {
        [DispId(1)]//Each event must have a unique DispId
        void OnMyEvent(object sender, EventArgs e);
    }


    [ClassInterface(ClassInterfaceType.None)]
    [ComSourceInterfaces(typeof(IMyEvents))]
    [ComVisible(true)]
    public class MyControl
    {
        public event MyEventHandler OnMyEvent;
  
    }
}

Compile the class library with "Register for COM interop" option in the Build tab of Visual Studio 2010: it will generate a tlb file aside the dll.

Add a reference to the tlb file in the VB6 project

Private WithEvents myCtrl As MyControl

Private Sub Form_Load()
 Set myCtrl = New MyControl
End Sub


Private Sub myCtrl_OnMyEvent(ByVal sender As Variant, ByVal e As EventArgs)
 MsgBox "MyEvent"
End Sub

venerdì 11 novembre 2011

DLL Injection Windows 7 64bit

It seems that Dll injection in Windows 7 64bit could work using the same technique used in Windows XP.
The code I was using works in Windows 7 32bit but doesn't work in Windows 7 64 bit

My code is copied from sample found out in Internet and opens the process to inject a dll:

// Get a handle for the target process.
hProcess = OpenProcess(
        PROCESS_CREATE_THREAD     |   // For CreateRemoteThread
        PROCESS_VM_OPERATION      |   // For VirtualAllocEx/VirtualFreeEx
        PROCESS_VM_WRITE,             // For WriteProcessMemory
        FALSE, dwProcessId);

The code above doesn't work in Windows 7 64 bit. For windows 7 64 bit it should be:

// Get a handle for the target process.
hProcess = OpenProcess(
        PROCESS_ALL_ACCESS, //fix wor windows 7 64 bit
        FALSE, dwProcessId);

mercoledì 2 novembre 2011

How to convert raw pcm data into wav files using NAUDIO library

In my project I have a third party library that produces raw PCM files and I need to play them.
Off course tools like Audacity are able to convert PCM files, but the easiest way I found out to read and play raw PCM files programmatically is using NAUDIO:

WaveFormat format = new WaveFormat(8000, 1);
using (RawSourceWaveStream reader = new RawSourceWaveStream(new FileStream (fileName, FileMode.Open), format))
{
 WaveFileWriter.CreateWaveFile(Path.ChangeExtension(fileName, "wav"), reader);
}

giovedì 1 settembre 2011

Error: The Visual Studio Remote Debugger service on the target computer cannot connect back to this computer

I spent a lot of time trying to debug an application running on an embedded device.
My development computer is running Visual Studio 2010 SP1 on Windows XP SP3 and it is on domain.
The target computer is running Windows Embedded 2009 and it is on the default workgroup.
I'm running the Remote Debugging Monitor as application.
According to this page http://msdn.microsoft.com/en-us/library/ms164725.aspx, using local accounts that have the same username and password on both computers the remote debugging should work.
Eventually I'be been able to debug remotely only taking the development computer out of the domain.

domenica 14 agosto 2011

Riconoscimento della grafia in Windows Embedded 2009

Ora che sono ampiamente disponibili e documentati SDK per dispositivi multitouch e surface SDK, ho faticato un po' a mettere insieme le informazioni per utilizzare il riconoscimento della grafia su un dispositivo senza tastiera con windows embedded 2009 o Windows XP SP3.

Installare il motore di riconoscimento della grafia in Windows XP SP3

Prima di tutto bisogna installare il Software Developers Kit for Windows Tablet PC version 1.7 scaricandolo da qui http://www.microsoft.com/download/en/details.aspx?id=20989.
Poi bisogna installare il Windows XP Tablet PC 2005 Recogniser Pack scaricabile da qui: http://www.microsoft.com/downloads/it-it/details.aspx?familyid=080184dd-5e92-4464-b907-10762e9f918b&displaylang=it.

Utilizzare Tablet PC SDK 1.7 in una applicazione WPF .NET 4.0
Il riconoscimento della grafia viene ottenuto con la classe InkAnalyzer accessibile aggiungendo nel progetto una referenza alla libreria IaWinFX.dll che dovrebbe trovarsi in  C:\Programmi\Reference Assemblies\Microsoft\Tablet PC\v1.7.
I pacchetti installati in precedenza non copiano però nessuna cartella in Reference Assemblies, per cui ho dovuto recuperare IaWinFX.dll da http://amazingwpfcontrols.codeplex.com/
Durante il runtime ho ottenuto però errori di questo tipo:

Error Message: "Could not load file or assembly 'IALoader, Version=1.7.5333.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35' or one of its dependencies. The system cannot find the file specified."

che spariscono installando il pacchetto Ink Analysis and Input Supplement for the Windows XP Tablet PC Edition Development Kit 1.7 da qui http://www.microsoft.com/download/en/details.aspx?id=10462.

Infine bisogna aggiungere nel file app.config useLegacyV2RuntimeActivationPolicy="true":
<configuration>
 
<startup useLegacyV2RuntimeActivationPolicy="true">
   
<supportedRuntime version="v4.0"/>
 
</startup> 
</configuration>


Esempio MVVM .NET 4

giovedì 11 agosto 2011

Choosing a DataTemplate based on properties or status of items

If you have a collection of the same type of data objects you could create a different DataTemplate for items that are of the same type but want to give it a completely different look based on a property or a status of the item itself.
Using the ItemTemplateSelector property of the ListBox could not be the right choice if the new DataTemplate should be triggered on a property change (e.g: change the DataTemplate when the item is selected)

I found out a solution here:
http://codingcontext.wordpress.com/2008/09/28/changing-the-data-template-for-the-currently-selected-item/

A easy solution could be create a new ItemContainerStyle for the ListBox. The ItemTemplate property must not be assigned.

<ListBox Width="400" Margin="10"
         ItemsSource="{Binding myList}"
         ItemContainerStyle="{StaticResource myListBoxItemStyle}"
         HorizontalContentAlignment="Stretch"/>

<Style x:Key="myListBoxItemStyle" TargetType="{x:Type ListBoxItem}" BasedOn="{StaticResource ListBoxItemStyle} >
  <Setter Property="ContentTemplate" Value="{StaticResource myNormalDataTemplate}"/>
    <Style.Triggers>
      <DataTrigger Binding="{Binding IsSpecial}" Value="True">
        <Setter Property="ContentTemplate" Value="{StaticResource mySpecialDataTemplate}"/>                                 
     </DataTrigger>   
  </Style.Triggers>
</Style>

You can download a sample here

mercoledì 10 agosto 2011

Setting a minimum height of the thumb on a vertical scrollbar

This topic has been discussed here http://social.msdn.microsoft.com/Forums/en/wpf/thread/1a7f71bd-d64f-4341-9b7f-9db90afa6e8b
Developing a touch application, the size and the shape of the thumb is very important. In a standard Windows application, the thumb's size is automatically calculated. When the content is very large, the thumb size could be too small to be touched.
To force a minimal size for the thumb:

<Style TargetType="ScrollBar">
        <Setter Property="Template">
          <Setter.Value>
            <ControlTemplate TargetType="ScrollBar">
              <Track Name="PART_Track"
                     IsDirectionReversed="true">
                <Track.Resources>
                  <!-- Thumb's minimum height is half of this metric -->
                  <sys:Double x:Key="{x:Static SystemParameters.VerticalScrollBarButtonHeightKey}">
                    100
                  </sys:Double>
                </Track.Resources>
                <Track.DecreaseRepeatButton>
                  <RepeatButton Command="ScrollBar.PageUpCommand"/>
                </Track.DecreaseRepeatButton>
                <Track.IncreaseRepeatButton>
                  <RepeatButton Command="ScrollBar.PageDownCommand"/>
                </Track.IncreaseRepeatButton>
                <Track.Thumb>
                  <Thumb/>
                </Track.Thumb>
              </Track>
              <ControlTemplate.Triggers>
                <Trigger SourceName="PART_Track" Property="IsEnabled" Value="false">
                  <Setter TargetName="PART_Track" Property="Visibility" Value="Hidden"/>
                </Trigger>
              </ControlTemplate.Triggers>
            </ControlTemplate>
          </Setter.Value>
        </Setter>
      </Style>

Add this in the namespaces section of the control to access System library:
xmlns:sys="clr-namespace:System;assembly=mscorlib"

http://stackoverflow.com/questions/2003372/how-to-represent-system-constants-in-xaml-like-double-maxvalue.

domenica 24 luglio 2011

How to animate an image in MVVM

I want to design a "tableau de bord" with some indicators blinking or animating as soon as a boolean condition is true.
The indicators are simple images, the blinking is obtained changing the image opacity in a Storyboard.

<Storyboard x:Key="BlinkingAnimation">
  <DoubleAnimation Storyboard.TargetProperty="(Image.Opacity)"    
    BeginTime="0:0:0" Duration="0:0:0.5"    
    From="1.0" To="0.0" RepeatBehavior="Forever" AutoReverse="True"/>
</Storyboard>

The animaton will start on a DataTrigger bound to a Property defined in the ViewModel


First recipe: just edit the style of the Image in the XAML

<Image Source="/MvvmBlinkingImage;component/Images/favorite.png" >
  <Image.Style>
     <Style>
      <Style.Triggers>
        <DataTrigger Binding="{Binding Property1}" Value="true">
          <DataTrigger.EnterActions>
            <BeginStoryboard Storyboard="{StaticResource BlinkingAnimation}" x:Name="blink"/>
          </DataTrigger.EnterActions>
          <DataTrigger.ExitActions>
            <StopStoryboard BeginStoryboardName="blink" />
          </DataTrigger.ExitActions>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Image.Style>
 
</Image> 

Second recipe: Create a custom control inherited from Image. The control registers a dependency property to bind to the DataTrigger


public class AnimatedImage : Image
{
        public static DependencyProperty IsBlinkingProperty =
            DependencyProperty.Register("IsBlinking", typeof(bool), typeof(AnimatedImage));
 
        public bool IsBlinking
        {
            get { return (bool)base.GetValue(IsBlinkingProperty); }
            set { base.SetValue(IsBlinkingProperty, value); }
        }
}

Now add a new style to a DictionaryResource for the new AnimatedImage control:


<
Style x:Key="AnimatedImageStyle" TargetType="{x:Type uc:AnimatedImage}">
  <Style.Triggers>
    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsBlinking}" Value="true">
      <DataTrigger.EnterActions>
        <BeginStoryboard Storyboard="{StaticResource BlinkingAnimation}" x:Name="blink"/>
      </DataTrigger.EnterActions>
      <DataTrigger.ExitActions>
        <StopStoryboard BeginStoryboardName="blink" />
      </DataTrigger.ExitActions>
    </DataTrigger>
  </Style.Triggers>
</Style>   

Please note that IsBlinking is a property of AnimateImage and not of the ViewModel, so it is Necessary override the DefaultContext with RelativeSource Self.Here an useful link on WPF binding: http://www.nbdtech.com/Free/WpfBinding.pdf

Eventually use the AnimateImage control and AnimatedImageStyle in the XAML:

<uc:AnimatedImage IsBlinking="{Binding Property1}" Style="{StaticResource AnimatedImageStyle}" Source="/MvvmBlinkingImage;component/Images/favorite.png" />



giovedì 21 luglio 2011

Detecting USB microphone insertion/removal in C# .Net 4.0 WPF

I'm working on a C# .Net 4.0 WPF project that must detect the insertion or removal of an USB microphone.
The code should be implemented in a C# class library.
Since .Net 4.0 doesn't have classes able to detect the insertion or removal of an USB device, the solution is hooking the message WM_DEVICECHANGE, then find out which device changed in order to be sure that the device is the one desired and not some other device.
The first issue to solve is that we don't have any hWnd handle in a class library, so we need to create a fake window in order to hook his window procedure:


HwndSource hwndSource = new HwndSource(0, 0, 0, 0, 0, "fake", IntPtr.Zero);
if (hwndSource != null)  //Attaching to window procedure
    hwndSource.AddHook(new HwndSourceHook(this.hwndSourceHook));

//the window procedure
IntPtr hwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
{
    if (msg == WM_DEVICECHANGE)   
   {
      if ((int)wParam == DBT_DEVICEARRIVAL)
     {   
        DEV_BROADCAST_DEVICEINTERFACE info = (DEV_BROADCAST_DEVICEINTERFACE)   
Marshal.PtrToStructure(lParam, typeof(DEV_BROADCAST_DEVICEINTERFACE));   
      }   
      else if ((int)wParam == DBT_DEVICEREMOVECOMPLETE)
     {
      }
      else if ((int)wParam == DBT_DEVNODES_CHANGED)
     {
     }
  }  
  return IntPtr.Zero;
}


The second problem is to identify the device by the GUID class.
Several microphones by Philips, Olympus or Dictaphone are multicomposite devices.
It means that when you plugin the microphone you get 5 or 6 WM_DEVICECHANGE messages.
So it is preferable to filter the device class using the RegisterDeviceNotification API.

DEV_BROADCAST_DEVICEINTERFACE notificationFilter = new DEV_BROADCAST_DEVICEINTERFACE();
int size = Marshal.SizeOf(notificationFilter);
notificationFilter.dbcc_size = size;
notificationFilter.dbcc_devicetype = DBT_DEVTYP_DEVICEINTERFACE;
notificationFilter.dbcc_reserved = 0;
notificationFilter.dbcc_classguid = new Guid(MediaClassID).ToByteArray();
IntPtr buffer = IntPtr.Zero;
buffer = Marshal.AllocHGlobal(size);
Marshal.StructureToPtr(notificationFilter, buffer, true);
IntPtr result = RegisterDeviceNotification(this._hwndSource.Handle, buffer, (Int32)(DEVICE_NOTIFY.DEVICE_NOTIFY_WINDOW_HANDLE));

The class guid are stored in the registry:
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Class HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\DeviceClasses
If you want find out the class guid of your device, use the parameter DEVICE_NOTIFY_ALL_INTERFACE_CLASSES in RegisterDeviceNotification API, plug in the device into the USB port and read the guid in the DEV_BROADCAST_DEVICEINTERFACE structure.

I found out the following classes used by USB microphones:
KSCATEGORY_CAPTURE = "{65E8773D-8F56-11D0-A3B9-00A0C9223196}"
KSCATEGORY_AUDIO = "{6994AD04-93EF-11D0-A3CC-00A0C9223196}"

Here attached a MVVM project using the USBDetector class

WPF

Non sono un serio sviluppatore ma nella mia attività mi tocca creare scripts e applicazioni per automatizzare l'attività di ufficio. Negli ultimi 20 anni ho utilizzato principalmente come strumenti di programmazione C++ e MFC. Quando l'anno scorso ho visto in azione .Net 4.0 e WPF, mi è uscito spontaneamante un Sokka!
Ho intrapreso un percorso autoformativo per uscire dalla caverna trovando particolarmente utili i webcast di Corrado Cavalli, senza dubbio il migliore nella sua categoria.
Molto interessanti i tutorial di channel9 e gli eventi tecnici di TechEd.
Aggiungendo un pizzico di patterns e toolkits (Model View ViewModel, Dependendy Injection, Inversion of Control) come MVVM LightUnity conto di disporre di un framework che rimarrà attuale per i prossimi 20 anni.

mercoledì 20 luglio 2011

Sokka!

Sokka! è una esclamazione legata a stupore e meraviglia, unita a un po' di soddisfazione, e che sta ad indicare "finalmente ho capito", "ho trovato", l'equivalente di eureka! pronunciato da Archimede, ma molto più liberatorio.
Potete pronunciare Sokka! davanti a un bolognese o a un giapponese, che senza dubbio capirà e si immedesimerà nel vostro stato d'animo. Sokka! è indicata soprattutto dopo essersi conto di aver commesso una grossa cappella.....
In questo blog vorrei postare la soluzione ai miei problemi di tipo informatico che mi hanno fatto esclamare Sokka! con l'auspicio che anche qualcun altro possa esclamare Sokka! leggendo il contenuto di un post.