汇编常用API函数
- 格式:doc
- 大小:130.00 KB
- 文档页数:18
目录WinAPI: waveInAddBuffer - 向波形输入设备发送一个输入缓冲区 (2)WinAPI: waveInGetPosition - 获取当前输入设备的输入位置 (3)WinAPI: waveInGetNumDevs - 获取波形输入设备的数目 (4)WinAPI: waveInGetID - 获取输入设备ID (4)WinAPI: waveInClose - 关闭指定的波形输入设备 (4)WinAPI: waveInGetDevCaps - 查询输入设备的性能 (5)WinAPI: waveInGetErrorText - 根据错误号得到错误描述 (6)WinAPI: waveInMessage - 向波形输入设备发送一条消息 (6)WinAPI: waveInOpen - 打开波形输入设备 (6)WinAPI: waveInPrepareHeader - 为波形输入准备一个缓冲区 (8)WinAPI: waveInReset - 重置输入 (9)WinAPI: waveInStart - 启动输入 (9)WinAPI: waveInStop - 停止输入 (9)WinAPI: waveInUnprepareHeader - 清除由waveInPrepareHeader 完成的准备 (10)WinAPI: waveOutBreakLoop - 跳出循环 (11)WinAPI: waveOutClose - 关闭设备 (12)WinAPI: waveOutGetDevCaps - 查询输出设备的性能 (12)WinAPI: waveOutGetID - 获取输出设备ID (13)WinAPI: waveOutGetNumDevs - 获取波形输出设备的数目 (13)WinAPI: waveOutGetPitch - 获取输出设备当前的音调设置(音高的倍数值) (14)WinAPI: waveOutGetPlaybackRate - 获取输出设备当前的播放速度设置(默认速度值的倍数) (14)WinAPI: waveOutGetPosition - 获取输出设备当前的播放位置 (15)WinAPI: waveOutGetVolume - 获取输出设备当前的音量设置 (16)WinAPI: waveOutMessage - 向波形输出设备发送一条消息 (16)WinAPI: waveOutOpen - 打开波形输出设备 (16)WinAPI: waveOutPause - 暂停播放 (18)WinAPI: waveOutPrepareHeader - 准备一个波形数据块用于播放 (18)WinAPI: waveOutReset - 重置输出 (19)WinAPI: waveOutRestart - 重新启动一个被暂停的输出设备 (19)WinAPI: waveOutSetPitch - 设置输出设备的音调设置(音高的倍数值) (20)WinAPI: waveOutGetPlaybackRate - 设置输出设备的播放速度(默认速度值的倍数) (20)WinAPI: waveOutUnprepareHeader - 清除由waveOutPrepareHeader 完成的准备 (21)WinAPI: waveOutWrite - 向输出设备发送一个数据块 (22){合并两个Wav 文件的函数} (23)合并两个Wav 文件流的函数- 回复"刘文强" 的问题 (25)操作Wave 文件(1): 关于Wave 文件的基础知识与文件格式 (28)操作Wave 文件(2): 判断一个文件是否是Wave 文件 (30)操作Wave 文件(3): 接触mmio 系列函数 (33)操作Wave 文件(4): 获取Wave 文件主块与子块的信息 (35)操作Wave 文件(5): 获取Wave 文件的格式信息 (38)操作Wave 文件(6): 获取Wave 文件的波形数据 (40)操作Wave 文件(7): 建立一个空的Wave 文件(三种方法) (42)操作Wave 文件(8): 使用TMediaPlayer 录制wav 文件 (46)操作Wave 文件(9): 使用waveOut... 函数播放wav 文件. (48)操作Wave 文件(10): 输入输出设备与格式支持 (54)操作Wave 文件(11): 使用waveIn...函数录制wav 文件 (56)操作Wave 文件(12): 使用waveOut...重复播放wav 文件. (63)操作Wave 文件(13): waveOutGetVolume、waveOutSetVolume (66)操作Wave 文件(14): waveOutSetPlaybackRate、waveOutSetPitch (71)操作Wave 文件(15): 合并与剪裁wav 文件 (77)WinAPI: waveInAddBuffer - 向波形输入设备发送一个输入缓冲区提示:缓冲区写满后送回应用程序.在缓冲区给waveInAddBuffer 前, 先要调用waveInPrepareHeader 准备; 还要调用GlobalAlloc 给TWaveHdr 和其中lpData 指向的缓冲区分配内存(使用GMEM_MOVEABLE、GMEM_SHARE), 并用GlobalLock 锁定.--------------------------------------------------------------------------------//声明:waveInAddBuffer(hWaveIn: HWAVEIN; {波形输入设备句柄}lpWaveInHdr: PWaveHdr; {TWaveHdr 结构的指针}uSize: UINT {TWaveHdr 结构大小}): MMRESULT; {成功返回0; 可能的错误值如下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}WAVERR_UNPREPARED = 34; {没准备好缓冲区}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}//TWaveHdr 是wavehdr_tag 结构的重定义wavehdr_tag = recordlpData: PChar; {指向波形数据缓冲区}dwBufferLength: DWORD; {波形数据缓冲区的长度}dwBytesRecorded: DWORD; {若首部用于输入, 指出缓冲区中的数据量}dwUser: DWORD; {指定用户的32位数据}dwFlags: DWORD; {缓冲区标志}dwLoops: DWORD; {循环播放次数, 仅用于输出缓冲区}lpNext: PWaveHdr; {保留}reserved: DWORD; {保留}end;//dwFlags 的可选值:WHDR_DONE = $00000001; {设备已使用完缓冲区, 并返回给程序}WHDR_PREPARED = $00000002; {waveInPrepareHeader 或waveOutPrepareHeader 已将缓冲区准备好}WHDR_BEGINLOOP = $00000004; {缓冲区是循环中的第一个缓冲区, 仅用于输出}WHDR_ENDLOOP = $00000008; {缓冲区是循环中的最后一个缓冲区, 仅用于输出} WHDR_INQUEUE = $00000010; { reserved for driver }WinAPI: waveInGetPosition - 获取当前输入设备的输入位置//声明:waveInGetPosition(hWaveIn: HWAVEIN; {设备句柄}lpInfo: PMMTime; {TMMTime 结构的指针}uSize: UINT {TMMTime 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}//TMMTime 是mmtime_tag 结构的重定义:mmtime_tag = recordcase wType: UINT ofTIME_MS: (ms: DWORD); {毫米}TIME_SAMPLES:(sample: DWORD); {波形音频取样数}TIME_BYTES: (cb: DWORD); {波形音频字节数(字节偏移量)}TIME_TICKS: (ticks: DWORD); {TICK 数}TIME_SMPTE:( {动画及电视协会的SMPTE 时间, 是个内嵌结构}hour: Byte; {时}min: Byte; {分}sec: Byte; {秒}frame: Byte; {帧}fps: Byte; {每秒帧数}dummy: Byte; {填充字节(为对齐而用)}pad: array[0..1] of Byte); {}TIME_MIDI : (songptrpos: DWORD); {MIDI 时间}end;//使用TMMTime 结构前, 应先指定TMMTime.wType :TIME_MS = $0001; {默认; 打开或复位时将回到此状态}TIME_SAMPLES = $0002;TIME_BYTES = $0004;TIME_SMPTE = $0008;TIME_MIDI = $0010;TIME_TICKS = $0020;WinAPI: waveInGetNumDevs - 获取波形输入设备的数目//声明:waveInGetNumDevs: UINT; {无参数; 返回波形输入设备的数目}WinAPI: waveInGetID - 获取输入设备ID//声明:waveInGetID(hWaveIn: HWAVEIN; {获取输入设备句柄}lpuDeviceID: PUINT {接受ID 的变量的指针}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveInClose - 关闭指定的波形输入设备提示: 若waveInAddBuffer 送出的缓冲区未返回则失败; 可用waveInReset 放弃所有未用完的缓冲区.--------------------------------------------------------------------------------//声明:waveInClose(hWaveIn: HWAVEIN {设备句柄; 函数若成功返回, 句柄则不再有效}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}WAVERR_STILLPLAYING = 33; {缓冲区还在队列中}WinAPI: waveInGetDevCaps - 查询输入设备的性能//声明:waveInGetDevCaps(hwo: HWAVEOUT; {输入设备ID; HWAVEIN ?}lpCaps: PWaveInCaps; {TWaveInCaps 结构的指针, 用于接受设备信息}uSize: UINT {TWaveInCaps 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_BADDEVICEID = 2; {设备ID超界}MMSYSERR_NODRIVER = 6; {没有安装驱动程序}//TWaveInCaps 是tagWAVEINCAPSA 结构的重定义:tagWAVEINCAPSA = recordwMid: Word; {制造商ID}wPid: Word; {产品ID}vDriverVersion: MMVERSION; {版本号; 高字节是主版本号, 低字节是次版本号}szPname: array[0..MAXPNAMELEN-1] of AnsiChar; {产品名称}dwFormats: DWORD; {支持的格式}wChannels: Word; {单声道(1)还是立体声(2)} wReserved1: Word; { structure packing }end;//dwFormats:WAVE_INVALIDFORMAT = $00000000; {invalid format}WAVE_FORMAT_1M08 = $00000001; {11.025 kHz, Mono, 8-bit }WAVE_FORMAT_1S08 = $00000002; {11.025 kHz, Stereo, 8-bit }WAVE_FORMAT_1M16 = $00000004; {11.025 kHz, Mono, 16-bit}WAVE_FORMAT_1S16 = $00000008; {11.025 kHz, Stereo, 16-bit}WAVE_FORMAT_2M08 = $00000010; {22.05 kHz, Mono, 8-bit }WAVE_FORMAT_2S08 = $00000020; {22.05 kHz, Stereo, 8-bit }WAVE_FORMAT_2M16 = $00000040; {22.05 kHz, Mono, 16-bit}WAVE_FORMAT_2S16 = $00000080; {22.05 kHz, Stereo, 16-bit}WAVE_FORMAT_4M08 = $00000100; {44.1 kHz, Mono, 8-bit }WAVE_FORMAT_4S08 = $00000200; {44.1 kHz, Stereo, 8-bit }WAVE_FORMAT_4M16 = $00000400; {44.1 kHz, Mono, 16-bit}WAVE_FORMAT_4S16 = $00000800; {44.1 kHz, Stereo, 16-bit}WinAPI: waveInGetErrorText - 根据错误号得到错误描述提示: 错误文本的长度一般不超过MAXERRORLENGTH = 128; 如果缓冲区太小, 文本会被截断.--------------------------------------------------------------------------------//声明:waveInGetErrorText(mmrError: MMRESULT; {错误号}lpText: PChar; {缓冲区}uSize: UINT {缓冲区大小}): MMRESULT; {成功返回0; 失败再返回错误号, 可能的错误是:}MMSYSERR_BADERRNUM = 9; {错误号超界}WinAPI: waveInMessage - 向波形输入设备发送一条消息//声明:waveInMessage(hWaveIn: HWAVEIN; {设备句柄}uMessage: UINT; {消息}dw1: DWORD {消息参数}dw2: DWORD {消息参数}): MMRESULT; {将由设备给返回值}WinAPI: waveInOpen - 打开波形输入设备提示: 因为其中的回调函数是在中断时间内访问的, 必须在DLL 中; 要访问的数据都必须是在固定的数据段中; 除了PostMessagetimeGetSystemTimetimeGetTimetimeSetEventtimeKillEventmidiOutShortMsgmidiOutLongMsgOutputDebugString 外, 也不能有其他系统调用.--------------------------------------------------------------------------------//声明:waveInOpen(lphWaveIn: PHWAVEIN; {用于返回设备句柄的指针; 如果dwFlags=WAVE_FORMAT_QUERY, 这里应是nil}uDeviceID: UINT; {设备ID; 可以指定为: WAVE_MAPPER, 这样函数会根据给定的波形格式选择合适的设备}lpFormatEx: PWaveFormatEx; {TWaveFormat 结构的指针; TWaveFormat 包含要申请的波形格式}dwCallback: DWORD {回调函数地址或窗口句柄; 若不使用回调机制, 设为nil} dwInstance: DWORD {给回调函数的实例数据; 不用于窗口}dwFlags: DWORD {打开选项}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_BADDEVICEID = 2; {设备ID超界}MMSYSERR_ALLOCATED = 4; {指定的资源已被分配}MMSYSERR_NODRIVER = 6; {没有安装驱动程序}MMSYSERR_NOMEM = 7; {不能分配或锁定内存}WAVERR_BADFORMAT = 32; {设备不支持请求的波形格式}//TWaveFormatEx 结构:TWaveFormatEx = packed recordwFormatTag: Word; {指定格式类型; 默认WAVE_FORMAT_PCM = 1;} nChannels: Word; {指出波形数据的声道数; 单声道为1, 立体声为2} nSamplesPerSec: DWORD; {指定采样频率(每秒的样本数)}nAvgBytesPerSec: DWORD; {指定数据传输的传输速率(每秒的字节数)}nBlockAlign: Word; {指定块对齐(每个样本的字节数), 块对齐是数据的最小单位} wBitsPerSample: Word; {采样大小(字节), 每个样本的量化位数}cbSize: Word; {附加信息的字节大小}end;{16 位立体声PCM 的块对齐是4 字节(每个样本2字节, 2个通道)}//打开选项dwFlags 的可选值:WAVE_FORMAT_QUERY = $0001; {只是判断设备是否支持给定的格式, 并不打开} WAVE_ALLOWSYNC = $0002; {当是同步设备时必须指定}CALLBACK_WINDOW = $00010000; {当dwCallback 是窗口句柄时指定}CALLBACK_FUNCTION = $00030000; {当dwCallback 是函数指针时指定}//如果选择窗口接受回调信息, 可能会发送到窗口的消息有:MM_WIM_OPEN = $3BE;MM_WIM_CLOSE = $3BF;MM_WIM_DATA = $3C0;//如果选择函数接受回调信息, 可能会发送给函数的消息有:WIM_OPEN = MM_WIM_OPEN;WIM_CLOSE = MM_WIM_CLOSE;WIM_DATA = MM_WIM_DA TA;WinAPI: waveInPrepareHeader - 为波形输入准备一个缓冲区提示: 必须调用GlobalAlloc 给TWaveHdr 和其中的lpData 指向的缓冲区分配内存(使用GMEM_MOVEABLE、GMEM_SHARE), 并用GlobalLock 锁定.--------------------------------------------------------------------------------//声明:waveInPrepareHeader(hWaveIn: HWAVEIN; {设备句柄}lpWaveInHdr: PWaveHdr; {TWaveHdr 结构的指针}uSize: UINT {TWaveHdr 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NOMEM = 7; {不能分配或锁定内存}MMSYSERR_HANDLEBUSY = 12; {其他线程正在使用该设备}//TWaveHdr 是wavehdr_tag 结构的重定义wavehdr_tag = recordlpData: PChar; {指向波形数据缓冲区}dwBufferLength: DWORD; {波形数据缓冲区的长度}dwBytesRecorded: DWORD; {若TWaveHdr 用于输入, 指出缓冲区中的数据量} dwUser: DWORD; {指定用户的32位数据}dwFlags: DWORD; {缓冲区标志}dwLoops: DWORD; {循环播放次数, 仅用于输出缓冲区}lpNext: PWaveHdr; {保留}reserved: DWORD; {保留}end;//TWaveHdr 中的dwFlags 的可选值:WHDR_DONE = $00000001; {设备已使用完缓冲区, 并返回给程序}WHDR_PREPARED = $00000002; {waveInPrepareHeader 或waveOutPrepareHeader 已将缓冲区准备好}WHDR_BEGINLOOP = $00000004; {缓冲区是循环中的第一个缓冲区, 仅用于输出}WHDR_ENDLOOP = $00000008; {缓冲区是循环中的最后一个缓冲区, 仅用于输出} WHDR_INQUEUE = $00000010; { reserved for driver }WinAPI: waveInReset - 重置输入提示:函数会终止输入, 位置清0; 放弃未处理的缓冲区并返回给程序;TWaveHdr 结构中的dwBytesRecorded 将包含实际数据的长度.--------------------------------------------------------------------------------//声明:waveInReset(hWaveIn: HWAVEIN {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveInStart - 启动输入//声明:waveInStart(hWaveIn: HWAVEIN {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveInStop - 停止输入提示: 如果未启动则调用无效, 但也返回0; 缓冲区会被返回, TWaveHdr 结构中的dwBytesRecorded 将包含返回的实际数据的长度.--------------------------------------------------------------------------------//声明:waveInStop(hWaveIn: HWAVEIN {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveInUnprepareHeader - 清除由waveInPrepareHeader 完成的准备提示:设备写满缓冲区返回给程序后, 须调用此函数;释放(GlobalFree)缓冲区前, 须调用此函数;取消一个尚未准备的缓冲区将无效, 但函数返回0--------------------------------------------------------------------------------//声明:waveInUnprepareHeader(hWaveIn: HWAVEIN; {设备句柄}lpWaveInHdr: PWaveHdr; {TWaveHdr 结构的指针}uSize: UINT {TWaveHdr 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WAVERR_STILLPLAYING = 33; {缓冲区还在队列中}//TWaveHdr 是wavehdr_tag 结构的重定义wavehdr_tag = recordlpData: PChar; {指向波形数据缓冲区}dwBufferLength: DWORD; {波形数据缓冲区的长度}dwBytesRecorded: DWORD; {若首部用于输入, 指出缓冲区中的数据量}dwUser: DWORD; {指定用户的32位数据}dwFlags: DWORD; {缓冲区标志}dwLoops: DWORD; {循环播放次数, 仅用于输出缓冲区}lpNext: PWaveHdr; {保留}reserved: DWORD; {保留}end;//TWaveHdr 中的dwFlags 的可选值:WHDR_DONE = $00000001; {设备已使用完缓冲区, 并返回给程序}WHDR_PREPARED = $00000002; {waveInPrepareHeader 或waveOutPrepareHeader 已将缓冲区准备好}WHDR_BEGINLOOP = $00000004; {缓冲区是循环中的第一个缓冲区, 仅用于输出}WHDR_ENDLOOP = $00000008; {缓冲区是循环中的最后一个缓冲区, 仅用于输出} WHDR_INQUEUE = $00000010; { reserved for driver }WinAPI: waveOutBreakLoop - 跳出循环提示:循环是由saveOutWrite 传递的TWaveHdr 结构的dwLoop 和dwFlags 控制的;dwFlags 的WHDR_BEGINLOOP、WHDR_ENDLOOP 标识循环的开始和结束数据块;在同一数据块上循环, 应同时指定这两个标志;循环次数dwLoops 应该在开始块上指定;循环终止前, 组成循环体的块一定要播放完;当无播放内容或循环设定失败时, 函数也能返回0.--------------------------------------------------------------------------------//声明:waveOutBreakLoop(hWaveOut: HWAVEOUT {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}//TWaveHdr 是wavehdr_tag 结构的重定义wavehdr_tag = recordlpData: PChar; {指向波形数据缓冲区}dwBufferLength: DWORD; {波形数据缓冲区的长度}dwBytesRecorded: DWORD; {若首部用于输入, 指出缓冲区中的数据量}dwUser: DWORD; {指定用户的32位数据}dwFlags: DWORD; {缓冲区标志}dwLoops: DWORD; {循环播放次数, 仅用于输出缓冲区}lpNext: PWaveHdr; {保留}reserved: DWORD; {保留}end;//TWaveHdr 中的dwFlags 的可选值:WHDR_DONE = $00000001; {设备已使用完缓冲区, 并返回给程序}WHDR_PREPARED = $00000002; {waveInPrepareHeader 或waveOutPrepareHeader 已将缓冲区准备好}WHDR_BEGINLOOP = $00000004; {缓冲区是循环中的第一个缓冲区, 仅用于输出}WHDR_ENDLOOP = $00000008; {缓冲区是循环中的最后一个缓冲区, 仅用于输出} WHDR_INQUEUE = $00000010; {保留(给设备)}WinAPI: waveOutClose - 关闭设备提示: 若正在播放, 应先调用waveOutReset 终止播放, 然后再关闭, 不然会失败.--------------------------------------------------------------------------------//声明:waveOutClose(hWaveOut: HWAVEOUT {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WAVERR_STILLPLAYING = 33; {缓冲区还在队列中}WinAPI: waveOutGetDevCaps - 查询输出设备的性能//声明:waveOutGetDevCaps(uDeviceID: UINT; {输出设备ID}lpCaps: PWaveOutCaps; {TWaveOutCaps 结构的指针, 用于接受设备信息}uSize: UINT): MMRESULT; {TWaveOutCaps 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_BADDEVICEID = 2; {设备ID超界}MMSYSERR_NODRIVER = 6; {没有安装驱动程序}//TWaveOutCaps 是tagWAVEOUTCAPSA 结构的重定义:tagWAVEOUTCAPSA = recordwMid: Word; {制造商ID}wPid: Word; {产品ID}vDriverVersion: MMVERSION; {版本号; 高字节是主版本号, 低字节是次版本号}szPname: array[0..MAXPNAMELEN-1] of AnsiChar; {产品名称}dwFormats: DWORD; {支持的格式}wChannels: Word; {单声道(1)还是立体声(2)} dwSupport: DWORD; {其他功能}end;//dwFormats:WAVE_INVALIDFORMAT = $00000000; {invalid format}WAVE_FORMAT_1M08 = $00000001; {11.025 kHz, Mono, 8-bit }WAVE_FORMAT_1S08 = $00000002; {11.025 kHz, Stereo, 8-bit }WAVE_FORMAT_1M16 = $00000004; {11.025 kHz, Mono, 16-bit}WAVE_FORMAT_1S16 = $00000008; {11.025 kHz, Stereo, 16-bit}WAVE_FORMAT_2M08 = $00000010; {22.05 kHz, Mono, 8-bit }WAVE_FORMAT_2S08 = $00000020; {22.05 kHz, Stereo, 8-bit }WAVE_FORMAT_2M16 = $00000040; {22.05 kHz, Mono, 16-bit}WAVE_FORMAT_2S16 = $00000080; {22.05 kHz, Stereo, 16-bit}WAVE_FORMAT_4M08 = $00000100; {44.1 kHz, Mono, 8-bit }WAVE_FORMAT_4S08 = $00000200; {44.1 kHz, Stereo, 8-bit }WAVE_FORMAT_4M16 = $00000400; {44.1 kHz, Mono, 16-bit}WAVE_FORMAT_4S16 = $00000800; {44.1 kHz, Stereo, 16-bit}//dwSupport:WAVECAPS_PITCH = $0001; {支持音调控制}WAVECAPS_PLAYBACKRATE = $0002; {支持播放速度控制}WAVECAPS_VOLUME = $0004; {支持音量控制}WAVECAPS_LRVOLUME = $0008; {支持左右声道音量控制} WAVECAPS_SYNC = $0010; {}WAVECAPS_SAMPLEACCURATE = $0020; {}WAVECAPS_DIRECTSOUND = $0040; {}WinAPI: waveOutGetID - 获取输出设备ID//声明:waveOutGetID(hWaveOut: HWAVEOUT; {设备句柄}lpuDeviceID: PUINT {接受ID 的变量的指针}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutGetNumDevs - 获取波形输出设备的数目//声明:waveOutGetNumDevs: UINT; {无参数; 返回波形输出设备的数目}WinAPI: waveOutGetPitch - 获取输出设备当前的音调设置(音高的倍数值)提示:参数lpdwPitch 虽然指向的是4 字节的正整数, 但表示的是个小数;两个高位表示整数部分, 两个低位表示小数部分;$8000 表示一半, $4000 表示四分之一;譬如: $00010000 表示1.0, 说明音高没变; $000F8000, 表示15.5 倍;修改音高不会改变播放速度、采样速度和播放时间, 但不是所有设备都支持.--------------------------------------------------------------------------------//声明:waveOutGetPitch(hWaveOut: HWAVEOUT; {设备句柄}lpdwPitch: PDWORD {存放音高值的变量的指针}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NOTSUPPORTED = 8; {设备不支持}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutGetPlaybackRate - 获取输出设备当前的播放速度设置(默认速度值的倍数)提示:参数lpdwRate 虽然指向的是4 字节的正整数, 但表示的是个小数;两个高位表示整数部分, 两个低位表示小数部分;$8000 表示一半, $4000 表示四分之一;譬如: $00010000 表示1.0, 说明速度没有改变变; $000F8000, 表示15.5 倍;修改播放速度不会改变采样速度, 但肯定会改变播放时间.--------------------------------------------------------------------------------//声明:waveOutGetPlaybackRate(hWaveOut: HWAVEOUT; {设备句柄}lpdwRate: PDWORD {存放速度值的变量的指针}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NOTSUPPORTED = 8; {设备不支持}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutGetPosition - 获取输出设备当前的播放位置//声明:waveOutGetPosition(hWaveOut: HWAVEOUT; {设备句柄}lpInfo: PMMTime; {TMMTime 结构的指针, 用于返回播放位置}uSize: UINT {TMMTime 结构的大小, 以字节为单位}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}//TMMTime 是mmtime_tag 结构的重定义:mmtime_tag = recordcase wType: UINT ofTIME_MS: (ms: DWORD); {毫米}TIME_SAMPLES:(sample: DWORD); {波形音频取样数}TIME_BYTES: (cb: DWORD); {波形音频字节数(字节偏移量)}TIME_TICKS: (ticks: DWORD); {TICK 数}TIME_SMPTE:( {动画及电视协会的SMPTE 时间, 是个内嵌结构}hour: Byte; {时}min: Byte; {分}sec: Byte; {秒}frame: Byte; {帧}fps: Byte; {每秒帧数}dummy: Byte; {填充字节(为对齐而用)}pad: array[0..1] of Byte); {}TIME_MIDI : (songptrpos: DWORD); {MIDI 时间}end;//使用TMMTime 结构前, 应先指定TMMTime.wType :TIME_MS = $0001; {默认; 打开或复位时将回到此状态}TIME_SAMPLES = $0002;TIME_BYTES = $0004;TIME_SMPTE = $0008;TIME_MIDI = $0010;TIME_TICKS = $0020;WinAPI: waveOutGetVolume - 获取输出设备当前的音量设置提示:参数lpdwVolume 的两低位字节存放左声道音量, 两高位字节存放右声道音量; $FFFF、$0000 分别表示最大与最小音量;如不支持立体声, 两低位字节存放单声道音量.--------------------------------------------------------------------------------//声明:waveOutGetVolume(hwo: HWAVEOUT; {设备句柄}lpdwVolume: PDWORD {存放音量值的变量的指针}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NODRIVER = 6; {没有安装驱动程序}MMSYSERR_NOTSUPPORTED = 8; {设备不支持}WinAPI: waveOutMessage - 向波形输出设备发送一条消息//声明:waveOutMessage(hWaveOut: HWAVEOUT; {设备句柄}uMessage: UINT; {消息}dw1: DWORD {消息参数}dw2: DWORD {消息参数}): Longint; {将由设备给返回值}WinAPI: waveOutOpen - 打开波形输出设备提示: 因为其中的回调函数是在中断时间内访问的, 必须在DLL 中; 要访问的数据都必须是在固定的数据段中; 除了PostMessagetimeGetSystemTimetimeGetTimetimeSetEventtimeKillEventmidiOutShortMsgmidiOutLongMsgOutputDebugString 外, 也不能有其他系统调用.--------------------------------------------------------------------------------//声明:waveOutOpen(lphWaveOut: PHWaveOut; {用于返回设备句柄的指针; 如果dwFlags=WAVE_FORMAT_QUERY, 这里应是nil}uDeviceID: UINT; {设备ID; 可以指定为: WAVE_MAPPER, 这样函数会根据给定的波形格式选择合适的设备}lpFormat: PWaveFormatEx; {TWaveFormat 结构的指针; TWaveFormat 包含要申请的波形格式}dwCallback: DWORD {回调函数地址或窗口句柄; 若不使用回调机制, 设为nil} dwInstance: DWORD {给回调函数的实例数据; 不用于窗口}dwFlags: DWORD {打开选项}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_BADDEVICEID = 2; {设备ID超界}MMSYSERR_ALLOCATED = 4; {指定的资源已被分配}MMSYSERR_NODRIVER = 6; {没有安装驱动程序}MMSYSERR_NOMEM = 7; {不能分配或锁定内存}WAVERR_BADFORMAT = 32; {设备不支持请求的波形格式}//TWaveFormatEx 结构:TWaveFormatEx = packed recordwFormatTag: Word; {指定格式类型; 默认WAVE_FORMAT_PCM = 1;} nChannels: Word; {指出波形数据的通道数; 单声道为1, 立体声为2} nSamplesPerSec: DWORD; {指定样本速率(每秒的样本数)}nAvgBytesPerSec: DWORD; {指定数据传输的平均速率(每秒的字节数)}nBlockAlign: Word; {指定块对齐(单位字节), 块对齐是数据的最小单位} wBitsPerSample: Word; {采样大小(字节)}cbSize: Word; {附加信息大小; PCM 格式没这个字段}end;{16 位立体声PCM 的块对齐是4 字节(每个样本2字节, 2个通道)}//打开选项dwFlags 的可选值:WAVE_FORMAT_QUERY = $0001; {只是判断设备是否支持给定的格式, 并不打开} WAVE_ALLOWSYNC = $0002; {当是同步设备时必须指定}CALLBACK_WINDOW = $00010000; {当dwCallback 是窗口句柄时指定}CALLBACK_FUNCTION = $00030000; {当dwCallback 是函数指针时指定}//如果选择窗口接受回调信息, 可能会发送到窗口的消息有:MM_WOM_OPEN = $3BB;MM_WOM_CLOSE = $3BC;MM_WOM_DONE = $3BD;//如果选择函数接受回调信息, 可能会发送给函数的消息有:WOM_OPEN = MM_WOM_OPEN;WOM_CLOSE = MM_WOM_CLOSE;WOM_DONE = MM_WOM_DONE;WinAPI: waveOutPause - 暂停播放提示: 暂停后会保存当前位置, 可以用waveOutRestart 从当前位置恢复播放. //声明: waveOutPause(hWaveOut: HWAVEOUT {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutPrepareHeader - 准备一个波形数据块用于播放提示: 必须调用GlobalAlloc 给TWaveHdr 和其中的lpData 指向的缓冲区分配内存(使用GMEM_MOVEABLE、GMEM_SHARE), 并用GlobalLock 锁定.--------------------------------------------------------------------------------//声明:waveOutPrepareHeader(hWaveOut: HWAVEOUT; {设备句柄}lpWaveOutHdr: PWaveHdr; {TWaveHdr 结构的指针}uSize: UINT {TWaveHdr 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NOMEM = 7; {不能分配或锁定内存}MMSYSERR_HANDLEBUSY = 12; {其他线程正在使用该设备}//TWaveHdr 是wavehdr_tag 结构的重定义wavehdr_tag = recordlpData: PChar; {指向波形数据缓冲区}dwBufferLength: DWORD; {波形数据缓冲区的长度}dwBytesRecorded: DWORD; {若首部用于输入, 指出缓冲区中的数据量}dwUser: DWORD; {指定用户的32位数据}dwFlags: DWORD; {缓冲区标志}dwLoops: DWORD; {循环播放次数, 仅用于输出缓冲区}lpNext: PWaveHdr; {保留}reserved: DWORD; {保留}end;//TWaveHdr 中的dwFlags 的可选值:WHDR_DONE = $00000001; {设备已使用完缓冲区, 并返回给程序}WHDR_PREPARED = $00000002; {waveInPrepareHeader 或waveOutPrepareHeader 已将缓冲区准备好}WHDR_BEGINLOOP = $00000004; {缓冲区是循环中的第一个缓冲区, 仅用于输出}WHDR_ENDLOOP = $00000008; {缓冲区是循环中的最后一个缓冲区, 仅用于输出} WHDR_INQUEUE = $00000010; { reserved for driver }WinAPI: waveOutReset - 重置输出提示: 函数会终止输入, 位置清0; 放弃未处理的缓冲区并返回给程序.--------------------------------------------------------------------------------//声明:waveOutReset(hWaveOut: HWAVEOUT {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutRestart - 重新启动一个被暂停的输出设备提示: 当输出设备未暂停时调用该函数无效, 但也返回0--------------------------------------------------------------------------------//声明:waveOutRestart(hWaveOut: HWAVEOUT {设备句柄}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutSetPitch - 设置输出设备的音调设置(音高的倍数值)提示:参数dwPitch 虽然是 4 字节的正整数, 但表示的是个小数;两个高位表示整数部分, 两个低位表示小数部分;$8000 表示一半, $4000 表示四分之一;譬如: $00010000 表示1.0, 说明音高没变; $000F8000, 表示15.5 倍;修改音高不会改变播放速度、采样速度和播放时间, 但不是所有设备都支持.--------------------------------------------------------------------------------//声明:waveOutSetPitch(hWaveOut: HWAVEOUT; {设备句柄}dwPitch: DWORD {存放音高值的变量}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NOTSUPPORTED = 8; {设备不支持}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutGetPlaybackRate - 设置输出设备的播放速度(默认速度值的倍数)提示:参数dwRate 虽然是 4 字节的正整数, 但表示的是个小数;两个高位表示整数部分, 两个低位表示小数部分;$8000 表示一半, $4000 表示四分之一;譬如: $00010000 表示1.0, 说明速度没有改变变; $000F8000, 表示15.5 倍;修改播放速度不会改变采样速度, 但肯定会改变播放时间.--------------------------------------------------------------------------------//声明:waveOutSetPlaybackRate(hWaveOut: HWAVEOUT; {设备句柄}dwRate: DWORD {存放速度值的变量}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_NOTSUPPORTED = 8; {设备不支持}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WinAPI: waveOutUnprepareHeader - 清除由waveOutPrepareHeader 完成的准备提示:设备使用完数据块后, 须调用此函数;释放(GlobalFree)缓冲区前, 须调用此函数;取消一个尚未准备的缓冲区将无效, 但函数返回0--------------------------------------------------------------------------------//声明:waveOutUnprepareHeader(hWaveOut: HWAVEOUT; {设备句柄}lpWaveOutHdr: PWaveHdr; {TWaveHdr 结构的指针}uSize: UINT {TWaveHdr 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WAVERR_STILLPLAYING = 33; {缓冲区还在队列中}//TWaveHdr 是wavehdr_tag 结构的重定义wavehdr_tag = recordlpData: PChar; {指向波形数据缓冲区}dwBufferLength: DWORD; {波形数据缓冲区的长度}dwBytesRecorded: DWORD; {若首部用于输入, 指出缓冲区中的数据量}dwUser: DWORD; {指定用户的32位数据}dwFlags: DWORD; {缓冲区标志}dwLoops: DWORD; {循环播放次数, 仅用于输出缓冲区}lpNext: PWaveHdr; {保留}reserved: DWORD; {保留}end;//TWaveHdr 中的dwFlags 的可选值:WHDR_DONE = $00000001; {设备已使用完缓冲区, 并返回给程序}WHDR_PREPARED = $00000002; {waveInPrepareHeader 或waveOutPrepareHeader 已将缓冲区准备好}WHDR_BEGINLOOP = $00000004; {缓冲区是循环中的第一个缓冲区, 仅用于输出}WHDR_ENDLOOP = $00000008; {缓冲区是循环中的最后一个缓冲区, 仅用于输出} WHDR_INQUEUE = $00000010; { reserved for driver }WinAPI: waveOutWrite - 向输出设备发送一个数据块提示: 把数据缓冲区传给waveOutWrite 之前, 必须使用waveOutPrepareHeader 准备该缓冲区;若未调用waveOutPause 函数暂停设备, 则第一次把数据块发送给设备时即开始播放.--------------------------------------------------------------------------------//声明:waveOutWrite(hWaveOut: HWAVEOUT; {设备句柄}lpWaveOutHdr: PWaveHdr; {TWaveHdr 结构的指针}uSize: UINT {TWaveHdr 结构大小}): MMRESULT; {成功返回0; 可能的错误值见下:}MMSYSERR_INVALHANDLE = 5; {设备句柄无效}MMSYSERR_HANDLEBUSY = 12; {设备已被另一线程使用}WAVERR_UNPREPARED = 34; {未准备数据块}//TWaveHdr 是wavehdr_tag 结构的重定义wavehdr_tag = recordlpData: PChar; {指向波形数据缓冲区}dwBufferLength: DWORD; {波形数据缓冲区的长度}dwBytesRecorded: DWORD; {若首部用于输入, 指出缓冲区中的数据量}dwUser: DWORD; {指定用户的32位数据}dwFlags: DWORD; {缓冲区标志}dwLoops: DWORD; {循环播放次数, 仅用于输出缓冲区}lpNext: PWaveHdr; {保留}reserved: DWORD; {保留}end;//TWaveHdr 中的dwFlags 的可选值:WHDR_DONE = $00000001; {设备已使用完缓冲区, 并返回给程序}WHDR_PREPARED = $00000002; {waveInPrepareHeader 或waveOutPrepareHeader 已将缓冲区准备好}WHDR_BEGINLOOP = $00000004; {缓冲区是循环中的第一个缓冲区, 仅用于输出}WHDR_ENDLOOP = $00000008; {缓冲区是循环中的最后一个缓冲区, 仅用于输出} WHDR_INQUEUE = $00000010; { reserved for driver }合并两个Wav 文件的函数unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls;typeTForm1 = class(TForm)Button1: TButton;procedure Button1Click(Sender: TObject);end;varForm1: TForm1;implementation{$R *.dfm}{合并两个Wav 文件的函数}function ConWavFile(AWavFile1, AWavFile2, ANewFile: string): Boolean;typeTWavFormat = packed recordChunkID: array[0..3] of AnsiChar; {'RIFF'}ChunkSize: Longword; {size-8}Format: array[0..3] of AnsiChar; {'WAVE'}SubChunk1ID: array[0..3] of AnsiChar; {'fmt '}SubChunk1Size: Longword; {hex10}AudioFormat: Word; {hex 01}NumOfChannels: Word; {1 mono, 2 stereo}SampleRate: Longword; {number of samples/sec}ByteRate: Longword; {samplerate* num of channels*bytes per (mono) sample}BytesperSample: Word; {size of (mono) sample}BitsPerSample: Word; {BytesperSample *8}SubChunk2ID: array[0..3] of AnsiChar; {'data'}SubChunk2Size: Longword; {number of data bytes}end;varvWavFormat1: TWavFormat;vWavFormat2: TWavFormat;vFileHandle1: THandle;vFileHandle2: THandle;vFileStream1: TFileStream;vFileStream2: TFileStream;vChunkSize1, vChunkSize2: Integer;beginResult := False;if not FileExists(AWavFile1) then Exit;if not FileExists(AWavFile2) then Exit;vFileHandle1 := _lopen(PAnsiChar(AnsiString(AWavFile1)), OF_READ or OF_SHARE_DENY_NONE);vFileHandle2 := _lopen(PAnsiChar(AnsiString(AWavFile2)), OF_READ or OF_SHARE_DENY_NONE);if (Integer(vFileHandle1) <= 0) or (Integer(vFileHandle2) <= 0) thenbegin_lclose(vFileHandle1);_lclose(vFileHandle2);Exit;end;vFileStream1 := TFileStream.Create(vFileHandle1);vFileStream2 := TFileStream.Create(vFileHandle2);tryif vFileStream1.Read(vWavFormat1, SizeOf(TWavFormat)) <> SizeOf(TWavFormat) then Exit;if vFileStream2.Read(vWavFormat2, SizeOf(TWavFormat)) <> SizeOf(TWavFormat) then Exit;if vWavFormat1.ChunkID <> 'RIFF' then Exit;if vWavFormat1.SubChunk2ID <> 'data' then Exit;vChunkSize1 := vWavFormat1.SubChunk2Size;vChunkSize2 := vWavFormat2.SubChunk2Size;vWavFormat1.ChunkSize := 0;vWavFormat1.SubChunk2Size := 0;vWavFormat2.ChunkSize := 0;vWavFormat2.SubChunk2Size := 0;if not CompareMem(@vWavFormat1, @vWavFormat2, SizeOf(TWavFormat)) then Exit; {格式不同}with TMemoryStream.Create do tryvWavFormat1.ChunkSize := vChunkSize1 + vChunkSize2 + SizeOf(vWavFormat1) - 8;vWavFormat1.SubChunk2Size := vChunkSize1 + vChunkSize2;Write(vWavFormat1, SizeOf(TWavFormat));CopyFrom(vFileStream1, vChunkSize1);CopyFrom(vFileStream2, vChunkSize2);trySaveToFile(ANewFile);except。
c语言调用汇编语言函数的方式以C语言调用汇编语言函数的方式在编程中,有时需要使用汇编语言来实现一些特定的功能。
但是,由于汇编语言复杂且难以维护,因此我们通常使用高级语言如C语言来编写主要的程序代码。
在这种情况下,我们需要一种方法来调用汇编语言函数,以便在程序中使用它们。
本文将介绍如何使用C 语言调用汇编语言函数。
1. 定义汇编函数我们需要编写一个汇编函数来执行我们需要的操作。
汇编函数可以使用任何汇编语言,但是必须遵循特定的调用约定。
在x86架构中,调用约定指定了函数参数的传递方式、寄存器的使用方式以及栈的使用方式。
以Windows操作系统为例,Windows API使用的是stdcall调用约定,即参数从右往左依次压入栈中,返回值放在EAX寄存器中。
因此,我们需要在编写汇编函数时遵循这个调用约定。
下面是一个使用汇编语言实现计算阶乘的例子:```global factorial ; 导出函数符号section .textfactorial:push ebp ; 保存调用函数的栈帧指针 mov ebp, esp ; 设置当前栈帧指针mov eax, [ebp+8] ; 获取函数参数cmp eax, 1 ; 判断参数是否为1jle .base_case ; 如果是,则返回1dec eax ; 否则,计算(n-1)!push eax ; 保存(n-1)的值call factorial ; 递归调用阶乘函数pop ecx ; 恢复(n-1)的值imul eax, ecx ; 计算n*(n-1)!jmp .done ; 返回结果.base_case:mov eax, 1 ; 如果参数为1,则返回1.done:mov esp, ebp ; 恢复栈指针pop ebp ; 恢复调用函数的栈帧指针 ret ; 返回函数结果```在这个例子中,我们定义了一个名为“factorial”的函数,该函数计算输入参数的阶乘。
win32api的使用方法
win32api的使用方法主要包括以下几种:
1. 调用win32api函数,如GetCursorPos()函数获取光标位置。
具体地,需要在代码中声明一个POINT结构体,然后使用DllImport属性导入动态链接库,最后调用GetCursorPos()函数并将返回的光标位置赋值给POINT 结构体中的X和Y属性。
2. 使用invoke语句调用API函数。
在MASM汇编语言中,可以使用invoke语句来调用API函数,并指定函数的参数。
编译器会检查参数的数量和类型是否正确,如果参数少了或者类型不匹配,会报错。
3. 在调用API函数之前,需要先声明该函数。
声明的格式包括函数名、原型、距离、语言和参数列表,其中参数列表包括每个参数的名称、数据类型和修饰符。
需要注意的是,win32api的使用需要一定的编程基础和经验,因此在学习使用win32api之前,建议先学习相关的编程语言和基础知识。
同时,win32api的使用也需要考虑到操作系统的版本和位数,不同的操作系统版本和位数可能会对API函数的可用性和行为产生影响。
因此,在使用
win32api时,需要注意选择正确的API函数并了解其用法和限制。
API进程线程函数API之进程和线程函数CancelWaitableTimer 这个函数⽤于取消⼀个可以等待下去的计时器操作CallNamedPipe 这个函数由⼀个希望通过管道通信的⼀个客户进程调⽤ConnectNamedPipe 指⽰⼀台服务器等待下去,直⾄客户机同⼀个命名管道连接CreateEvent 创建⼀个事件对象CreateMailslot 创建⼀个邮路。
返回的句柄由邮路服务器使⽤(收件⼈)CreateMutex 创建⼀个互斥体(MUTEX)CreateNamedPipe 创建⼀个命名管道。
返回的句柄由管道的服务器端使⽤CreatePipe 创建⼀个匿名管道CreateProcess 创建⼀个新进程(⽐如执⾏⼀个程序)CreateSemaphore 创建⼀个新的信号机CreateWaitableTimer 创建⼀个可等待的计时器对象DisconnectNamedPipe 断开⼀个客户与⼀个命名管道的连接DuplicateHandle 在指出⼀个现有系统对象当前句柄的情况下,为那个对象创建⼀个新句柄ExitProcess 中⽌⼀个进程FindCloseChangeNotification 关闭⼀个改动通知对象FindExecutable 查找与⼀个指定⽂件关联在⼀起的程序的⽂件名FindFirstChangeNotification 创建⼀个⽂件通知对象。
该对象⽤于监视⽂件系统发⽣的变化FindNextChangeNotification 重设⼀个⽂件改变通知对象,令其继续监视下⼀次变化FreeLibrary 释放指定的动态链接库GetCurrentProcess 获取当前进程的⼀个伪句柄GetCurrentProcessId 获取当前进程⼀个唯⼀的标识符GetCurrentThread 获取当前线程的⼀个伪句柄GetCurrentThreadId 获取当前线程⼀个唯⼀的线程标识符GetExitCodeProces 获取⼀个已中断进程的退出代码GetExitCodeThread 获取⼀个已中⽌线程的退出代码GetHandleInformation 获取与⼀个系统对象句柄有关的信息GetMailslotInfo 获取与⼀个邮路有关的信息GetModuleFileName 获取⼀个已装载模板的完整路径名称GetModuleHandle 获取⼀个应⽤程序或动态链接库的模块句柄GetPriorityClass 获取特定进程的优先级别GetProcessShutdownParameters 调查系统关闭时⼀个指定的进程相对于其它进程的关闭早迟情况GetProcessTimes 获取与⼀个进程的经过时间有关的信息GetProcessWorkingSetSize 了解⼀个应⽤程序在运⾏过程中实际向它交付了多⼤容量的内存GetSartupInfo 获取⼀个进程的启动信息GetThreadPriority 获取特定线程的优先级别GetTheardTimes 获取与⼀个线程的经过时间有关的信息GetWindowThreadProcessId 获取与指定窗⼝关联在⼀起的⼀个进程和线程标识符LoadLibrary 载⼊指定的动态链接库,并将它映射到当前进程使⽤的地址空间LoadLibraryEx 装载指定的动态链接库,并为当前进程把它映射到地址空间LoadModule 载⼊⼀个Windows应⽤程序,并在指定的环境中运⾏MsgWaitForMultipleObjects 等侯单个对象或⼀系列对象发出信号。
2.2.3 SolidWorks API函数介绍在SolidWorks创建的对象中,每个对象都有自己的属性和方法,通过调用API 函数来实现,反过来,应用SolidWorks的每一步操作都体现在特定的对象类中。
以下介绍一些在使用Visual Basic 6.0为开发平台时常用的API函数。
(1) 连接SolidWorks当在使用SolidWorks API调用功能时,我们必须先要与SolidWorks API提供的程序对象建立连接关系,也就是首先创建SolidWorks的应用对象,用到的SolidWorks 应用程序对象是:SldWorks。
SolidWorks应用程序对象(在宏程序里面声明为swApp,当然也可以声明为其他变量)是宏程序调用其他对象的入口,是所有调用SolidWorks API功能的最顶层,要调用SolidWorks API的其他功能,必须先调用此对象。
一般情况下,它在程序中的表现形式为:Dim swApp As Sldworks.SldworksSet swApp = Application.Sldworks变量swApp可以定义为Object或Sldworks.Sldworks(SolidWorks规定的对象)。
在对SolidWorks进行二次开发时,首先要建立SolidWorks的连接,创建SolidWorks的应用对象:Dim swApp As ObjectSet swApp = CreateObject(“SldWorks.Application”)通过这个函数,就打开了SolidWorks的接口,可以调用它的API函数了。
(2) 建立新的零件图创建零件图:Dim Part As ObjectSet Part = swApp.newpart使用该函数就能建立一个新的工作区,从而进行建模的操作。
(3) 选择要素该命令在SolidWorks中使用的非常频繁,在实际操作当中,有很多的命令在使用时都要选择操作对象,调用的API是ModelDoc对象中的SelectByID函数:ModelDoc.SelectByID(objectName,object Type,x,y,z)该函数在应用时需要输入五个参数:objectName表示要选择对象的名称,这个名称是SolidWorks在创建对象时按先后顺序自动命名的,例如基准面1,基准面2,Line5,D1@草图**************等。
VBA调用系统API函数的方法与实例说明VBA(Visual Basic for Applications)是一种基于Microsoft Visual Basic语言的宏编程语言,主要用于操作Microsoft Office软件中的各种功能。
尽管VBA本身提供了丰富的功能,但有时候我们可能需要调用操作系统的API函数来实现一些高级或特定的功能。
本文将详细介绍VBA调用系统API函数的方法,并提供一些实例说明。
在VBA中调用系统API函数可以拓展VBA的功能,并且提供了解决复杂问题的能力。
使用API函数可以与操作系统进行交互,访问底层功能和资源。
以下是一些常用的VBA调用系统API函数的方法:1. 声明API函数在使用API函数之前,我们需要在VBA中声明该函数。
声明API函数的语法如下:```Declare Function 函数名 Lib "库名称" ([alias]] [参数列表]) [返回值类型]```其中,函数名是要调用的API函数的名称,Lib是API 函数所在的库名称,参数列表是API函数的输入参数,返回值类型是API函数的返回值类型。
2. 调用API函数一旦我们声明了API函数,就可以在VBA代码中调用该函数。
调用API函数的语法如下:```变量名 = 函数名([参数列表])```其中,变量名是接收API函数返回值的变量名,函数名是已声明的API函数的名称,参数列表是传递给API函数的参数列表。
3. 释放资源在调用API函数之后,我们需要确保适当地释放相关资源以避免内存泄漏。
可以使用相关的API函数来释放资源,如CloseHandle函数释放句柄资源。
现在让我们通过几个实例来说明如何在VBA中调用系统API函数:1. 调用MessageBox函数MessageBox函数用于显示一个包含指定消息和按钮的模态对话框,并返回用户的操作。
下面的代码演示了如何在VBA中调用MessageBox函数:```vbaDeclare Function MessageBox Lib "user32" Alias "MessageBoxA" (ByVal hWnd As Long, _ByVal lpText As String, ByVal lpCaption As String, ByVal uType As Long) As LongSub ShowMessageBox()Dim prompt As StringDim title As StringDim result As Longprompt = "这是一个提示框!"title = "提示"result = MessageBox(0, prompt, title, 1)End Sub```在上述代码中,我们首先声明了MessageBox函数,然后在Sub过程ShowMessageBox中调用了该函数。
VB6中API函数的使用
一、什么是API函数
API(应用程序编程接口)函数是操作系统提供的一组函数,提供给
其它程序调用。
API允许软件开发者在调用接口时要求操作系统完成项工作。
二、Visual Basic6中使用API函数
Visual Basic6中使用API函数的方法有三种,它们分别是:
1.使用VBApi模块
VBApi模块可以帮助你实现API函数的调用。
它可以用在任何类型的
应用程序中,并且它可以用来调用任何的API函数,只需要在Visual Basic6中添加一个VBApi模块即可,添加方式如下:
2.使用Declare语句
Declare定义是用来定义Visual Basic程序和外部函数或DLL文件
中的特殊函数的语句。
[Public , Private][Static] Declare FunctionName AliasAliasname Lib"PathName"[(AsReturnType]
3.使用DLL
使用DLL是比使用VBApi模块和Declare语句更高级的API函数调用
方式,它可以大大简化调用过程。
在使用DLL之前,需要先配置DLL文件,具体步骤如下:
(1)将需要调用的DLL文件添加到Visual Basic的References中,这样Visual Basic就可以调用该DLL文件中的函数。
(2)添加Win32API模块,使用此模块可定义API函数的参数。
学会⽤API函数读出内存数据CheatEngine6.2下载地址将⽤CE来找出对对碰游戏 坐位号基址,棋盘数组基址并把它读出来教学⽬的:学会⽤API函数读出内存数据1、预备知识4种数据类型字节 Byte=00-FF 0-255 8bit字 WORD =2Byte= $0000⾄ $FFFF 0-65535 16bit双字 DWORD =4Byte= $00000000⾄$FFFFFFFF 0-4294967295 32 bit整型 integer=4Byte=-$80000000⾄$7FFFFFFF -2147483648,2147483647 32bit游戏基址:就是⼀个全局变量存放数据的起始地址。
准备⼯具 CE (全称Cheat Engine V5.4)打开QQ对对碰游戏打开内存搜索⼯具 CE找坐位号基址:我们搜索在 0-3以内的数值 数值类型选DWORD 双字找对应坐标号 棋盘数组基址:我们搜索 棋盘数组的 第⼀格 数值类型设为 BYTE 字节2、编写程序3个 API函数GetWindowThreadProcessId :获取进程IDOpenProcess :获取进程句柄ReadProcessMemory :读出指定进程 指定位置 的数据到缓冲区DWORD GetWindowThreadProcessId(HWND hWnd, // 窗⼝句柄 由FindWindow获取LPDWORD lpdwProcessId // 存放进程ID的 变量);HANDLE OpenProcess(DWORD dwDesiredAccess, // PROCESS_VM_READ or PROCESS_VM_WRITE 访问权限 BOOL bInheritHandle, // 这个是继承标志 在这⾥ 为falseDWORD dwProcessId // 进程ID 由GetWindowThreadProcessId 获取);BOOL ReadProcessMemory(HANDLE hProcess, // 进程句柄 由OpenProcess函数获取LPCVOID lpBaseAddress, // 要读出数据的地址:$47d814LPVOID lpBuffer, // ⽤于存放读取数据的地址:sitNumDWORD nSize, // 要读出的数据⼤⼩ 4LPDWORD lpNumberOfBytesRead // 读出数据的实际⼤⼩);具体代码//从对对碰程序读出棋盘数据 到棋盘数组⾥边const GameName='对对碰⾓⾊版'const sitNumBase= ;varPidGame :DWORD; //⽤来保存进程IDhGame :HWND; //⽤来保存游戏窗⼝句柄readByte:DWORD; //⽤来保存 实际读取的字节数ChessData:Array[1..8,1..25] of byte; //定义的⼀个棋盘数组//4个棋盘基址号var sitBase:array[0..3] of ^integer=(Pointer($0047A318),Pointer($0047AEF4),Pointer($0047BAD0),Pointer($0047C6AC));Function UpDataChess():boolean;begin//获取游戏窗⼝句柄hGame:=Findwindow(nil,GameName);//获取游戏进程 PIDwindows.GetWindowThreadProcessId(hGame,PidGame) ;//获取游戏进程句柄hProcess:=windows.OpenProcess(windows.PROCESS_ALL_ACCESS,false,PidGame);//读出当前坐位号windows.ReadProcessMemory(hProcess,Pointer(sitNumBase),sitNumP,4,readByte);//读出棋盘数据到数组windows.ReadProcessMemory(hProcess,sitBase[sitNum],@ChessData[1][1],200,readByte); //释放进程句柄result:=CloseHandle(Hprocess);end;。
A PI 示例API (应用程序编程接口)是 DLL 文件中所包含的一种功能。
这些功能通常由 Windows 和其他应用程序使用,但也可以被最终用户所使用。
注释: 使用 API 调用请多加小心。
要注意保存以避免丢失所做的工作。
由于这种功能的设计目的是由系统和应用程序所调用,所以许多错误捕获功能并未实施。
这意味着使用 API 调用时,有可能导致系统挂起、崩溃或其他不可预测的副作用。
下面的示例说明了如何使用基本的 API 。
已经在 Windows98 和 Excel 中测试通过。
使用这些功能的方式很多,程序员可以自行确定哪种方式更为合适。
检查所有的驱动器盘符下面的示例使用“GetLogicalDriveStrings ”函数循环通过所有逻辑驱动器。
逻辑驱动器是指软盘、硬盘、CD 驱动器及映射的网络共享。
Option ExplicitPrivate Declare Function GetLogicalDriveStrings Lib "kernel32" Alias "GetLogicalDriveStringsA" _ (ByVal nBufferLength As Long, _ByVal lpBuffer As String) As Long Sub Get_Logical_Drive_String()Dim DrvString As String Dim TotDrvs As Long Dim Counter As Integer'变量“TotDrvs”返回字符串中总的字符数TotDrvs = GetLogicalDriveStrings(0&, DrvString) '变量“DrvString”是为存放该字符串而创建的缓冲区DrvString = String(TotDrvs - 1, " ")'再次调用“GetLogicalDriveStrings”,用有效数据填充字符串'示例 "a:\ c:\ d:\ e:\ "TotDrvs = GetLogicalDriveStrings(TotDrvs, DrvString)'解析整个返回的字符串,并在“msgbox”中显示每个盘符For Counter = 1 To TotDrvs Step 4 MsgBox Mid(DrvString, Counter, 3)Next CounterEnd Sub返回视频分辨率下面的示例代码返回当前的屏幕视频分辨率并在消息框中显示信息。
【文件操作类的api函数主要是包含】:文件的创建; createfile | 文件的读写;writefile |获取文件大小;getfilesize | 取文件属性;GetFileAttributesA|设置文件属性;setfileattribute|复制文件 copyfile|移动文件movefile | 关闭文件句柄;closehandle1、sleep 延迟函数004A2015 68 E8030000 push 0x3E8 1000毫秒==1秒004A201A E8 41C2F6FF call <jmp.&kernel32.Sleep>004A1E48 > 68 E8030000 push 3E8004A1E4D FF15 70834A00 call dword ptrds:[<&kernel32.Sleep>] ; kernel32.Sleeppush xxxxcall [xxxxxxxx] 模板CTRL+N查找函数参考-------------------------------------------2、ExitProcess 中止一个进程004A20E0 6A 00 push 0x0 (终止本进程)004A20E2 E8 4D4DF6FF call <jmp.&kernel32.ExitProcess>004A1E48 > 6A 00 push 0004A1E4A FF15 E0844A00 call dword ptrds:[<&kernel32.ExitProc>; kernel32.ExitProcess-------------------------------------------3、WinExec 调用运行另一个程序的函数push 0push 路径call [xxxxxxxx]004A2078 50 push eax004A2079 E8 EE50F6FF call <jmp.&kernel32.WinExec>004A1E48 > 6A 01 push 0x1 //显示运行004A1E4A 68 721E4A00 push004A1E72 ; ASCII "c:\d.exe"004A1E4F FF15 48834A00 call dword ptr[<&kernel32.WinExec>] ; kernel32.WinExec----------------------------------------------4、GetLocalTime 获取本地时间的函数0040ADF3 50 PUSH EAX0040ADF4 E8 3BC1FFFF CALL <JMP.&kernel32.GetLocalTime> DB 07 2011年月周日时分秒004A1E49 8D85 70FEFFFF lea eax, dword ptr [ebp-0x190]004A1E4F 50 push eax //这个里面004A1E50 FF15 60844A00 call dword ptr[<&kernel32.GetLocalTime>] ;00473AD5 8D45 EC lea eax, dword ptr [ebp-0x14] 00473AD8 50 push eax00473AD9 E8 A634F9FF call <jmp.&kernel32.GetSystemTime> --------------------------------------------------------------5、GetSystemDirectoryA 获取系统目录的函数call <jmp.&kernel32.GetWindowsDirectoryA>0049FD5E 68 FF000000 push 0xFF 大小0049FD63 8D85 00FFFFFF lea eax, dword ptr [ebp-0x100] 0049FD69 50 push eax0049FD6A E8 6D72F6FF call<jmp.&kernel32.GetWindowsDirectoryA>00401006 6A 20 push 0x20 bufer size00401008 68 00234000 push 00402300 bufer address 0040100D FF15 04314000 call GetSystemDirectoryA004A1E48 > 68 00010000 push 0x100004A1E4D 8D85 00FFFFFF lea eax, dword ptr [ebp-0x100]004A1E53 50 push eax004A1E54 FF15 23204C00 call dword ptr[<&kernel32.GetSystemDirectoryA>] ;xp c:\windows\system322000--------------------------------------------------------------6、GetTickCount 从你开机----现在所经历的毫秒数 1000 ==1秒GetTickCount 无参数有返回值获取系统启动时间的函数返回数据存放在eax寄存器中;005C7A02005DCED4005E06DC获取到这个数据,然后将他写入到程序里面。
md57、GetModuleHandleA 获取基础地址(可以用这个函数对自动加密代码进行改造)00401715 |. 6A 00 push 0x0 00401717 FF15 90A14200 call dword ptr[<&KERNEL32.GetModuleHandleA>]; kernel32.GetModuleHandleAcallpopandcmpsubjmp----------------------------------------------------------------------区别于98、 GetModuleFileNameA 获取本运行程序的路径(包括本程序的名字)()三个参数00401066 |. 68 04010000 push 0x104 ; /BufSize = 104 (260.)0040106B |. 8D95 FCFEFFFF lea edx, dword ptr [ebp-0x104] ; |00401071 |. 52 pushedx ; |PathBuffer00401072 |. 6A 00 push 0x0 ; |hModule = NULL00401074 |. FF15 84A14200 call dword ptr [<&KERNEL32.GetModuleF>; \GetModuleFileNameA0012FDF0 43 3A 5C 44 6F 63 75 6D 65 6E 74 73 20 61 6E 64 C:\Documents and0012FE00 20 53 65 74 74 69 6E 67 73 5C 41 64 6D 69 6E 69 Settings\Admini 0012FE10 73 74 72 61 74 6F 72 5C D7 C0 C3 E6 5C 61 70 69 strator\桌面\api0012FE20 2E 65 78 65 .exepush 200lea eax,[ebp-120]push eaxcall [xxxxxxx]--------------------------------------------------------------------------------区别于89、GetCurrentDirectoryA 获取本程序运行的所在路径(不包括文件名本身)00401089 |. 50 pusheax ; /Buffer0040108A |. 68 04010000 push 0x104 ; |BufSize = 104 (260.)0040108F |. FF15 80A14200 call dword ptr [<&KERNEL32.GetCurrent>; \GetCurrentDirectoryAName=kernel32.GetCurrentDirectoryA0012FEAA 43 3A 5C 44 6F 63 75 6D 65 6E 74 73 20 61 6E 64 C:\Documents and0012FEBA 20 53 65 74 74 69 6E 67 73 5C 41 64 6D 69 6E 69 Settings\Admini 0012FECA 73 74 72 61 74 6F 72 5C D7 C0 C3 E6 00 strator\桌面..=[强调]:就是buffer 缓冲区;lea edx,[ebp-108]push edxpush 120call [xxxxxxxxx]------------------------------------------------------------------------------------【关注】10、GetVersion 获取系统版本(这个以后咱们有大用处)【无参数】00401636 FF15 9CA14200 call dword ptr [<&KERNEL32.GetVersion>; kernel32.GetVersion返回值:0A 28 01 05ah alal中代表的是主版本ah代表是副版本call dword ptr [<&KERNEL32.GetVersion>; kernel32.GetVersioncmp al,5jecmp ah,1je xxxxxxxx:这个就是windows xp (32)------------------------------------------------------------------------11、GetStartupInfoA 该函数返回进程在启动时被指定的 STARTUPINFO 结构(该函数咱们不做过多讲解);【主要是作为“花”来用就可以了】004016DE 51 push ecx004016DF FF15 94A14200 call dword ptr[<&KERNEL32.GetStartupInfoA>];00496B5B 8D85 787FFFFF lea eax, dword ptr [ebp-124]00496B61 50 push eax00496B62 E8 FD03F7FF call <jmp.&kernel32.GetStartupInfoA>----------------------------------------------------------------------------------------------12、lstrcmpiA若第一个字符串比第二个字符串小则返回值为负;若第一个字符串比第二个字符串大则返回值为正;若两个字符串相等则返回值为0。