在手機上打字是一件很痛苦的事情,如果用說的可能會來得比較快樂點,現在就來跟各位說如何發一封語音郵件,那在手機上要如何錄音呢,我們可以利用 Recording and Playing Sound with the Waveform Audio Interface參考http://msdn.microsoft.com/en-us/library/aa446573.aspx
Step1:開啟vs2008 新增一個vb 智慧型裝置專案,在表單上產生ListBox元件來顯示整個操作過程訊息, Button按鍵用來開始錄音及結束發送mail

Step2:將滑鼠移到方案總管到SmartDeviceProject1下的參考,按下滑鼠右鍵加入參考

Step3:選擇Microsoft.WindowsMobile.PocketOutlook按下確定

Step4:插入Class Memory

01 
Imports ...System
02
Imports System.Runtime.InteropServices
03
04
Public Class Memory
05
06
07
Public Const LMEM_FIXED As Integer = &H0
08
09
Public Const LMEM_ZEROINIT As Integer = &H40
10
11
Public Const LMEM_MOVEABLE As Integer = &H2
12
13
Public Const LMEM_MODIFY As Integer = &H80
14
15
16
<DllImport("coredll.dll")> _
17 
Public Shared Function LocalAlloc() Shared Function LocalAlloc(ByVal uFlags As Integer, ByVal uBytes As Integer) As IntPtr
18
End Function
19
20
<DllImport("coredll.dll")> _
21 
Public Shared Function LocalFree() Shared Function LocalFree(ByVal hMem As IntPtr) As IntPtr
22
End Function
23
24
<DllImport("coredll.dll")> _
25 
Public Shared Function LocalReAlloc() Shared Function LocalReAlloc(ByVal hMem As IntPtr, ByVal uBytes As Integer, ByVal fuFlags As Integer) As IntPtr
26
End Function
27
28
End Class
Step5:插入Class Wave

001 
Imports ...System
002
Imports System.IO
003
Imports System.Runtime.InteropServices
004
005
006
Public Class Wave
007
008
009
Public Const WAVE_MAPPER As Integer = -1
010
011
Public Const CALLBACK_WINDOW As Integer = &H10000
012
013
Private Const WAVERR_BASE As Integer = 32
014
Private Const MMSYSERR_BASE As Integer = 0
015
016
017
Public Enum MMSYSERR
018
NOERROR = 0
019
GENERROR = (MMSYSERR_BASE + 1)
020
BADDEVICEID = (MMSYSERR_BASE + 2)
021
NOTENABLED = (MMSYSERR_BASE + 3)
022
ALLOCATED = (MMSYSERR_BASE + 4)
023
INVALHANDLE = (MMSYSERR_BASE + 5)
024
NODRIVER = (MMSYSERR_BASE + 6)
025
NOMEM = (MMSYSERR_BASE + 7)
026
NOTSUPPORTED = (MMSYSERR_BASE + 8)
027
BADERRNUM = (MMSYSERR_BASE + 9)
028
INVALFLAG = (MMSYSERR_BASE + 10)
029
INVALPARAM = (MMSYSERR_BASE + 11)
030
HANDLEBUSY = (MMSYSERR_BASE + 12)
031
INVALIDALIAS = (MMSYSERR_BASE + 13)
032
BADDB = (MMSYSERR_BASE + 14)
033
KEYNOTFOUND = (MMSYSERR_BASE + 15)
034
READERROR = (MMSYSERR_BASE + 16)
035
WRITEERROR = (MMSYSERR_BASE + 17)
036
DELETEERROR = (MMSYSERR_BASE + 18)
037
VALNOTFOUND = (MMSYSERR_BASE + 19)
038
NODRIVERCB = (MMSYSERR_BASE + 20)
039
LASTERROR = (MMSYSERR_BASE + 20)
040
End Enum
041
042
' Enum equivalent to WAVERR_*
043
Private Enum WAVERR
044
NONE = 0
045
BADFORMAT = WAVERR_BASE + 0
046
STILLPLAYING = WAVERR_BASE + 1
047
UNPREPARED = WAVERR_BASE + 2
048
SYNC = WAVERR_BASE + 3
049
LASTERROR = WAVERR_BASE + 3
050
End Enum
051
052
053
Public Const WAVE_INVALIDFORMAT As Integer = &H0
054
055
Public Const WAVE_FORMAT_1M08 As Integer = &H1
056
057
Public Const WAVE_FORMAT_1S08 As Integer = &H2
058
059
Public Const WAVE_FORMAT_1M16 As Integer = &H4
060
061
Public Const WAVE_FORMAT_1S16 As Integer = &H8
062
063
Public Const WAVE_FORMAT_2M08 As Integer = &H10
064
065
Public Const WAVE_FORMAT_2S08 As Integer = &H20
066
067
Public Const WAVE_FORMAT_2M16 As Integer = &H40
068
069
Public Const WAVE_FORMAT_2S16 As Integer = &H80
070
071
Public Const WAVE_FORMAT_4M08 As Integer = &H100
072
073
Public Const WAVE_FORMAT_4S08 As Integer = &H200
074
075
Public Const WAVE_FORMAT_4M16 As Integer = &H400
076
077
Public Const WAVE_FORMAT_4S16 As Integer = &H800
078
079
Public Class WAVEFORMATEX
080
081
Protected Const WF_OFFSET_FORMATTAG As Integer = 20
082
Protected Const WF_OFFSET_CHANNELS As Integer = 22
083
Protected Const WF_OFFSET_SAMPLESPERSEC As Integer = 24
084
Protected Const WF_OFFSET_AVGBYTESPERSEC As Integer = 28
085
Protected Const WF_OFFSET_BLOCKALIGN As Integer = 32
086
Protected Const WF_OFFSET_BITSPERSAMPLE As Integer = 34
087
Public Const WF_OFFSET_DATA As Integer = 44
088
089 
Public Property wFormatTag() Property wFormatTag()
090
Get
091
Return Convert.ToInt32(m_wFormatTag)
092
End Get
093
Set(ByVal Value)
094
m_wFormatTag = Convert.ToUInt16(Value)
095
End Set
096
End Property
097 
Protected m_wFormatTag As UInt16 = Convert.ToUInt16() m_wFormatTag As UInt16 = Convert.ToUInt16(0)
098
099 
Public Property nChannels() Property nChannels()
100
Get
101
Return Convert.ToInt32(m_nChannels)
102
End Get
103
Set(ByVal Value)
104
m_nChannels = Convert.ToUInt16(Value)
105
End Set
106
End Property
107 
Protected m_nChannels As UInt16 = Convert.ToUInt16() m_nChannels As UInt16 = Convert.ToUInt16(0)
108
109 
Public Property nSamplesPerSec() Property nSamplesPerSec()
110
Get
111
Return Convert.ToInt32(m_nSamplesPerSec)
112
End Get
113
Set(ByVal Value)
114
m_nSamplesPerSec = Convert.ToUInt32(Value)
115
End Set
116
End Property
117 
Protected m_nSamplesPerSec As UInt32 = Convert.ToUInt32() m_nSamplesPerSec As UInt32 = Convert.ToUInt32(0)
118
119 
Public Property nAvgBytesPerSec() Property nAvgBytesPerSec()
120
Get
121
Return Convert.ToInt32(m_nAvgBytesPerSec)
122
End Get
123
Set(ByVal Value)
124
m_nAvgBytesPerSec = Convert.ToUInt32(Value)
125
End Set
126
End Property
127 
Protected m_nAvgBytesPerSec As UInt32 = Convert.ToUInt32() m_nAvgBytesPerSec As UInt32 = Convert.ToUInt32(0)
128
129 
Public Property nBlockAlign() Property nBlockAlign()
130
Get
131
Return Convert.ToInt32(m_nBlockAlign)
132
End Get
133
Set(ByVal Value)
134
m_nBlockAlign = Convert.ToUInt16(Value)
135
End Set
136
End Property
137 
Protected m_nBlockAlign As UInt16 = Convert.ToUInt16() m_nBlockAlign As UInt16 = Convert.ToUInt16(0)
138
139 
Public Property wBitsPerSample() Property wBitsPerSample()
140
Get
141
Return Convert.ToInt32(m_wBitsPerSample)
142
End Get
143
Set(ByVal Value)
144
m_wBitsPerSample = Convert.ToUInt16(Value)
145
End Set
146
End Property
147 
Protected m_wBitsPerSample As UInt16 = Convert.ToUInt16() m_wBitsPerSample As UInt16 = Convert.ToUInt16(0)
148
149 
Public Sub SeekTo() Sub SeekTo(ByVal fs As Stream)
150
fs.Seek(WF_OFFSET_FORMATTAG, SeekOrigin.Begin)
151
End Sub
152
153 
Public Sub Skip() Sub Skip(ByVal fs As Stream)
154
fs.Seek(WF_OFFSET_DATA, SeekOrigin.Begin)
155
End Sub
156
157 
Public Sub Read() Sub Read(ByVal rdr As BinaryReader)
158
159
m_wFormatTag = rdr.ReadUInt16()
160
m_nChannels = rdr.ReadUInt16()
161
m_nSamplesPerSec = rdr.ReadUInt32()
162
m_nAvgBytesPerSec = rdr.ReadUInt32()
163
m_nBlockAlign = rdr.ReadUInt16()
164
m_wBitsPerSample = rdr.ReadUInt16()
165
166
Dim dataId As UInt32 = rdr.ReadUInt32()
167
Dim dataLength As UInt32 = rdr.ReadUInt32()
168
169
End Sub
170
171 
Public Sub Write() Sub Write(ByVal wrtr As BinaryWriter)
172
173
wrtr.Write(Convert.ToUInt16(m_wFormatTag))
174
wrtr.Write(Convert.ToUInt16(m_nChannels))
175
wrtr.Write(Convert.ToUInt32(m_nSamplesPerSec))
176
wrtr.Write(Convert.ToUInt32(m_nAvgBytesPerSec))
177
wrtr.Write(Convert.ToUInt16(m_nBlockAlign))
178
wrtr.Write(Convert.ToUInt16(m_wBitsPerSample))
179
180
End Sub
181
End Class
182
183
Public Class WAVEHDR
184
Implements IDisposable
185
186
Public Const WHDR_DONE As Integer = &H1
187
188
Public Const WHDR_PREPARED As Integer = &H2
189
190
Public Const WHDR_BEGINLOOP As Integer = &H4
191
192
Public Const WHDR_ENDLOOP As Integer = &H8
193
194
Public Const WHDR_INQUEUE As Integer = &H10
195
196
Public Const WAVE_FORMAT_PCM As Integer = 1
197
198
Public lpData As IntPtr = IntPtr.Zero
199
200
Public dwBufferLength As Integer = 0
201
202
Public dwBytesRecorded As Integer = 0
203
204
Public dwUser As Integer = 0
205
206
Public dwFlags As Integer = 0
207
208
Public dwLoops As Integer = 0
209
210
Public lpNext As IntPtr = IntPtr.Zero
211
212
Public reserved As Integer = 0
213
214 
Public Function Read() Function Read(ByVal rdr As BinaryReader, ByVal readLength As Integer, ByVal align As Integer) As MMSYSERR
215
216
Dim bufferLength As Integer = readLength
217
218
If bufferLength Mod align <> 0 Then
219
bufferLength += (align - (bufferLength Mod align))
220
End If
221
222
dwBufferLength = bufferLength
223
Dim data(readLength - 1) As Byte
224
rdr.Read(data, 0, data.Length)
225
226
If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
227
lpData = Memory.LocalAlloc(Memory.LMEM_FIXED, bufferLength)
228
End If
229
230
If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
231
Return MMSYSERR.NOMEM
232
End If
233
234
Marshal.Copy(data, 0, lpData, data.Length)
235
236
Return MMSYSERR.NOERROR
237
238
End Function
239
240 
Public Function Write() Function Write(ByVal wrtr As BinaryWriter) As MMSYSERR
241
242
If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
243
Return Wave.MMSYSERR.NOMEM
244
End If
245
246
Dim data(dwBytesRecorded - 1) As Byte
247
Marshal.Copy(lpData, data, 0, data.Length)
248
wrtr.Write(data)
249
250
Return Wave.MMSYSERR.NOERROR
251
252
End Function
253
254 
Public Function Init() Function Init(ByVal bufferLength As Integer, ByVal initData As Boolean) As MMSYSERR
255
256
If lpData.ToInt32() <> IntPtr.Zero.ToInt32() AndAlso dwBufferLength < bufferLength Then
257
Memory.LocalFree(lpData)
258
lpData = IntPtr.Zero
259
End If
260
261
If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
262
lpData = Memory.LocalAlloc(Memory.LMEM_FIXED, bufferLength)
263
End If
264
265
dwBufferLength = bufferLength
266
267
If lpData.ToInt32() = IntPtr.Zero.ToInt32() Then
268
Return MMSYSERR.NOMEM
269
End If
270
271
If initData Then
272
Dim i As Integer
273
For i = 0 To bufferLength - 1
274
Marshal.WriteByte(lpData, i, 0)
275
Next
276
End If
277
278
Return MMSYSERR.NOERROR
279
280
End Function
281
282 
Public Sub Dispose() Sub Dispose() Implements IDisposable.Dispose
283
If lpData.ToInt32() <> IntPtr.Zero.ToInt32() Then
284
Memory.LocalFree(lpData)
285
End If
286
End Sub
287
End Class
288
End Class
Step6:插入Class WaveIn

001 
Imports ...System
002
Imports System.Runtime.InteropServices
003
Imports System.IO
004
Imports Microsoft.WindowsCE.Forms
005
Imports System.Text
006
Imports System.Threading
007
Imports System.Windows.Forms
008
Imports System.Diagnostics
009
010
011
Public Class WaveIn
012
013
Protected Class WaveFile
014
Implements IDisposable
015
016
Protected m_hwi As IntPtr = IntPtr.Zero
017
018
019
Protected m_wfmt As Wave.WAVEFORMATEX = Nothing
020
021
022 
Protected m_whdr() m_whdr() As Wave.WAVEHDR = Nothing
023
024
025
Protected m_inited As Boolean = False
026
027
028
Protected m_curBlock As Integer
029
030
031
Protected m_numBlocks As Integer
032
033
034
Protected m_bufferSize As Integer
035
036
Protected m_maxDataLength As Integer
037
038 
Public ReadOnly Property Done() ReadOnly Property Done()
039
Get
040
Return Not m_recording
041
End Get
042
End Property
043
Protected m_recording As Boolean = False
044
045
046 
Public Function Preload() Function Preload(ByVal curDevice As Integer, ByVal hwnd As IntPtr, ByVal maxRecordLength_ms As Integer, ByVal bufferSize As Integer) As Wave.MMSYSERR
047
048
' Do not allow recording to be interrupted
049
If m_recording Then
050
Return Wave.MMSYSERR.GENERROR
051
End If
052
053
' If this file is already initialized then start over
054
If m_inited Then
055
StopRecord()
056
FreeWaveBuffers()
057
End If
058
059
' Create an instance of WAVEINCAPS to check if our desired
060
' format is supported
061
Dim caps As WAVEINCAPS = New WAVEINCAPS
062
waveInGetDevCaps(0, caps.Data, caps.Size)
063
If (caps.dwFormats And Wave.WAVE_FORMAT_2S16) = 0 Then
064
Return Wave.MMSYSERR.NOTSUPPORTED
065
End If
066
067
' Initialize a WAVEFORMATEX structure specifying the desired
068
' format
069
m_wfmt = New Wave.WAVEFORMATEX
070
m_wfmt.wFormatTag = Wave.WAVEHDR.WAVE_FORMAT_PCM
071
m_wfmt.wBitsPerSample = 16
072
m_wfmt.nChannels = 2
073
m_wfmt.nSamplesPerSec = 22050
074
m_wfmt.nAvgBytesPerSec = Fix((m_wfmt.nSamplesPerSec * m_wfmt.nChannels * m_wfmt.wBitsPerSample) / 8)
075
m_wfmt.nBlockAlign = Fix((m_wfmt.wBitsPerSample * m_wfmt.nChannels) / 8)
076
077
' Attempt to open the specified device with the desired wave format
078
Dim result As Wave.MMSYSERR = waveInOpen(m_hwi, curDevice, m_wfmt, hwnd, 0, Wave.CALLBACK_WINDOW)
079
If result <> Wave.MMSYSERR.NOERROR Then
080
Return result
081
End If
082
083
If bufferSize = 0 Then
084
Return Wave.MMSYSERR.GENERROR
085
End If
086
087
m_bufferSize = bufferSize
088
089
' Force the buffers to align to nBlockAlign
090
If (m_bufferSize Mod m_wfmt.nBlockAlign) <> 0 Then
091
m_bufferSize += m_wfmt.nBlockAlign - (m_bufferSize Mod m_wfmt.nBlockAlign)
092
End If
093
094
' Determine the number of buffers needed to record the maximum length
095
m_maxDataLength = (m_wfmt.nAvgBytesPerSec * maxRecordLength_ms) / 1000
096
m_numBlocks = Fix(m_maxDataLength / m_bufferSize)
097
If (m_numBlocks * m_bufferSize) < m_maxDataLength Then
098
m_numBlocks += 1
099
End If
100
101
' Allocate the list of buffers
102
m_whdr = New Wave.WAVEHDR(m_numBlocks) {}
103
104
105
' Allocate and initialize two buffers to start with
106
m_whdr(0) = New Wave.WAVEHDR
107
m_whdr(1) = New Wave.WAVEHDR
108
109
result = InitBuffer(0)
110
If result <> Wave.MMSYSERR.NOERROR Then
111
Return result
112
End If
113
114
result = InitBuffer(1)
115
If result <> Wave.MMSYSERR.NOERROR Then
116
Return result
117
End If
118
119
m_curBlock = 0
120
m_inited = True
121
122
Return Wave.MMSYSERR.NOERROR
123
124
End Function
125
126
127 
Public Sub BlockDone() Sub BlockDone()
128
129
m_curBlock += 1
130
131
' If the next block is not the padding buffer at the end of the
132
' recording then initialize another buffer, otherwise stop recording
133
If m_curBlock < m_numBlocks Then
134
InitBuffer(m_curBlock + 1)
135
ElseIf m_curBlock = m_numBlocks Then
136
StopRecord()
137
End If
138
139
End Sub
140
141
142 
Public Function InitBuffer() Function InitBuffer(ByVal bufIndex As Integer) As Wave.MMSYSERR
143
144
' Determine the size of the buffer to create
145
Dim writeLength As Integer = m_bufferSize
146
147
If bufIndex < m_numBlocks Then
148
Dim remainingDataLength As Integer = m_maxDataLength - (bufIndex * m_bufferSize)
149
If m_bufferSize > remainingDataLength Then
150
writeLength = remainingDataLength
151
End If
152
End If
153
154
' If the header is not already instanced then instance it
155
If m_whdr(bufIndex) Is Nothing Then
156
m_whdr(bufIndex) = New Wave.WAVEHDR
157
End If
158
159
' Allocate memory if not already allocated
160
Dim result As Wave.MMSYSERR = m_whdr(bufIndex).Init(writeLength, False)
161
If result <> Wave.MMSYSERR.NOERROR Then
162
Return result
163
End If
164
165
' Prepare the header
166
result = waveInPrepareHeader(m_hwi, m_whdr(bufIndex), Marshal.SizeOf(m_whdr(bufIndex)))
167
If result <> Wave.MMSYSERR.NOERROR Then
168
Return result
169
End If
170
171
' Put the buffer in the queue
172
Return waveInAddBuffer(m_hwi, m_whdr(bufIndex), Marshal.SizeOf(m_whdr(bufIndex)))
173
174
End Function
175
176 
Public Function Start() Function Start() As Wave.MMSYSERR
177
178
If Not m_inited OrElse m_recording Then
179
Return Wave.MMSYSERR.GENERROR
180
End If
181
182
Dim result As Wave.MMSYSERR = waveInStart(m_hwi)
183
If result <> Wave.MMSYSERR.NOERROR Then
184
Return result
185
End If
186
187
m_recording = True
188
189
Return Wave.MMSYSERR.NOERROR
190
191
End Function
192
193 
Private Sub FreeWaveBuffers() Sub FreeWaveBuffers()
194
195
m_inited = False
196
197
If Not (m_whdr Is Nothing) Then
198
199
Dim i As Integer
200
For i = 0 To m_whdr.Length - 1
201
If Not (m_whdr(i) Is Nothing) Then
202
waveInUnprepareHeader(m_hwi, m_whdr(i), Marshal.SizeOf(m_whdr(i)))
203
204
m_whdr(i).Dispose()
205
m_whdr(i) = Nothing
206
End If
207
Next
208
209
m_whdr = Nothing
210
211
End If
212
213
waveInClose(m_hwi)
214
215
m_hwi = IntPtr.Zero
216
217
End Sub
218
219 
Private Sub WriteChars() Sub WriteChars(ByVal wrtr As BinaryWriter, ByVal txt As String)
220
221
Dim i As Integer
222
For i = 0 To txt.Length - 1
223
Dim c As Char = txt.Chars(i)
224
wrtr.Write(c)
225
Next
226
227
End Sub
228
229 
Public Function Save() Function Save(ByVal fileName As String) As Wave.MMSYSERR
230
231
If Not m_inited Then
232
Return Wave.MMSYSERR.GENERROR
233
End If
234
235
If m_recording Then
236
StopRecord()
237
End If
238
239
Dim strm As FileStream = Nothing
240
Dim wrtr As BinaryWriter = Nothing
241
242
Try
243
244
If File.Exists(fileName) Then
245
246
Dim fi As FileInfo = New FileInfo(fileName)
247
If (fi.Attributes And FileAttributes.ReadOnly) <> 0 Then
248
fi.Attributes -= FileAttributes.ReadOnly
249
End If
250
251
strm = New FileStream(fileName, FileMode.Truncate)
252
Else
253
strm = New FileStream(fileName, FileMode.Create)
254
End If
255
256
If strm Is Nothing Then
257
Return Wave.MMSYSERR.GENERROR
258
End If
259
260
wrtr = New BinaryWriter(strm)
261
If wrtr Is Nothing Then
262
Return Wave.MMSYSERR.GENERROR
263
End If
264
265
' Determine the size of the data, as the total number of bytes
266
' recorded by each buffer
267
Dim totalSize As Integer = 0
268
Dim i As Integer
269
For i = 0 To m_numBlocks - 1
270
If Not (m_whdr(i) Is Nothing) Then
271
totalSize += m_whdr(i).dwBytesRecorded
272
End If
273
Next
274
275
276
Dim chunkSize As Integer = 36 + totalSize
277
278
' Write out the header information
279
WriteChars(wrtr, "RIFF")
280
wrtr.Write(chunkSize)
281
WriteChars(wrtr, "WAVEfmt ")
282
wrtr.Write(Convert.ToInt32(16))
283
m_wfmt.Write(wrtr)
284
WriteChars(wrtr, "data")
285
wrtr.Write(totalSize)
286
287
' Write the data recorded to each buffer
288
For i = 0 To m_numBlocks - 1
289
If Not (m_whdr(i) Is Nothing) Then
290
Dim result As Wave.MMSYSERR = m_whdr(i).Write(wrtr)
291
If result <> Wave.MMSYSERR.NOERROR Then
292
Return result
293
End If
294
End If
295
Next
296
297
Return Wave.MMSYSERR.NOERROR
298
299
Finally
300
FreeWaveBuffers()
301
302
If Not (strm Is Nothing) Then
303
strm.Close()
304
End If
305
306
If Not (wrtr Is Nothing) Then
307
wrtr.Close()
308
End If
309
310
End Try
311
312
End Function
313
314 
Public Sub StopRecord() Sub StopRecord()
315
316
waveInReset(m_hwi)
317
m_recording = False
318
319
End Sub
320
321
322 
Public Sub Dispose() Sub Dispose() Implements IDisposable.Dispose
323
324
StopRecord()
325
FreeWaveBuffers()
326
327
End Sub
328
329
End Class
330
331
332
Protected Class SoundMessageWindow
333
Inherits MessageWindow
334
335
Public Const MM_WIM_OPEN As Integer = &H3BE
336
Public Const MM_WIM_CLOSE As Integer = &H3BF
337
Public Const MM_WIM_DATA As Integer = &H3C0
338
339
' Instance of a recording interface
340
Protected m_wi As WaveIn = Nothing
341
342 
Public Sub New() Sub New(ByVal wi As WaveIn)
343
m_wi = wi
344
End Sub
345
346 
Protected Overrides Sub WndProc() Overrides Sub WndProc(ByRef msg As Message)
347
348
Select Case (msg.Msg)
349
' When this message is encountered, a block is
350
' done recording, so notify the WaveIn instance.
351
Case MM_WIM_DATA
352
If Not (m_wi Is Nothing) Then
353
m_wi.BlockDone()
354
End If
355
End Select
356
357
MyBase.WndProc(msg)
358
359
End Sub
360
361
End Class
362
363
364
Protected m_msgWindow As SoundMessageWindow = Nothing
365
366
Protected m_file As WaveFile = Nothing
367
368 
Public Sub New() Sub New()
369
m_msgWindow = New SoundMessageWindow(Me)
370
m_file = New WaveFile
371
End Sub
372
373
374 
Public Function NumDevices() Function NumDevices() As Integer
375
Return waveInGetNumDevs()
376
End Function
377
378
379 
Public Function GetDeviceName() Function GetDeviceName(ByVal deviceId As Integer, ByRef prodName As String) As Wave.MMSYSERR
380
Dim caps As WAVEINCAPS = New WAVEINCAPS
381
Dim result As Wave.MMSYSERR = waveInGetDevCaps(deviceId, caps.Data, caps.Size)
382
383
If result <> Wave.MMSYSERR.NOERROR Then
384
Return result
385
End If
386
387
prodName = caps.szPname
388
389
Return Wave.MMSYSERR.NOERROR
390
391
End Function
392
393
394 
Public Sub BlockDone() Sub BlockDone()
395
m_file.BlockDone()
396
End Sub
397
398
399 
Public Function Preload() Function Preload(ByVal maxRecordLength_ms As Integer, ByVal bufferSize As Integer) As Wave.MMSYSERR
400
401
If Not (m_file Is Nothing) Then
402
Return m_file.Preload(0, m_msgWindow.Hwnd, maxRecordLength_ms, bufferSize)
403
End If
404
405
Return Wave.MMSYSERR.NOERROR
406
407
End Function
408
409 
Public Sub StopRecord() Sub StopRecord()
410
411
If Not (m_file Is Nothing) Then
412
m_file.StopRecord()
413
End If
414
415
End Sub
416
417
' <summary>
418
' Start recording.
419
' </summary>
420
' <returns>MMSYSERR.NOERROR if successful</returns>
421 
Public Function Start() Function Start() As Wave.MMSYSERR
422
423
If Not (m_file Is Nothing) Then
424
Return m_file.Start()
425
End If
426
427
Return Wave.MMSYSERR.NOERROR
428
429
End Function
430
>
431 
Public Function Done() Function Done() As Boolean
432
Return m_file.Done
433
End Function
434
435 
Public Function Save() Function Save(ByVal fileName As String) As Wave.MMSYSERR
436
437
If Not (m_file Is Nothing) Then
438
Return m_file.Save(fileName)
439
End If
440
441
Return Wave.MMSYSERR.NOERROR
442
443
End Function
444
445 
Public Sub Dispose() Sub Dispose()
446
447
m_msgWindow.Dispose()
448
449
If Not (m_file Is Nothing) Then
450
m_file.Dispose()
451
End If
452
453
End Sub
454
455
456
<DllImport("coredll.dll")> _
457 
Protected Shared Function waveInGetNumDevs() Shared Function waveInGetNumDevs() As Integer
458
End Function
459
460
461
<DllImport("coredll.dll")> _
462 
Private Shared Function waveInOpen() Shared Function waveInOpen(ByRef phwi As IntPtr, ByVal uDeviceID As Integer, ByVal pwfx As Wave.WAVEFORMATEX, ByVal dwCallback As IntPtr, ByVal dwInstance As Integer, ByVal fdwOpen As Integer) As Wave.MMSYSERR
463
End Function
464
465
466
<DllImport("coredll.dll")> _
467 
Private Shared Function waveInPrepareHeader() Shared Function waveInPrepareHeader(ByVal hwi As IntPtr, ByVal pwh As Wave.WAVEHDR, ByVal cbwh As Integer) As Wave.MMSYSERR
468
End Function
469
470
<DllImport("coredll.dll")> _
471 
Private Shared Function waveInUnprepareHeader() Shared Function waveInUnprepareHeader(ByVal hwi As IntPtr, ByVal pwh As Wave.WAVEHDR, ByVal cbwh As Integer) As Wave.MMSYSERR
472
End Function
473
474
<DllImport("coredll.dll")> _
475 
Protected Shared Function waveInClose() Shared Function waveInClose(ByVal hwi As IntPtr) As Wave.MMSYSERR
476
End Function
477
478
<DllImport("coredll.dll")> _
479 
Protected Shared Function waveInReset() Shared Function waveInReset(ByVal hwi As IntPtr) As Wave.MMSYSERR
480
End Function
481
482
<DllImport("coredll.dll")> _
483 
Protected Shared Function waveInStart() Shared Function waveInStart(ByVal hwi As IntPtr) As Wave.MMSYSERR
484
End Function
485
486
<DllImport("coredll.dll")> _
487 
Protected Shared Function waveInStop() Shared Function waveInStop(ByVal hwi As IntPtr) As Wave.MMSYSERR
488
End Function
489
490
<DllImport("coredll.dll")> _
491 
Private Shared Function waveInAddBuffer() Shared Function waveInAddBuffer(ByVal hwi As IntPtr, ByVal pwh As Wave.WAVEHDR, ByVal cbwh As Integer) As Wave.MMSYSERR
492
End Function
493
494
495
Protected Class WAVEINCAPS
496
497
Const WAVEINCAPS_SIZE As Integer = 80
498
499 
Private m_data() m_data() As Byte = Nothing
500
501 
Public ReadOnly Property Size() ReadOnly Property Size()
502
Get
503
Return WAVEINCAPS_SIZE
504
End Get
505
End Property
506
507 
Public ReadOnly Property wMid() ReadOnly Property wMid()
508
Get
509
Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 0))
510
End Get
511
End Property
512
513 
Public ReadOnly Property wPid() ReadOnly Property wPid()
514
Get
515
Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 2))
516
End Get
517
End Property
518
519 
Public ReadOnly Property vDriverVersion() ReadOnly Property vDriverVersion()
520
Get
521
Return Convert.ToInt32(BitConverter.ToUInt32(m_data, 4))
522
End Get
523
End Property
524
525 
Public ReadOnly Property dwFormats() ReadOnly Property dwFormats()
526
Get
527
Return Convert.ToInt32(BitConverter.ToUInt32(m_data, 72))
528
End Get
529
End Property
530
531 
Public ReadOnly Property wChannels() ReadOnly Property wChannels()
532
Get
533
Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 76))
534
End Get
535
End Property
536
537 
Public ReadOnly Property wReserved1() ReadOnly Property wReserved1()
538
Get
539
Return Convert.ToInt32(BitConverter.ToUInt16(m_data, 78))
540
End Get
541
End Property
542
543 
Public ReadOnly Property szPname() ReadOnly Property szPname()
544
Get
545
Dim bytes(31) As Char
546
Dim i As Integer
547
For i = 0 To 31
548
bytes(i) = Convert.ToChar(BitConverter.ToUInt16(m_data, i * 2 + 8))
549
Next
550
551
Return New String(bytes)
552
553
End Get
554
End Property
555
556 
Public Sub New() Sub New()
557
m_data = New Byte(WAVEINCAPS_SIZE - 1) {}
558
End Sub
559
560 
Public ReadOnly Property Data() ReadOnly Property Data()
561
Get
562
Return m_data
563
End Get
564
End Property
565
566
End Class
567
568
569
<DllImport("coredll.dll")> _
570 
Protected Shared Function waveInGetDevCaps() Shared Function waveInGetDevCaps(ByVal uDeviceID As Integer, ByVal pwic() As Byte, ByVal cbwic As Integer) As Wave.MMSYSERR
571
End Function
572
573 
Public Shared Sub TestProc() Shared Sub TestProc(ByVal showLine As ListBox)
574
575
Dim wi As WaveIn = Nothing
576
577
Try
578
wi = New WaveIn
579
580
Dim numDevices As Integer = wi.NumDevices()
581
If numDevices < 1 Then
582
showLine.Items.Add("FAILURE: No valid sound drivers detected")
583
Return
584
End If
585
586
showLine.Items.Add(String.Format("{0} device{1} detected:", numDevices, IIf(numDevices <> 1, "s", "")))
587
Dim i As Integer
588
For i = 0 To numDevices - 1
589
Dim prodName As String = ""
590
If Wave.MMSYSERR.NOERROR <> wi.GetDeviceName(i, prodName) Then
591
showLine.Items.Add(String.Format(" {0}: Failed to get name", i))
592
Else
593
showLine.Items.Add(String.Format(" {0}: {1}", i, prodName))
594
End If
595
Next
596
597
598
showLine.Items.Add("Setting max time to 3 seconds")
599
showLine.Items.Add("Using 256KB buffers")
600
If Wave.MMSYSERR.NOERROR <> wi.Preload(3000, 256 * 1024) Then
601
showLine.Items.Add("FAILURE: Failed to preload buffers")
602
End If
603
604
showLine.Items.Add("Starting recording...")
605
If Wave.MMSYSERR.NOERROR <> wi.Start() Then
606
showLine.Items.Add("FAILURE: Failed to start recording")
607
End If
608
609
showLine.Items.Add("Waiting for 2 seconds...")
610
Thread.Sleep(2000)
611
612
showLine.Items.Add("Stopping recording early")
613
wi.StopRecord()
614
615
Dim fileName As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
616
fileName = Path.GetDirectoryName(fileName)
617
fileName = Path.Combine(fileName, "test.wav")
618
showLine.Items.Add("Saving file test.wav")
619
620
If Wave.MMSYSERR.NOERROR <> wi.Save(fileName) Then
621
showLine.Items.Add("FAILURE: Failed to save file")
622
End If
623
624
Finally
625
626
If Not (wi Is Nothing) Then
627
wi.Dispose()
628
End If
629
630
End Try
631
632
End Sub
633
634
End Class
Step7:插入表單程式碼


Imports ...System.IO
Imports System.Threading
Public Class Form1
Dim wi As New WaveIn

Private Sub Button1_Click() Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
Try
If Button1.Text = "開始" Then
ListBox1.Items.Clear()
Dim numDevices As Integer = wi.NumDevices()
If numDevices < 1 Then
ListBox1.Items.Add("FAILURE: No valid sound drivers detected")
Return
End If
ListBox1.Items.Add(String.Format("{0} device{1} detected:", numDevices, IIf(numDevices <> 1, "s", "")))
Dim i As Integer
For i = 0 To numDevices - 1
Dim prodName As String = ""
If Wave.MMSYSERR.NOERROR <> wi.GetDeviceName(i, prodName) Then
ListBox1.Items.Add(String.Format(" {0}: Failed to get name", i))
Else
ListBox1.Items.Add(String.Format(" {0}: {1}", i, prodName))
End If
Next
ListBox1.Items.Add("Setting max time to 3 seconds")
ListBox1.Items.Add("Using 256KB buffers")
If Wave.MMSYSERR.NOERROR <> wi.Preload(3000, 256 * 1024) Then
ListBox1.Items.Add("FAILURE: Failed to preload buffers")
End If
ListBox1.Items.Add("Starting recording...")
If Wave.MMSYSERR.NOERROR <> wi.Start() Then
ListBox1.Items.Add("FAILURE: Failed to start recording")
End If
Button1.Text = "停止"
Else
ListBox1.Items.Add("Waiting for 2 seconds...")
Thread.Sleep(2000)
ListBox1.Items.Add("Stopping recording early")
wi.StopRecord()
Dim fileName As String = System.Reflection.Assembly.GetExecutingAssembly().GetName().CodeBase
fileName = Path.GetDirectoryName(fileName)
fileName = Path.Combine(fileName, "test.wav")
ListBox1.Items.Add("Saving file test.wav")
If Wave.MMSYSERR.NOERROR <> wi.Save(fileName) Then
ListBox1.Items.Add("FAILURE: Failed to save file")
Exit Sub
End If
Dim mail As New Microsoft.WindowsMobile.PocketOutlook.EmailMessage
Dim Session As New Microsoft.WindowsMobile.PocketOutlook.OutlookSession
mail.To.Add(New Microsoft.WindowsMobile.PocketOutlook.Recipient("kylin1979@gmail.com"))
mail.Subject = "Voice Mail"
mail.BodyText = "TEST"
mail.Attachments.Add(New Microsoft.WindowsMobile.PocketOutlook.Attachment(fileName))
mail.Send(Session.EmailAccounts.Item("Gmail"))
ListBox1.Items.Add("Send Mail")
Button1.Text = "開始"
End If
Finally
End Try
End Sub
End Class
Step8:按下偵錯\開始偵錯來部署應用程式測試一下

Step9:按下畫面開始鍵,就可以開始錄音了說完就按下停止鍵

Step10:按下停止鍵後就會把我們剛才的錄音送到指定的信箱裡面去

Step11:接著我們來看一下我剛才指的mail 收一下,看看是否剛才錄音有成功

Step12:源碼下載