Results 1 to 8 of 8

Thread: Windows 2000 issues...

  1. #1

    Windows 2000 issues...

    Okay maybe someone can help explain this...

    I wrote an app using JEDI's Direct X 8.1 headers. Now the app works fine, however upon exit the app crashes under Windows 2000, and it seems to be a pointer issue. I've narrowed down the code section that apparently causes the problem. I'm hoping someone can tell me why it does.

    [pascal][background=#FFFFFF][normal=#000080][number=#FF0000][string=#0000FF][comment=#8080FF][reserved=#000000]
    //Create associated DirectInput devices
    for iCount := 0 to (FJoyList.Count - 1) do begin
    SetLength(FJoyDevice, Length(FJoyDevice) + 1);
    FDirectInput.CreateDevice(PGUID(FJoyList.Objects[iCount])^, FJoyDevice[iCount], nil);
    FJoyDevice[iCount].SetDataFormat(@c_dfDIJoystick2);
    FJoyDevice[iCount].SetCooperativeLevel(Handle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
    //SetLength(FJoyCaps, Length(FJoyCaps) + 1);
    //FJoyCaps[iCount].dwSize := SizeOf(TDIDevCaps);
    //FJoyDevice[iCount].GetCapabilities(FJoyCaps[iCount]);
    DevNum := iCount;
    FJoyDevice[iCount].EnumObjects(EnumInputAxis, nil, DIDFT_AXIS);
    FJoyDevice[iCount].Acquire;
    end;

    [/pascal]

    The three commented lines...
    [pascal][background=#FFFFFF][normal=#000080][number=#FF0000][string=#0000FF][comment=#8080FF][reserved=#000000]
    //SetLength(FJoyCaps, Length(FJoyCaps) + 1);
    //FJoyCaps[iCount].dwSize := SizeOf(TDIDevCaps);
    //FJoyDevice[iCount].GetCapabilities(FJoyCaps[iCount]);

    [/pascal]

    when commented allow for perfect operation. However when uncommented they cause the crash as explained above. I can't figure out why. It seems to surround FJoyCaps which is declared globally as:

    [pascal][background=#FFFFFF][normal=#000080][number=#FF0000][string=#0000FF][comment=#8080FF][reserved=#000000]
    VAR
    FJoyCaps: array of TDIDevCaps;

    [/pascal]

    I've tried setting FJoyCaps := nil; at the end of the procedure, but that doesn't seem to help. Any ideas? This is the only place in my code where I currently use FJoyCaps. And I don't want to proceed until I figure out why this is causing the application to crash on exit.
    My DGDev forum pascal syntax highlight settings:
    <br />[background=#FFFFFF][comment=#8080FF][normal=#000080]
    <br />[number=#C00000][reserved=#000000][string=#00C000]

  2. #2

    Windows 2000 issues...

    I can't quite see the problem here, but why don't you just set the length of the FJoyCaps array before the loop? Also, are you supposed to zero the memory for the TDIDevCaps structure before setting the dwSize?
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  3. #3

    Windows 2000 issues...

    Well I could set the size ahead of time, but I'd much rather only have it as big as I need it. The utility I'm working on is used for configuring gamepads for a console emulator, and there could very well be a large number of attached controllers with varied features. And I have no real way of know whether there are 3 or 30 gamepads attached (okay 30 is pushing it, but I like to be ready for anything). I'll try zeroing out the memory ahead of time and see what happens.

    Here is the entire procedure where I enumerate all the devices:
    [pascal][background=#FFFFFF][normal=#000080][number=#C00000][string=#00C000][comment=#8080FF][reserved=#000000]
    Procedure Tfrm_Main.FormActivate(Sender: TObject);
    Var
    FJoyList: TStringList;
    iCount: Integer;
    Begin
    //Create the DirectInput object
    DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, FDirectInput, nil);

    //Create primary keyboard interface
    ZeroMemory(@DIKeyBuffer, SizeOf(DIKeyBuffer));
    FDirectInput.CreateDevice(GUID_SysKeyboard, FKeyDevice, nil);
    FKeyDevice.SetDataFormat(@c_dfDIKeyboard);
    FKeyDevice.SetCooperativeLevel(Handle, DISCL_NONEXCLUSIVE or DISCL_FOREGROUND);
    FKeyDevice.Acquire;

    //Enumerate attached game controllers
    FJoyList := TStringList.Create;
    FDirectInput.EnumDevices(DIDEVTYPE_JOYSTICK, EnumInputDevs, FJoyList, DIEDFL_ATTACHEDONLY);

    //Create associated DirectInput devices
    for iCount := 0 to (FJoyList.Count - 1) do begin
    SetLength(FJoyDevice, Length(FJoyDevice) + 1);
    FDirectInput.CreateDevice(PGUID(FJoyList.Objects[iCount])^, FJoyDevice[iCount], nil);
    FJoyDevice[iCount].SetDataFormat(@c_dfDIJoystick2);
    FJoyDevice[iCount].SetCooperativeLevel(Handle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
    //SetLength(FJoyCaps, Length(FJoyCaps) + 1);
    //FJoyCaps[iCount].dwSize := SizeOf(TDIDevCaps);
    //FJoyDevice[iCount].GetCapabilities(FJoyCaps[iCount]);
    DevNum := iCount;
    FJoyDevice[iCount].EnumObjects(EnumInputAxis, nil, DIDFT_AXIS);
    FJoyDevice[iCount].Acquire;
    end;

    //Cleanup and free local objects
    for iCount := 0 to (FJoyList.Count - 1) do begin
    Dispose(PGUID(FJoyList.Objects[iCount]));
    end;
    FJoyList.Free;

    //Refresh Main Window
    RefreshWindow;
    End;

    [/pascal]
    My DGDev forum pascal syntax highlight settings:
    <br />[background=#FFFFFF][comment=#8080FF][normal=#000080]
    <br />[number=#C00000][reserved=#000000][string=#00C000]

  4. #4

    Windows 2000 issues...

    Had something like this last month, tied it down to the dynamic array.

    Your line SetLength(FJoyDevice, Length(FJoyDevice) + 1); is definitely going to cause you problems.

    First, (at least in D4) Length refers to the length of a string NOT an array.

    Second finding the size of an array like this (I used Sizeof) simply returns the pointer size to the array.

    The number of elements is given by the function High(arrayname), so to expand a dynamic array you would write

    SetLength(FJoyDevice,High(FJoyDevice)+1);

    Suggest you try this line and see if it solves your problem.

    Hope it helps a little.
    Stevie
    <br />
    <br />Don't follow me..... I'm lost.

  5. #5

    Windows 2000 issues...

    Xorcist:
    I wasn't suggesting having a fixed-length array, but I thought you could have done this:
    [pascal]
    SetLength(FJoyCaps,FJoyList.Count); // Set length here
    FillChar(FJoyCaps[0], (FJoyList.Count * SizeOf(TDIDevCaps)), 0); //Zero memory -- not sure if this is necessary or not...
    for iCount := 0 to (FJoyList.Count - 1) do begin
    SetLength(FJoyDevice, Length(FJoyDevice) + 1);
    FDirectInput.CreateDevice(PGUID(FJoyList.Objects[iCount])^, FJoyDevice[iCount], nil);
    FJoyDevice[iCount].SetDataFormat(@c_dfDIJoystick2);
    FJoyDevice[iCount].SetCooperativeLevel(Handle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
    //SetLength(FJoyCaps, Length(FJoyCaps) + 1); // Remove this line
    FJoyCaps[iCount].dwSize := SizeOf(TDIDevCaps);
    FJoyDevice[iCount].GetCapabilities(FJoyCaps[iCount]);
    DevNum := iCount;
    FJoyDevice[iCount].EnumObjects(EnumInputAxis, nil, DIDFT_AXIS);
    FJoyDevice[iCount].Acquire;
    end;
    [/pascal]

    Stevie:

    SetLength(FJoyDevice, Length(FJoyDevice) + 1); should be fine.

    'High' actually returns length - 1, so to expand the array you would have to do:
    SetLength(FJoyDevice,High(FJoyDevice)+2);

    Length and SizeOf are completely different. Length returns the number of characters in a string, or the number of elements in an array. SizeOf returns the amount of space a particular type takes up (dynamic arrays are actually pointers, so this will always return 4)
    [size=10px][ Join us in #pgd on irc.freenode.net ] [ Sign the Petition for a Software Patent Free Europe ][/size]

  6. #6

    Windows 2000 issues...

    Well I modified the code as such:

    [pascal][background=#FFFFFF][comment=#8080FF][normal=#000080][number=#C00000][reserved=#000000][string=#00C000]
    Procedure Tfrm_Main.FormActivate(Sender: TObject);
    Var
    FJoyList: TStringList;
    iCount: Integer;
    Begin
    //Create the DirectInput object
    DirectInput8Create(hInstance, DIRECTINPUT_VERSION, IID_IDirectInput8, FDirectInput, nil);

    //Create primary keyboard interface
    FillChar(DIKeyBuffer[0], (Length(DIKeyBuffer) * SizeOf(Byte)), 0);
    FDirectInput.CreateDevice(GUID_SysKeyboard, FKeyDevice, nil);
    FKeyDevice.SetDataFormat(@c_dfDIKeyboard);
    FKeyDevice.SetCooperativeLevel(Handle, DISCL_NONEXCLUSIVE or DISCL_FOREGROUND);
    FKeyDevice.Acquire;

    //Enumerate attached game controllers
    FJoyList := TStringList.Create;
    FDirectInput.EnumDevices(DIDEVTYPE_JOYSTICK, EnumInputDevs, FJoyList, DIEDFL_ATTACHEDONLY);

    //Create associated DirectInput devices
    SetLength(FJoyDevice, FJoyList.Count);
    FillChar(FJoyDevice[0], (Length(FJoyDevice) * SizeOf(IDirectInputDevice), 0);
    SetLength(FJoyCaps, FJoyList.Count);
    FillChar(FJoyCaps[0], (Length(FJoyCaps) * SizeOf(TDIDevCaps)), 0);
    for iCount := 0 to (FJoyList.Count - 1) do begin
    FDirectInput.CreateDevice(PGUID(FJoyList.Objects[iCount])^, FJoyDevice[iCount], nil);
    FJoyDevice[iCount].SetDataFormat(@c_dfDIJoystick2);
    FJoyDevice[iCount].SetCooperativeLevel(Handle, DISCL_EXCLUSIVE or DISCL_FOREGROUND);
    FJoyCaps[iCount].dwSize := SizeOf(TDIDevCaps);
    FJoyDevice[iCount].GetCapabilities(FJoyCaps[iCount]);
    DevNum := iCount;
    FJoyDevice[iCount].EnumObjects(EnumInputAxis, nil, DIDFT_AXIS);
    FJoyDevice[iCount].Acquire;
    end;

    //Cleanup and free local objects
    for iCount := 0 to (FJoyList.Count - 1) do begin
    Dispose(PGUID(FJoyList.Objects[iCount]));
    end;
    FJoyList.Free;

    //Refresh Main Window
    RefreshWindow;
    End;

    [/pascal]

    and it seems to have fixed the immediate problems I was having, thanks. Now it's time for an extended testing process. I'll let you know how it goes.
    My DGDev forum pascal syntax highlight settings:
    <br />[background=#FFFFFF][comment=#8080FF][normal=#000080]
    <br />[number=#C00000][reserved=#000000][string=#00C000]

  7. #7

    Windows 2000 issues...

    Um... okay, looks like my initial code was fine too. It seems there is a problem with the Windows 2000 machine I was using as a testbed. I have subsequently tested both versions on other machines running 2000 and both work fine.
    My DGDev forum pascal syntax highlight settings:
    <br />[background=#FFFFFF][comment=#8080FF][normal=#000080]
    <br />[number=#C00000][reserved=#000000][string=#00C000]

  8. #8

    Windows 2000 issues...

    I have similar problems everytime I use a "array of " with any record type, and pass to COM objects.

    so, create a variable...

    BufferCaps: TDIDevCaps;

    and use:

    SetLength(FJoyCaps, Length(FJoyCaps) + 1);
    BufferCaps.dwSize := SizeOf(TDIDevCaps);
    FJoyDevice[iCount].GetCapabilities(BufferCaps);
    FJoyCaps[iCount] := BufferCaps;

    always use a local record to pass to any COM interface, if you pass a record of a dynamic array you always get Access Violation (i think that is bug in the compiler)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •