topameng's profileQuake3 启示录PhotosBlogListsMore Tools Help

Blog


    April 30

    DINPUT8 Buffer overflow

    long long ago。。。
    DIPROPDWORD property;
    property.dwData = 16;
    这个值基本上够用,但调试的时候会报 buffer overflow 的警告
    所以调高其到255(最大可以调整到1023)。

    在GetDeviceData() 之前如果设备丢失必须先 Acquire() 获取设备。
    不然会有个警告
    看了quake3 可以在GetDeviceData 前调用 Acquire一次, 无论设备是否丢失,这个函数不怎么影响效率。
    当鼠标移动到NC区域,如标题栏,这时候也要卸载dinput鼠标,从dinput获得鼠标位置使用 PtInRect 判断是否在客户区域内,
    但较慢的机器往往有几率不能判断出来,使得dinput鼠标没有卸载,这样拖动标题栏会没有反应。但很多时候又正常。
    只能通过GetCursorPos 来获得鼠标位置再来判断是否出了客户区。

    April 25

    关闭 min max 宏

    #define  NOMINMAX 去掉 windows.h 头文件中的min max宏.
    这样才能使用标准库 limits 中的 min max 函数

    The MDX file format 1

    不好搜到了。备份一份在blog
    The MDX file format!
    Compiled by Magnus Ostberg (aka Magos)
    MagosX@GMail.com

    //+-----------------------------------------------------------------------------
    //| Data types
    //+-----------------------------------------------------------------------------
    CHAR   - 8bit character
    BYTE   - 8bit unsigned integer
    WORD   - 16bit unsigned integer
    DWORD  - 32bit unsigned integer
    FLOAT  - 32bit floating point number
    FLOAT2 - 2-dimensional floating point vector (elements ordered as x, y)
    FLOAT3 - 3-dimensional floating point vector (elements ordered as x, y, z or b, g, r)
    FLOAT4 - 4-dimensional floating point vector (elements ordered as x, y, z, w)
    X[n]   - An n-dimensional vector of type X

    //+-----------------------------------------------------------------------------
    //| Descriptions
    //+-----------------------------------------------------------------------------
    ChunkSize     - ChunkSize is the size of the whole structure *NOT*
                    including the tag and size itself. As an example,
                    the chunksize of the Version structure is 4.

    InclusiveSize - InclusiveSize is the size of the structure including
                    the size of the InclusiveSize variable.

    ExclusiveSize - ExclusiveSize is the size of the structure *NOT*
                    including the size of the ExclusiveSize variable.

    {X};          - A structure that may or may not be present. They
                    may also be in a different order than specified.

    X;            - A structure that must be present and in the
                    specified order.

    #X            - A flag value, more than one can be combined.

    //+-----------------------------------------------------------------------------
    //| Notes
    //+-----------------------------------------------------------------------------
    - All ID's (ObjectId, ParentId, GlobalSequenceId, TextureAnimationId, etc...)
      can use the special value 0xFFFFFFFF to represent 'no ID'.

    - Some ID's (GeosetId, etc...) can use the special value 0xFFFFFFFF to
      represent 'multiple IDs'.

    - All colors are stored as BGR, not RGB!

    //+-----------------------------------------------------------------------------
    //| MDX Model structure
    //+-----------------------------------------------------------------------------
    struct MdxModel
    {
      DWORD 'MDLX';

      {VersionChunk};
      {ModelChunk};
      {SequenceChunk};
      {GlobalSequenceChunk};
      {TextureChunk};
      {TextureAnimationChunk};
      {GeosetChunk};
      {GeosetAnimationChunk};
      {BoneChunk};
      {LightChunk};
      {HelperChunk};
      {AttachmentChunk};
      {PivotPointChunk};
      {ParticleEmitterChunk};
      {ParticleEmitter2Chunk};
      {RibbonEmitterChunk};
      {EventObjectChunk};
      {CameraChunk};
      {CollisionShapeChunk};
    };

    //+-----------------------------------------------------------------------------
    //| Animated geoset translation
    //+-----------------------------------------------------------------------------
    struct GeosetTranslation
    {
      DWORD 'KGTR';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct TranslationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Translation;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated geoset rotation
    //+-----------------------------------------------------------------------------
    struct GeosetRotation
    {
      DWORD 'KGRT';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct RotationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT4 Rotation;

        if(InterpolationType > 1)
        {
          FLOAT4 InTan;
          FLOAT4 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated geoset scaling
    //+-----------------------------------------------------------------------------
    struct GeosetScaling
    {
      DWORD 'KGSC';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Scaling;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated geoset alpha
    //+-----------------------------------------------------------------------------
    struct GeosetAlpha
    {
      DWORD 'KGAO';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Alpha;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated geoset color
    //+-----------------------------------------------------------------------------
    struct GeosetColor
    {
      DWORD 'KGAC';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Color;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated texture translation
    //+-----------------------------------------------------------------------------
    struct TextureTranslation
    {
      DWORD 'KTAT';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct TranslationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Translation;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated texture rotation
    //+-----------------------------------------------------------------------------
    struct TextureRotation
    {
      DWORD 'KTAR';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct TranslationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT4 Rotation;

        if(InterpolationType > 1)
        {
          FLOAT4 InTan;
          FLOAT4 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated texture scaling
    //+-----------------------------------------------------------------------------
    struct TextureScaling
    {
      DWORD 'KTAS';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct TranslationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Scaling;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated camera position translation
    //+-----------------------------------------------------------------------------
    struct CameraPositionTranslation
    {
      DWORD 'KCTR';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct TranslationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Translation;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated camera target translation
    //+-----------------------------------------------------------------------------
    struct CameraTargetTranslation
    {
      DWORD 'KTTR';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct TranslationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Translation;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated camera rotation
    //+-----------------------------------------------------------------------------
    struct CameraRotation
    {
      DWORD 'KCRL';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct TranslationTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Rotation;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated material texture ID
    //+-----------------------------------------------------------------------------
    struct MaterialTextureId
    {
      DWORD 'KMTF';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        DWORD TextureId;

        if(InterpolationType > 1)
        {
          DWORD InTan;
          DWORD OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated material alpha
    //+-----------------------------------------------------------------------------
    struct MaterialAlpha
    {
      DWORD 'KMTA';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Alpha;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated attachment visibility
    //+-----------------------------------------------------------------------------
    struct AttachmentVisibility
    {
      DWORD 'KATV';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Visibility;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated light visibility
    //+-----------------------------------------------------------------------------
    struct LightVisibility
    {
      DWORD 'KLAV';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Visibility;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated light color
    //+-----------------------------------------------------------------------------
    struct LightColor
    {
      DWORD 'KLAC';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 Color;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated light intensity
    //+-----------------------------------------------------------------------------
    struct LightIntensity
    {
      DWORD 'KLAI';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Intensity;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated light ambient color
    //+-----------------------------------------------------------------------------
    struct LightAmbientColor
    {
      DWORD 'KLBC';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT3 AmbientColor;

        if(InterpolationType > 1)
        {
          FLOAT3 InTan;
          FLOAT3 OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated light ambient intensity
    //+-----------------------------------------------------------------------------
    struct LightAmbientIntensity
    {
      DWORD 'KLBI';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT AmbientIntensity;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated particle emitter visibility
    //+-----------------------------------------------------------------------------
    struct ParticleEmitterVisibility
    {
      DWORD 'KPEV';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Visibility;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated particle emitter 2 visibility
    //+-----------------------------------------------------------------------------
    struct ParticleEmitter2Visibility
    {
      DWORD 'KP2V';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Visibility;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated particle emitter 2 emission rate
    //+-----------------------------------------------------------------------------
    struct ParticleEmitter2EmissionRate
    {
      DWORD 'KP2E';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT EmissionRate;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated particle emitter 2 width
    //+-----------------------------------------------------------------------------
    struct ParticleEmitter2Width
    {
      DWORD 'KP2W';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Width;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated particle emitter 2 length
    //+-----------------------------------------------------------------------------
    struct ParticleEmitter2Length
    {
      DWORD 'KP2N';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Length;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    The MDX file format 2

    //+-----------------------------------------------------------------------------
    //| Animated particle emitter 2 speed
    //+-----------------------------------------------------------------------------
    struct ParticleEmitter2Speed
    {
      DWORD 'KP2S';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Speed;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated ribbon emitter visibility
    //+-----------------------------------------------------------------------------
    struct RibbonEmitterVisibility
    {
      DWORD 'KRVS';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT Visibility;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated ribbon emitter height above
    //+-----------------------------------------------------------------------------
    struct RibbonEmitterHeightAbove
    {
      DWORD 'KRHA';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT HeightAbove;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Animated ribbon emitter height below
    //+-----------------------------------------------------------------------------
    struct RibbonEmitterHeightBelow
    {
      DWORD 'KRHB';

      DWORD NrOfTracks;
      DWORD InterpolationType;             //0 - None
                                           //1 - Linear
                                           //2 - Hermite
                                           //3 - Bezier
      DWORD GlobalSequenceId;

      struct ScalingTrack[NrOfTracks]
      {
        DWORD Time;
        FLOAT HeightBelow;

        if(InterpolationType > 1)
        {
          FLOAT InTan;
          FLOAT OutTan;
        }
      };
    };

    //+-----------------------------------------------------------------------------
    //| Node (the base for some of the objects)
    //+-----------------------------------------------------------------------------
    struct Node
    {
      DWORD InclusiveSize;

      CHAR[80] Name;

      DWORD ObjectId;
      DWORD ParentId;
      DWORD Flags;                         //0        - Helper
                                           //#1       - DontInheritTranslation
                                           //#2       - DontInheritRotation
                                           //#4       - DontInheritScaling
                                           //#8       - Billboarded
                                           //#16      - BillboardedLockX
                                           //#32      - BillboardedLockY
                                           //#64      - BillboardedLockZ
                                           //#128     - CameraAnchored
                                           //#256     - Bone
                                           //#512     - Light
                                           //#1024    - EventObject
                                           //#2048    - Attachment
                                           //#4096    - ParticleEmitter
                                           //#8192    - CollisionShape
                                           //#16384   - RibbonEmitter
                                           //#32768   - Unshaded / EmitterUsesMdl
                                           //#65536   - SortPrimitivesFarZ / EmitterUsesTga
                                           //#131072  - LineEmitter
                                           //#262144  - Unfogged
                                           //#524288  - ModelSpace
                                           //#1048576 - XYQuad

      {GeosetTranslation}
      {GeosetRotation}
      {GeosetScaling}
    };

    //+-----------------------------------------------------------------------------
    //| Version information
    //+-----------------------------------------------------------------------------
    struct VersionChunk
    {
      DWORD 'VERS';
      DWORD ChunkSize;

      DWORD Version;                       //Currently 800
    };

    //+-----------------------------------------------------------------------------
    //| Model information
    //+-----------------------------------------------------------------------------
    struct ModelChunk
    {
      DWORD 'MODL';
      DWORD ChunkSize;

      CHAR[80] Name;
      CHAR[260] AnimationFileName;

      FLOAT BoundsRadius;
      FLOAT3 MinimumExtent;
      FLOAT3 MaximumExtent;
      DWORD BlendTime;
    };

    //+-----------------------------------------------------------------------------
    //| Sequences
    //+-----------------------------------------------------------------------------
    struct SequenceChunk
    {
      DWORD 'SEQS';
      DWORD ChunkSize;

      struct Sequence[NrOfSequences]       //NrOfSequences = ChunkSize / 132
      {
        CHAR[80] Name;

        DWORD IntervalStart;
        DWORD IntervalEnd;
        FLOAT MoveSpeed;
        DWORD Flags;                       //0 - Looping
                                           //1 - NonLooping
        FLOAT Rarity;
        DWORD SyncPoint;

        FLOAT BoundsRadius;
        FLOAT3 MinimumExtent;
        FLOAT3 MaximumExtent;
      };
    };

    //+-----------------------------------------------------------------------------
    //| Global sequences
    //+-----------------------------------------------------------------------------
    struct GlobalSequenceChunk
    {
      DWORD 'GLBS';
      DWORD ChunkSize;

      struct GlobalSequence[NrOfGlobalSequences]  //NrOfGlobalSequences = ChunkSize / 4
      {
        DWORD Duration;
      };
    };

    //+-----------------------------------------------------------------------------
    //| Textures
    //+-----------------------------------------------------------------------------
    struct TextureChunk
    {
      DWORD 'TEXS';
      DWORD ChunkSize;

      struct Texture[NrOfTextures]         //NrOfTextures = ChunkSize / 268
      {
        DWORD ReplaceableId;

        CHAR[260] FileName;
        DWORD Flags;                       //#1 - WrapWidth
                                           //#2 - WrapHeight
      };
    };

    //+-----------------------------------------------------------------------------
    //| Layers
    //+-----------------------------------------------------------------------------
    struct LayerChunk
    {
      DWORD 'LAYS';
      DWORD NrOfLayers;

      struct Layer[NrOfLayers]
      {
        DWORD InclusiveSize;

        DWORD FilterMode;                  //0 - None
                                           //1 - Transparent
                                           //2 - Blend
                                           //3 - Additive
                                           //4 - AddAlpha
                                           //5 - Modulate
                                           //6 - Modulate2x

        DWORD ShadingFlags;                //#1   - Unshaded
                                           //#2   - SphereEnvironmentMap
                                           //#4   - ???
                                           //#8   - ???
                                           //#16  - TwoSided
                                           //#32  - Unfogged
                                           //#64  - NoDepthTest
                                           //#128 - NoDepthSet

        DWORD TextureId;
        DWORD TextureAnimationId;
        DWORD CoordId;
        FLOAT Alpha;

        {MaterialAlpha}
        {MaterialTextureId}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Materials
    //+-----------------------------------------------------------------------------
    struct MaterialChunk
    {
      DWORD 'MTLS';
      DWORD ChunkSize;

      struct Material[NrOfMaterials]
      {
        DWORD InclusiveSize;

        DWORD PriorityPlane;
        DWORD Flags;                       //#1  - ConstantColor
                                           //#2  - ???
                                           //#4  - ???
                                           //#8  - SortPrimitivesNearZ
                                           //#16 - SortPrimitivesFarZ
                                           //#32 - FullResolution

        {LayerChunk}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Texture animations
    //+-----------------------------------------------------------------------------
    struct TextureAnimationChunk
    {
      DWORD 'TXAN';
      DWORD ChunkSize;

      struct TextureAnimation[NrOfTextureAnimations]
      {
        DWORD InclusiveSize;

        {TextureTranslation}
        {TextureRotation}
        {TextureScaling}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Geosets
    //+-----------------------------------------------------------------------------
    struct GeosetChunk
    {
      DWORD 'GEOS';
      DWORD ChunkSize;

      struct Geoset[NrOfGeosets]
      {
        DWORD InclusiveSize;

        DWORD 'VRTX';
        DWORD NrOfVertexPositions;

        struct VertexPosition[NrOfVertexPositions]
        {
          FLOAT3 Position;
        };

        DWORD 'NRMS';
        DWORD NrOfVertexNormals;

        struct VertexNormal[NrOfVertexNormals]
        {
          FLOAT3 Normal;
        };

        DWORD 'PTYP';
        DWORD NrOfFaceTypeGroups;

        struct FaceTypeGroup[NrOfFaceTypeGroups]
        {
          DWORD FaceType;                  //4   - Triangles
                                           //??? - Triangle fan
                                           //??? - Triangle strip
                                           //??? - Quads
                                           //??? - Quad strip
        };

        DWORD 'PCNT';
        DWORD NrOfFaceGroups;

        struct FaceGroup[NrOfFaceGroups]
        {
          DWORD NrOfIndexes;
        };

        DWORD 'PVTX';
        DWORD TotalNrOfIndexes;

        struct Face[TotalNrOfFaces]        //TotalNrOfFaces = TotalNrOfIndexes / 3
        {
          WORD Index1;
          WORD Index2;
          WORD Index3;
        };

        DWORD 'GNDX';
        DWORD NrOfVertexGroups;

        struct VertexGroup[NrOfVertexGroups]
        {
          BYTE MatrixGroup;
        };

        DWORD 'MTGC';
        DWORD NrOfMatrixGroups;

        struct MatrixGroup[NrOfMatrixGroups]
        {
          DWORD MatrixGroupSize;
        };

        DWORD 'MATS';
        DWORD NrOfMatrixIndexes;

        struct MatrixIndex[NrOfMatrixIndexes]
        {
          DWORD MatrixIndex;
        };

        DWORD MaterialId;
        DWORD SelectionGroup;
        DWORD SelectionFlags;              //0  - None
                                           //#1 - ???
                                           //#2 - ???
                                           //#4 - Unselectable

        FLOAT BoundsRadius;
        FLOAT3 MinimumExtent;
        FLOAT3 MaximumExtent;

        DWORD NrOfExtents;

        struct Extent[NrOfExtents]
        {
          FLOAT3 MinimumExtent;
          FLOAT3 MaximumExtent;
        };

        DWORD 'UVAS';
        DWORD NrOfTextureVertexGroups;

        DWORD 'UVBS';
        DWORD NrOfVertexTexturePositions;

        struct VertexTexturePosition[NrOfVertexTexturePositions]
        {
          FLOAT2 TexturePosition;
        };
      };
    };

    //+-----------------------------------------------------------------------------
    //| Geoset animations
    //+-----------------------------------------------------------------------------
    struct GeosetAnimationChunk
    {
      DWORD 'GEOA';
      DWORD ChunkSize;

      struct GeosetAnimation[NrOfGeosetAnimations]
      {
        DWORD InclusiveSize;

        FLOAT Alpha;
        DWORD Flags;                       //#1 - DropShadow
                                           //#2 - Color
        FLOAT3 Color;

        DWORD GeosetId;

        {GeosetAlpha}
        {GeosetColor}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Bones
    //+-----------------------------------------------------------------------------
    struct BoneChunk
    {
      DWORD 'BONE';
      DWORD ChunkSize;

      struct Bone[NrOfBones]
      {
        Node;

        DWORD GeosetId;
        DWORD GeosetAnimationId;
      };
    };

    //+-----------------------------------------------------------------------------
    //| Lights
    //+-----------------------------------------------------------------------------
    struct LightChunk
    {
      DWORD 'LITE';
      DWORD ChunkSize;

      struct Light[NrOfLights]
      {
        DWORD InclusiveSize;

        Node;

        DWORD Type;                        //0 - Omnidirectional
                                           //1 - Directional
                                           //2 - Ambient
        DWORD AttenuationStart;
        DWORD AttenuationEnd;
        FLOAT3 Color;
        FLOAT Intensity;
        FLOAT3 AmbientColor;
        FLOAT AmbientIntensity;

        {LightVisibility}
        {LightColor}
        {LightIntensity}
        {LightAmbientColor}
        {LightAmbientIntensity}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Helpers
    //+-----------------------------------------------------------------------------
    struct HelperChunk
    {
      DWORD 'HELP';
      DWORD ChunkSize;

      struct Helper[NrOfHelpers]
      {
        Node;
      };
    };

    //+-----------------------------------------------------------------------------
    //| Attachments
    //+-----------------------------------------------------------------------------
    struct AttachmentChunk
    {
      DWORD 'ATCH';
      DWORD ChunkSize;

      struct Attachment[NrOfAttachments]
      {
        DWORD InclusiveSize;

        Node;

        CHAR[260] Path;
        DWORD AttachmentId;                //First attachment - 0, second - 1 etc...

        {AttachmentVisibility}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Pivot points
    //+-----------------------------------------------------------------------------
    struct PivotPointChunk
    {
      DWORD 'PIVT';
      DWORD ChunkSize;

      struct PivotPoint[NrOfPivotPoints]   //NrOfPivotPoints = ChunkSize / 12
      {
        FLOAT3 Position;
      };
    };

    //+-----------------------------------------------------------------------------
    //| Particle emitters
    //+-----------------------------------------------------------------------------
    struct ParticleEmitterChunk
    {
      DWORD 'PREM';
      DWORD ChunkSize;

      struct ParticleEmitter[NrOfParticleEmitters]
      {
        DWORD InclusiveSize;

        Node;

        FLOAT EmissionRate;
        FLOAT Gravity;
        FLOAT Longitude;
        FLOAT Latitude;

        CHAR[260] SpawnModelFileName;

        FLOAT LifeSpan;
        FLOAT InitialVelocity;

        {ParticleEmitterVisibility}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Particle emitters 2
    //+-----------------------------------------------------------------------------
    struct ParticleEmitter2Chunk
    {
      DWORD 'PRE2';
      DWORD ChunkSize;

      struct ParticleEmitter2[NrOfParticleEmitters2]
      {
        DWORD InclusiveSize;

        Node;

        FLOAT Speed;
        FLOAT Variation;
        FLOAT Latitude;
        FLOAT Gravity;
        FLOAT Lifespan;
        FLOAT EmissionRate;
        FLOAT Length;
        FLOAT Width;

        DWORD FilterMode;                  //0 - Blend
                                           //1 - Additive
                                           //2 - Modulate
                                           //3 - Modulate2x
                                           //4 - AlphaKey

        DWORD Rows;
        DWORD Columns;
        DWORD HeadOrTail;                  //0 - Head
                                           //1 - Tail
                                           //2 - Both

        FLOAT TailLength;
        FLOAT Time;

        FLOAT3[3] SegmentColor;
        BYTE[3] SegmentAlpha;
        FLOAT[3] SegmentScaling;

        DWORD HeadIntervalStart
        DWORD HeadIntervalEnd
        DWORD HeadIntervalRepeat
        DWORD HeadDecayIntervalStart
        DWORD HeadDecayIntervalEnd
        DWORD HeadDecayIntervalRepeat
        DWORD TailIntervalStart
        DWORD TailIntervalEnd
        DWORD TailIntervalRepeat
        DWORD TailDecayIntervalStart
        DWORD TailDecayIntervalEnd
        DWORD TailDecayIntervalRepeat

        DWORD TextureId;
        DWORD Squirt;                      //0 - No Squirt
                                           //1 - Squirt
        DWORD PriorityPlane;
        DWORD ReplaceableId;

        {ParticleEmitter2Visibility}
        {ParticleEmitter2EmissionRate}
        {ParticleEmitter2Width}
        {ParticleEmitter2Length}
        {ParticleEmitter2Speed}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Ribbon emitters
    //+-----------------------------------------------------------------------------
    struct RibbonEmitterChunk
    {
      DWORD 'RIBB';
      DWORD ChunkSize;

      struct RibbonEmitter[NrOfRibbonEmitters]
      {
        DWORD InclusiveSize;

        Node;

        FLOAT HeightAbove;
        FLOAT HeightBelow;
        FLOAT Alpha;
        FLOAT3 Color;
        FLOAT LifeSpan;

        DWORD TextureSlot;

        DWORD EmissionRate;
        DWORD Rows;
        DWORD Columns;
        DWORD MaterialId;
        FLOAT Gravity;

        {RibbonEmitterVisibility}
        {RibbonEmitterHeightAbove}
        {RibbonEmitterHeightBelow}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Tracks
    //+-----------------------------------------------------------------------------
    struct Tracks
    {
      DWORD 'KEVT';
      DWORD NrOfTracks;

      DWORD GlobalSequenceId;

      struct Track[NrOfTracks]
      {
        DWORD Time;
      };
    };

    //+-----------------------------------------------------------------------------
    //| Event objects
    //+-----------------------------------------------------------------------------
    struct EventObjectChunk
    {
      DWORD 'EVTS';
      DWORD ChunkSize;

      struct EventObject[NrOfEventObjects]
      {
        Node;

        {Tracks}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Cameras
    //+-----------------------------------------------------------------------------
    struct CameraChunk
    {
      DWORD 'CAMS';
      DWORD ChunkSize;

      struct Camera[NrOfCameras]
      {
        DWORD InclusiveSize;

        CHAR[80] Name;

        FLOAT3 Position;
        DWORD FieldOfView;
        DWORD FarClippingPlane;
        DWORD NearClippingPlane;
        FLOAT3 TargetPosition;

        {CameraPositionTranslation}
        {CameraTargetTranslation}
      };
    };

    //+-----------------------------------------------------------------------------
    //| Collision shapes
    //+-----------------------------------------------------------------------------
    struct CollisionShapeChunk
    {
      DWORD 'CLID';
      DWORD ChunkSize;

      struct CollisionShape[NrOfCollisionShapes]
      {
        Node;

        DWORD Type;                        //0 - Box
                                           //1 - ???
                                           //2 - Sphere

                                           //NrOfVertices = 2 (if Type == 0)
        struct Vertex[NrOfVertices]        //NrOfVertices = 1 (if Type == 2)
        {
          FLOAT3 Position;
        };

        if(Type == 2)
        {
          FLOAT BoundsRadius;
        }
      };
    };

    April 21

    dxcpl 调试

    设置 dxcpl debug output level 为最大,出现大量下面的警告:
    Direct3D9: (WARN) :Ignoring redundant SetRenderState。。。
    说明某个SetRenderState 反复设置相同的值。如:
    Direct3D9: (WARN) :Ignoring redundant SetRenderState - 24
    反复设置 D3DRS_ALPHAREF 为相同值。
    这样会降低效率。既然已经设置过了除非设置不同的值,否则就无需再设置了,应该减少的函数调用还是可以减少的。
    检查dx内存泄漏可以用dcpl 中的 break on allocid 来观察,好像不行
    可以,往往一个资源未卸载导致一堆泄漏,从最后一个allocid 查起。有时看运气,跟运行时间也有关系。

    debug 版本工程预处理定义加入 D3D_DEBUG_INFO
    用的2006的dxcpl,里面的设置似乎只影响dx9程序,当在调试和运行版切换时,dx9库的程序效率下降,dx8的反倒没有什么变化
    几次忘掉这个事,以为那里错了,效率差了这么多,忙忙呼呼找上半天。

    dll 中 string 内存泄漏问题

    dll 导出函数即使间接引用的函数,如果输入参数为std::string 引用类型,那么该string 会引起内存泄漏。
    如导出函数,这种容易发现。但间接的很难查找。: 
    void dllex(char* s)
    {
       std::string test = s
    }
    但不一定就泄漏,很光棍的问题。类A中一个类成员变量B的成员name为string 。赋值时出现内存泄漏.而我在A中声明一个string成员同样取得相同值。缺没有内存泄漏出现。郁闷,百思不得其解中,弄错了这里
    void dllex(string& str)  如果dllex 中修改了str内容,这样会有内存泄漏。
    终于找到原因了,回收b的地方memset了结构对象放入了回收列表。而原来是用char数组的,改成string 实现没有发现这个地方,
    :( ,发现内存泄漏后,反倒一直在alloc的地方找问题。郁闷

    April 18

    错误c2059

    疯了,浪费了一个小时。删除掉了一个空行就出了这个问题。加回去正常编译。日
    怀疑预编译头文件有问题,把当前文件预编译选项设成了不使用预编译头,编译又过了。
    等我加了个空行,日啊,又不行了。
    最后发现是 typedef struct {} structa; 这个结构中我放入了一个string 类型,这可捅了马蜂窝,浪费时间和心情。
    typedef struct
    {

    } name;
    这是常用的 c 中的写法。
    鄙视. 郁闷, 总夸c++ 灵活,灵活的地方小人物用不到,我是没信心去搞模板那一套,搞得比perl还难懂。用常用的东西,还要躲避乱七八糟的规则,烦啊

    得到的教训是:struct 只包含原型成员不应包含类成员(struct 定义的类也算),可以作为编码规范。如果需要类成员,则定义为类class 而非struct。还有认清typedef的用法

    在使用2003时遇到的问题,到2005似乎没有了。忘记了当时的情形。 :(, 不过现在用2005不用为这个烦恼了。typedef 还是可以用的

    April 15

    SwapEffect

    使用D3DSWAPEFFECT_DISCARD 才能支持全屏抗锯齿,但使用GetBackBuffer可能获得不到后台缓冲。用这个方法截屏就不行了。而且DISCARD 并不像某些书写的效率高,在我的8600GT 上还没有COPY效率好。
    或者3D游戏多边形多起来才能体现效率吧,毕竟3D游戏都是需要抗锯齿给玩家选择的
    主要是因为设置了puredevice才造成不能GetBackBuffer.但有些显卡又可以调用
    DISCARD 是要用的。puredevice 也需要。截屏似乎用截屏键更有效,或者还有其他方法来实现

    ogre 无法解析的外部符号 _IID_IDirect3DBaseTexture9

    RenderSystem_Direct3D9 工程加入dxguid.lib
    解决办法 DX9SDK\Lib\x86 目录放到vc平台 sdk 目录前面

    D3DCREATE_FPU_PRESERVE

    在FPU中,却存在着三种运算精度:single precision(24bits),double precision(53bits),double extended precision(64bits)。FPU的默认精度是53bits的double precision。D3D的CreateDevice函数会将FPU的运算精度改成24bits,除非指定了D3DCREATE_FPU_PRESERVE参数。
    April 02

    驱动级模拟(硬件模拟)

    转个文章,即使使用directinput 也不能屏蔽按键精灵的输入,而按键精灵不过调用了第三方的dll.来实现的知道这些有利于检测简单的按键程序
    对于检测加速器就更简单了,其实只要你调试一下程序就能发现所谓加速器的秘密。不过是让2次timeGetTime 之类函数差值变长。甚好解决

      如果上面的方法你都试过了,可是你发现目标程序却仍然顽固的不接受你模拟的消息,寒~~~~~~~~~还好,我还剩下最后一招,这就是驱动级模拟:直接读写键盘的硬件端口!

      有一些使用DirectX接口的游戏程序,它们在读取键盘操作时绕过了windows的消息机制,而使用DirectInput.这是因为有些游戏对实时性控制的要求比较高,比如赛车游戏,要求以最快速度响应键盘输入。而windows消息由于是队列形式的,消息在传递时会有不少延迟,有时1秒钟也就传递十几条消息,这个速度达不到游戏的要求。而DirectInput则绕过了windows消息,直接与键盘驱动程序打交道,效率当然提高了不少。因此也就造成,对这样的程序无论用PostMessage或者是keybd_event都不会有反应,因为这些函数都在较高层。对于这样的程序,只好用直接读写键盘端口的方法来模拟硬件事件了。要用这个方法来模拟键盘,需要先了解一下键盘编程的相关知识。

      在DOS时代,当用户按下或者放开一个键时,就会产生一个键盘中断(如果键盘中断是允许的),这样程序会跳转到BIOS中的键盘中断处理程序去执行。打开windows的设备管理器,可以查看到键盘控制器由两个端口控制。其中&H60是数据端口,可以读出键盘数据,而&H64是控制端口,用来发出控制信号。也就是,从&H60号端口可以读此键盘的按键信息,当从这个端口读取一个字节,该字节的低7位就是按键的扫描码,而高1位则表示是按下键还是释放键。当按下键时,最高位为0,称为通码,当释放键时,最高位为1,称为断码。既然从这个端口读数据可以获得按键信息,那么向这个端口写入数据就可以模拟按键了!用过QbASIC4.5的朋友可能知道,QB中有个OUT命令可以向指定端口写入数据,而INP函数可以读取指定端口的数据。那我们先看看如果用QB该怎么写代码:

    假如你想模拟按下一个键,这个键的扫描码为&H50,那就这样
    OUT &H64,&HD2   '把数据&HD2发送到&H64端口。这是一个KBC指令,表示将要向键盘写入数据
    OUT &H60,&H50   '把扫描码&H50发送到&H60端口,表示模拟按下扫描码为&H50的这个键
    那么要释放这个键呢?像这样,发送该键的断码:
    OUT &H64,&HD2   '把数据&HD2发送到&H64端口。这是一个KBC指令,表示将要向键盘写入数据
    OUT &H60,(&H50 or &H80)   '把扫描码&H50与数据&H80进行或运算,可以把它的高位置1,得到断码,表示释放这个键

      好了,现在的问题就是在VB中如何向端口写入数据了。因为在windows中,普通应用程序是无权操作端口的,于是我们就需要一个驱动程序来帮助我们实现。在这里我们可以使用一个组件WINIO来完成读写端口操作。什么是WINIO?WINIO是一个全免费的、无需注册的、含源程序的WINDOWS2000端口操作驱动程序组件(可以到http://www.internals.com/上去下载)。它不仅可以操作端口,还可以操作内存;不仅能在VB下用,还可以在DELPHI、VC等其它环境下使用,性能特别优异。下载该组件,解压缩后可以看到几个文件夹,其中Release文件夹下的3个文件就是我们需要的,这3个文件是WinIo.sys(用于win xp下的驱动程序),WINIO.VXD(用于win 98下的驱动程序),WinIo.dll(封装函数的动态链接库),我们只需要调用WinIo.dll中的函数,然后WinIo.dll就会安装并调用驱动程序来完成相应的功能。值得一提的是这个组件完全是绿色的,无需安装,你只需要把这3个文件复制到与你的程序相同的文件夹下就可以使用了。用法很简单,先用里面的InitializeWinIo函数安装驱动程序,然后就可以用GetPortVal来读取端口或者用SetPortVal来写入端口了。好,让我们来做一个驱动级的键盘模拟吧。先把winio的3个文件拷贝到你的程序的文件夹下,然后在VB中新建一个工程,添加一个模块,在模块中加入下面的winio函数声明:

    Declare Function MapPhysToLin Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysSize As Long, ByRef PhysMemHandle) As Long
    Declare Function UnmapPhysicalMemory Lib "WinIo.dll" (ByVal PhysMemHandle, ByVal LinAddr) As Boolean
    Declare Function GetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByRef PhysVal As Long) As Boolean
    Declare Function SetPhysLong Lib "WinIo.dll" (ByVal PhysAddr As Long, ByVal PhysVal As Long) As Boolean
    Declare Function GetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByRef PortVal As Long, ByVal bSize As Byte) As Boolean
    Declare Function SetPortVal Lib "WinIo.dll" (ByVal PortAddr As Integer, ByVal PortVal As Long, ByVal bSize As Byte) As Boolean
    Declare Function InitializeWinIo Lib "WinIo.dll" () As Boolean
    Declare Function ShutdownWinIo Lib "WinIo.dll" () As Boolean
    Declare Function InstallWinIoDriver Lib "WinIo.dll" (ByVal DriverPath As String, ByVal Mode As Integer) As Boolean
    Declare Function RemoveWinIoDriver Lib "WinIo.dll" () As Boolean

    ' ------------------------------------以上是WINIO函数声明-------------------------------------------

    Declare Function MapVirtualKey Lib "user32" Alias "MapVirtualKeyA" (ByVal wCode As Long, ByVal wMapType As Long) As Long

    '-----------------------------------以上是WIN32 API函数声明-----------------------------------------

    再添加下面这个过程:
    Sub KBCWait4IBE()   '等待键盘缓冲区为空
    Dim dwVal As Long
      Do
      GetPortVal &H64, dwVal, 1
    '这句表示从&H64端口读取一个字节并把读出的数据放到变量dwVal中
    'GetPortVal函数的用法是GetPortVal 端口号,存放读出数据的变量,读入的长度
      Loop While (dwVal And &H2)
    End Sub
    上面的是一个根据KBC规范写的过程,它的作用是在向键盘端口写入数据前等待一段时间,后面将会用到。
    然后再添加如下过程,这2个过程用来模拟按键:

    Public Const KBC_KEY_CMD = &H64    '键盘命令端口
    Public Const KBC_KEY_DATA = &H60   '键盘数据端口

    Sub MyKeyDown(ByVal vKeyCoad As Long)  
    '这个用来模拟按下键,参数vKeyCoad传入按键的虚拟码
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)
      
        KBCWait4IBE   '发送数据前应该先等待键盘缓冲区为空
        SetPortVal KBC_KEY_CMD, &HD2, 1     '发送键盘写入命令
    'SetPortVal函数用于向端口写入数据,它的用法是SetPortVal 端口号,欲写入的数据,写入数据的长度
        KBCWait4IBE
        SetPortVal KBC_KEY_DATA, btScancode, 1  '写入按键信息,按下键
        
    End Sub

    Sub MyKeyUp(ByVal vKeyCoad As Long)  
    '这个用来模拟释放键,参数vKeyCoad传入按键的虚拟码
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)

       KBCWait4IBE    '等待键盘缓冲区为空
       SetPortVal KBC_KEY_CMD, &HD2, 1 '发送键盘写入命令
       KBCWait4IBE
       SetPortVal KBC_KEY_DATA, (btScancode or &H80), 1 '写入按键信息,释放键

    End Sub


      定义了上面的过程后,就可以用它来模拟键盘输入了。在窗体模块中添加一个定时器控件,然后加入以下代码:

    Private Sub Form_Load()

    If InitializeWinIo = False Then  
    '用InitializeWinIo函数加载驱动程序,如果成功会返回true,否则返回false
       MsgBox "驱动程序加载失败!"
       Unload Me
    End If
    Timer1.Interval=3000
    Timer1.Enabled=True
    End Sub

    Private Sub Form_Unload(Cancel As Integer)
    ShutdownWinIo '程序结束时记得用ShutdownWinIo函数卸载驱动程序
    End Sub

    Private Sub Timer1_Timer()
    Dim VK_A as Long = &H41
    MyKeyDown VK_A  
    MyKeyUp VK_A    '模拟按下并释放A键
    End Sub

      运行上面的程序,就会每隔3秒钟模拟按下一次A键,试试看,怎么样,是不是对所有程序都有效果了?

    需要注意的问题:

      要在VB的调试模式下使用WINIO,需要把那3个文件拷贝到VB的安装目录中。
      键盘上有些键属于扩展键(比如键盘上的方向键就是扩展键),对于扩展键不应该用上面的MyKeyDown和MyKeyUp过程来模拟,可以使用下面的2个过程来准确模拟扩展键:

    QUOTE:
    Sub MyKeyDownEx(ByVal vKeyCoad As Long)    '模拟扩展键按下,参数vKeyCoad是扩展键的虚拟码
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)

       KBCWait4IBE    '等待键盘缓冲区为空
       SetPortVal KBC_KEY_CMD, &HD2, 1    '发送键盘写入命令
       KBCWait4IBE
       SetPortVal KBC_KEY_DATA, &HE0, 1 '写入扩展键标志信息

       KBCWait4IBE    '等待键盘缓冲区为空
       SetPortVal KBC_KEY_CMD, &HD2, 1    '发送键盘写入命令
       KBCWait4IBE
       SetPortVal KBC_KEY_DATA, btScancode, 1 '写入按键信息,按下键
    End Sub

    Sub MyKeyUpEx(ByVal vKeyCoad As Long)    '模拟扩展键弹起
    Dim btScancode As Long
    btScancode = MapVirtualKey(vKeyCoad, 0)

       KBCWait4IBE    '等待键盘缓冲区为空
       SetPortVal KBC_KEY_CMD, &HD2, 1    '发送键盘写入命令
       KBCWait4IBE
       SetPortVal KBC_KEY_DATA, &HE0, 1 '写入扩展键标志信息
      
       KBCWait4IBE    '等待键盘缓冲区为空
       SetPortVal KBC_KEY_CMD, &HD2, 1    '发送键盘写入命令
       KBCWait4IBE
       SetPortVal KBC_KEY_DATA, (btScancode or &H80), 1 '写入按键信息,释放键
      
    End Sub

      还应该注意的是,如果要从扩展键转换到普通键,那么普通键的KeyDown事件应该发送两次。也就是说,如果我想模拟先按下一个扩展键,再按下一个普通键,那么就应该向端口发送两次该普通键被按下的信息。比如,我想模拟先按下左方向键,再按下空格键这个事件,由于左方向键是扩展键,空格键是普通键,那么流程就应该是这样的:

    MyKeyDownEx VK_LEFT    '按下左方向键
    Sleep 200          '延时200毫秒
    MyKeyUpEx VK_LEFT    '释放左方向键

    Sleep 500
    MyKeyDown VK_SPACE    '按下空格键,注意要发送两次
    MyKeyDown VK_SPACE
    Sleep 200
    MyKeyUp VK_SPACE    '释放空格键