2

I tested my MIDI app in the Windows XP mode virtual PC and it crashed immediately. Tests on several VirtualBox XP machines were ok. When I remote debug the application it appears to crash in the startup code before it reaches any line of (visible) code. The error message was that there were no MIDI drivers present. This is weird because only in a much later stage of the application the presence of any MIDI system is required and tested.

The control panel shows no MIDI system present, although as one of the integration features audio is mentioned.

Question: how can I prevent my application from crashing because no MIDI drivers are present, before I have a chance to test their presence?

Thanks in advance for any suggestion.

Using Delphi XE

Update Well, I was fooled by the remote debugger in combination with Windows XP mode. It usually doesn't work. The one time I got it somewhat working it gave me the correct answer (no MIDI drivers present). Rob and Warren were right, I should have dived deeper into the debugger before asking the question, sorry for that. However, the problem remains essentially the same, I hope it is accepted to modify the question slightly.

Slightly modified question How can I test in Delphi for no MIDI drivers present in Windows XP mode?

If in my Windows XP mode virtual PC there are no MIDI drivers present, Delphi still sees that one MIDI output device is present. As soon as I try to open this device an exception is raised "There is no driver installed on your system". That's right, but why does midiOutGetNumDevs return 1 instead of 0 in that situation? Using Dave Churchers midi components I have written a small program to reproduce the error. This code works ok on VirtualBox.

unit MIDITest_Main;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, MMSystem, MIDIOut;

type
  TForm1 = class(TForm)
    Button1: TButton;
    List: TListBox;
    Button2: TButton;

    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click (Sender: TObject);
begin
   List.Items.Add (Format ('%d MIDI output devices', [midiOutGetNumDevs]));
end; // Button1Click //

procedure TForm1.Button2Click (Sender: TObject);
var Device: TMidiOutput;
    ePort: Int32;
begin
   for ePort := 0 to midiOutGetNumDevs - 1 do
   begin
      Device := TMidiOutput.Create (Self);
      Device.DeviceID := ePort;
      List.Items.Add (Format ('Trying to open device %d', [Device.DeviceID]));
      Application.ProcessMessages;
//      ShowMessage ('Open');
      if Device.Open then
      begin
         List.Items.Add (Format ('Opened device %s', [Device.ProductName]));
         Application.ProcessMessages;
      end else
      begin
         List.Items.Add (Format ('Cannot open device %d', [Device.DeviceID]));
         Application.ProcessMessages;
      end; // if
   end; // if
end; // Button2Click //

end.
Arnold
  • 4,578
  • 6
  • 52
  • 91
  • 1
    You need more information about how your program crashes in the absence of the required drivers. Once you identify that part of the program, you can work on either delaying that code till later, or getting some of your own code to run first. For example, maybe you're linking with a DLL, and if you loaded the DLL at run time (LoadLibrary), you could have more control over the failure than you can with load-time dynamic linking. – Rob Kennedy Feb 27 '12 at 23:46
  • Why don't you debug the code and find where it crashes. Probably as simple as checking for a valid handle returned from some bit of code you have that wasn't written in a robust style: `if Handle=0 then exit(false);` Programs don't just CRASH because DRIVERS are not present. Code that dereferences a nil pointer crashes. Think, man, think. Learn to use your debug mode. Rob's probably right, it's not a driver in that case, it could be a DLL, an Active X OCX, or anything really. – Warren P Feb 28 '12 at 15:33
  • The crash occurs before the main form is opened, therefor I am not able to test for handles that are zero or dereferencing nil pointers. I can duplicate the absence of a MIDI driver and the crash. And that is strange because MIDI is used later on. I do not link consicously to DLL's, maybe the system ones. There are no initialization sections. Thank you both for your suggestions. I will check for DLL's just to be sure. That is something I would have never thought of. – Arnold Feb 28 '12 at 20:48
  • 3
    Try [madExcept](http://madshi.net/madExceptDescription.htm) – kobik Feb 29 '12 at 12:24
  • @Kobik - didn't know about this product. Seems very useful for these type of errors, thanks for mentioning it! – Arnold Mar 01 '12 at 21:13

1 Answers1

1

This will have nothing to do with Delphi or the MIDI components. midiOutGetNumDevs is an external call to winmm.dll via MMSystem.pas - if that is returning an incorrect value when virtualised, then you need to be looking at or asking Microsoft for the reason why.

BTW, those MIDI components are pretty old now, have you seen this ? http://www.delphipraxis.net/151718-midi-i-o-komponenten-v7.html It is based on the same stuff by Dave Churcher but more recent.ie, it includes a D2010 package rather than Delphi 3(!)

You never know, they may have fixed the crash when no Devices are present.

sergeantKK
  • 644
  • 7
  • 16