といいますのも、曲の最初の部分での現在位置の表示が1秒ではなくて2秒になっています。デバッグしてMCI_STATUS_PARMSのdwReturnをMCI_MSF_SECONDで変換して出力させても始めは1秒ではなくて2秒目からになってしまいます。
一応全ソースを載せておきます。長いですが。
コード: 全て選択
'-----------------------------------------------------------------------------
' イベント プロシージャ
'-----------------------------------------------------------------------------
' このファイルには、ウィンドウ [MainWnd] に関するイベントをコーディングします。
' ウィンドウ ハンドル: hMainWnd
' TODO: この位置にグローバルな変数、構造体、定数、関数を定義します。
'グローバル変数宣言 ここから
Const ID_TIMER = 100 'タイマーのID
Dim mop As MCI_OPEN_PARMS 'MCI_OPEN_PARMS構造体
Dim AllTrackNum As Long 'CDのトラック数
Dim TrackNum As Long '再生中のトラック番号
Dim NowMusicMinute As Long '再生中のトラックの長さ(分)
Dim NowMusicSecond As Long '再生中のトラックの長さ(秒)
Dim BeforeMusicLong As QWord '前まで再生した長さ
'ここまで
TrackNum=1
'CD用MCIデバイスをオープンする自作関数
Function OpenMciDevice() As Long
Dim dwError As DWord '
Dim buffer[255] As Byte 'MCIエラーを格納する変数
mop.dwCallback=hMainWnd '
mop.lpstrDeviceType="cdaudio" 'デバイスタイプを設定
dwError=mciSendCommand(0, MCI_OPEN, 'MCIデバイスを
MCI_WAIT or MCI_OPEN_TYPE, mop) 'オープン
If dwError Then '
mciGetErrorString(dwError, buffer, 255) 'MCIエラーを取得
MessageBox(hMainWnd, Ex"デバイスのオープンに失敗\r\n" + buffer, "Error - LightCDPlayer", MB_OK or MB_ICONSTOP)
'戻り値を設定
OpenMciDevice=0
Else
OpenMciDevice=1
End If
End Function
'MCIデバイスを閉じる自作関数
Sub CloseMciDevice()
Dim dwDummy As DWord
mciSendCommand(mop.wDeviceID, MCI_CLOSE, MCI_WAIT, dwDummy)
mop.wDeviceID=0
End Sub
'トラック数を取得する自作関数
Sub GetTrackNum()
Dim dwError As DWord
Dim buffer[255] As Byte
If mop.wDeviceID Then
'再生中なら停止
SendMessage(hMainWnd, WM_COMMAND, StopButton, 0)
End If
If OpenMciDevice()=0 Then Exit Sub
'デバイスが準備未了かトレイが開いている時は終わる
Dim msp As MCI_STATUS_PARMS
msp.dwItem=MCI_STATUS_MODE
dwError=mciSendCommand(mop.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, msp)
If msp.dwReturn=MCI_MODE_NOT_READY Then
CloseMciDevice()
Exit Sub
End If
'トラック数を取得
msp.dwItem=MCI_STATUS_NUMBER_OF_TRACKS
dwError=mciSendCommand(mop.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, msp)
If dwError Then
'MCIデバイスを閉じる
CloseMciDevice()
Exit Sub
End If
AllTrackNum = msp.dwReturn
'トラック情報を表示する
TrackNum = 1
GetTrackLong(TrackNum)
wsprintf(buffer, "Track:01 - 0:00/%d:%02d", NowMusicMinute, NowMusicSecond)
SetDlgItemText(hMainWnd, Static_TrackInfo, buffer)
BeforeMusicLong = NowMusicMinute * 60 + NowMusicSecond
'[PlayButton][NextmButton]を有効化する
EnableWindow(GetDlgItem(hMainWnd, PlayButton), TRUE)
EnableWindow(GetDlgItem(hMainWnd, NextmButton), TRUE)
'MCIデバイスを閉じる
CloseMciDevice()
End Sub
'CDトラックの長さを取得する自作関数
Sub GetTrackLong(TrackNum As Long)
Dim msep As MCI_SET_PARMS
Dim msp As MCI_STATUS_PARMS
Dim sw As Long
If mop.wDeviceID=0 Then
'デバイスをオープン
If OpenMciDevice()=0 Then Exit Sub
sw = 1
End If
'時刻形式にMSFを指定
msep.dwTimeFormat = MCI_FORMAT_MSF
mciSendCommand(mop.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, msep)
'TrackNumに格納されたトッラクの長さを取得
msp.dwItem=MCI_STATUS_LENGTH
msp.dwTrack=TrackNum
mciSendCommand(mop.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM or MCI_TRACK, msp)
'NowMusicMinuteとNowMusicSecondにトラックの長さを格納
NowMusicMinute = MCI_MSF_MINUTE(msp.dwReturn)
NowMusicSecond = MCI_MSF_SECOND(msp.dwReturn)
If sw Then
CloseMciDevice()
End If
End Sub
'-----------------------------------------------------------------------------
' ウィンドウメッセージを処理するためのコールバック関数
Function MainWndProc(hWnd As DWord, dwMsg As DWord, wParam As DWord, lParam As DWord) As DWord
' TODO: この位置にウィンドウメッセージを処理するためのコードを記述します。
' イベントプロシージャの呼び出しを行います。
MainWndProc=EventCall_MainWnd(hWnd,dwMsg,wParam,lParam)
End Function
'-----------------------------------------------------------------------------
' ここから下は、イベントプロシージャを記述するための領域になります。
Sub MainWnd_Destroy()
If mop.wDeviceID Then
SendMessage(hMainWnd, WM_COMMAND, StopButton, 0)
End If
lcdplyr_DestroyObjects()
PostQuitMessage(0)
End Sub
Sub MainWnd_Create(ByRef CreateStruct As CREATESTRUCT)
Dim buffer[255] As Byte
'ボタンにアイコンを表示させる
SendMessage(GetDlgItem(hMainWnd, BackmButton), BM_SETIMAGE, IMAGE_ICON, LoadIcon(CreateStruct.hInstance, IDI_ICON1))
SendMessage(GetDlgItem(hMainWnd, PlayButton), BM_SETIMAGE, IMAGE_ICON, LoadIcon(CreateStruct.hInstance, IDI_ICON5))
SendMessage(GetDlgItem(hMainWnd, PauseButton), BM_SETIMAGE, IMAGE_ICON, LoadIcon(CreateStruct.hInstance, IDI_ICON4))
SendMessage(GetDlgItem(hMainWnd, StopButton), BM_SETIMAGE, IMAGE_ICON, LoadIcon(CreateStruct.hInstance, IDI_ICON6))
SendMessage(GetDlgItem(hMainWnd, NextmButton), BM_SETIMAGE, IMAGE_ICON, LoadIcon(CreateStruct.hInstance, IDI_ICON3))
SendMessage(GetDlgItem(hMainWnd, EjectButton), BM_SETIMAGE, IMAGE_ICON, LoadIcon(CreateStruct.hInstance, IDI_ICON2))
'MainWndを画面の真ん中に移動
Dim MainWndRect As RECT
GetWindowRect(hMainWnd, MainWndRect)
SetWindowPos(hMainWnd, 0,_
(GetSystemMetrics(SM_CXSCREEN) - MainWndRect.right + MainWndRect.left) \ 2,_
(GetSystemMetrics(SM_CYSCREEN) - MainWndRect.bottom + MainWndRect.top) \ 2,_
0, 0, SWP_NOSIZE or SWP_NOZORDER)
'トラック数を取得する
GetTrackNum()
End Sub
Sub MainWnd_EjectButton_Click()
If mop.wDeviceID Then
'再生中のときは停止
SendMessage(hMainWnd, WM_COMMAND, StopButton, 0)
End If
'MCIデバイスをオープン
If OpenMciDevice()=0 Then Exit Sub
'CDを取り出す
mciSendCommand(mop.wDeviceID, MCI_SET, MCI_SET_DOOR_OPEN, ByVal 0)
'デバイスを閉じる
CloseMciDevice()
'再生・一時停止・停止・戻す・送るボタンを無効化する
EnableWindow(GetDlgItem(hMainWnd, PlayButton), 0)
EnableWindow(GetDlgItem(hMainWnd, PauseButton), 0)
EnableWindow(GetDlgItem(hMainWnd, StopButton), 0)
EnableWindow(GetDlgItem(hMainWnd, BackmButton), 0)
EnableWindow(GetDlgItem(hMainWnd, NextmButton), 0)
End Sub
Sub MainWnd_ReLoadButton_Click()
GetTrackNum()
End Sub
Sub MainWnd_PlayButton_Click()
'変数宣言
Dim MciError As DWord
Dim buffer[255] As Byte
Dim msep As MCI_SET_PARMS
Dim msp As MCI_STATUS_PARMS
Dim mpp As MCI_PLAY_PARMS
Dim MciParms As DWord
If mop.wDeviceID=0 Then
'新しくMCIデバイスをオープンする
If OpenMciDevice()=0 Then Exit Sub
'演奏を開始
'時刻形式にTMSFを指定
msep.dwTimeFormat = MCI_FORMAT_TMSF
mciSendCommand(mop.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, msep)
mpp.dwCallback=hMainWnd
mpp.dwFrom=MCI_MAKE_TMSF(TrackNum, 0, 0, 0)
If TrackNum=AllTrackNum Then
MciParms = MCI_FROM or MCI_NOTIFY
Else
mpp.dwTo=MCI_MAKE_TMSF(TrackNum, NowMusicMinute, NowMusicSecond, 0)
MciParms=MCI_FROM or MCI_TO or MCI_NOTIFY
End If
MciError=mciSendCommand(mop.wDeviceID, MCI_PLAY, MciParms, mpp)
Else
'一時停止、シーク時からの復帰の時
'再生
mpp.dwCallback=hMainWnd
If TrackNum=AllTrackNum Then
MciParms=MCI_NOTIFY
Else
mpp.dwTo=MCI_MAKE_TMSF(TrackNum + 1, NowMusicMinute, NowMusicSecond, 0)
MciParms=MCI_TO or MCI_NOTIFY
End If
MciError=mciSendCommand(mop.wDeviceID, MCI_PLAY, MciParms, mpp)
End If
If MciError Then
'再生時にエラーが起きた時
mciGetErrorString(MciError, buffer, 255)
MessageBox(hMainWnd, Ex"再生に失敗。\r\n" + buffer, "Error - LightCDPlayer", MB_OK or MB_ICONSTOP)
'MCIデバイスを閉じる
CloseMciDevice()
Exit Sub
End If
'再生ボタンを無効化し、一時停止・停止ボタンを有効化する
EnableWindow(GetDlgItem(hMainWnd, PlayButton), 0)
EnableWindow(GetDlgItem(hMainWnd, PauseButton), 1)
EnableWindow(GetDlgItem(hMainWnd, StopButton), 1)
'タイマー処理を開始する
SetTimer(hMainWnd, ID_TIMER, 100, 0)
End Sub
Sub MainWnd_PauseButton_Click()
Dim buffer[255] As Byte
'一時停止
mciSendCommand(mop.wDeviceID, MCI_PAUSE, 0, ByVal 0)
'再生・停止ボタンを有効化し、一時停止ボタンを無効化する
EnableWindow(GetDlgItem(hMainWnd, PlayButton), 1)
EnableWindow(GetDlgItem(hMainWnd, PauseButton), 0)
EnableWindow(GetDlgItem(hMainWnd, StopButton), 1)
'タイマー処理を終了する
KillTimer(hMainWnd, ID_TIMER)
End Sub
Sub MainWnd_StopButton_Click()
Dim MciErr As Long
Dim dwCallBack As DWord
Dim buffer[255] As Byte
'停止
MciErr=mciSendCommand(mop.wDeviceID, MCI_STOP, MCI_WAIT, dwCallBack)
If MciErr Then
MessageBox(hMainWnd, "音楽の停止に失敗", "Error - LightCDPlayer", MB_OK or MB_ICONSTOP)
ExitSub
End If
'デバイスを閉じる
CloseMciDevice()
'再生ボタンを有効化し、一時停止・停止ボタンを無効化する
EnableWindow(GetDlgItem(hMainWnd, PlayButton), 1)
EnableWindow(GetDlgItem(hMainWnd, PauseButton), 0)
EnableWindow(GetDlgItem(hMainWnd, StopButton), 0)
'トラック情報を更新する
GetTrackLong(TrackNum)
wsprintf(buffer, "Track:%02d - 0:00/%d:%02d", TrackNum, NowMusicMinute, NowMusicSecond)
SetDlgItemText(hMainWnd, Static_TrackInfo, buffer)
'タイマー処理を終了する
KillTimer(hMainWnd, ID_TIMER)
End Sub
Sub MainWnd_NextmButton_Click()
Dim buffer[255] As Byte, dwCallBack As DWord
If TrackNum<>AllTrackNum Then
TrackNum=TrackNum + 1
If TrackNum=AllTrackNum Then
EnableWindow(GetDlgItem(hMainWnd, NextmButton), 0)
End If
EnableWindow(GetDlgItem(hMainWnd, BackmButton), 1)
ElseIf TrackNum=AllTrackNum Then
Exit Sub
End If
'トラック情報を表示
GetTrackLong(TrackNum)
BeforeMusicLong = BeforeMusicLong + ((NowMusicMinute * 60) + NowMusicSecond)
wsprintf(buffer, "Track:%02d - 0:00/%d:%02d", TrackNum, NowMusicMinute, NowMusicSecond)
SetDlgItemText(hMainWnd, Static_TrackInfo, buffer)
If mop.wDeviceID Then
'再生中のとき
mciSendCommand(mop.wDeviceID, MCI_STOP, MCI_WAIT, dwCallBack)
CloseMciDevice()
SendMessage(hMainWnd, WM_COMMAND, PlayButton, 0)
End If
End Sub
Sub MainWnd_BackmButton_Click()
Dim buffer[255] As Byte, dwCallBack As DWord
If TrackNum<>1 Then
TrackNum=TrackNum - 1
If TrackNum=1 Then
EnableWindow(GetDlgItem(hMainWnd, BackmButton), 0)
End If
EnableWindow(GetDlgItem(hMainWnd, NextmButton), 1)
ElseIf TrackNum=AllTrackNum Then
Exit Sub
End If
BeforeMusicLong = BeforeMusicLong - ((NowMusicMinute * 60) + NowMusicSecond)
'トラック情報を表示
GetTrackLong(TrackNum)
wsprintf(buffer, "Track:%02d - 0:00/%d:%02d", TrackNum, NowMusicMinute, NowMusicSecond)
SetDlgItemText(hMainWnd, Static_TrackInfo, buffer)
If mop.wDeviceID Then
'再生中のとき
mciSendCommand(mop.wDeviceID, MCI_STOP, MCI_WAIT, dwCallBack)
CloseMciDevice()
SendMessage(hMainWnd, WM_COMMAND, PlayButton, 0)
End If
End Sub
Sub MainWnd_MciNotify(flags As Long, DevID As DWord)
If flags=MCI_NOTIFY_SUCCESSFUL Then
If TrackNum<>AllTrackNum Then
Dim dwCallBack As DWord
TrackNum=TrackNum + 1
If TrackNum=AllTrackNum Then
EnableWindow(GetDlgItem(hMainWnd, NextmButton), 0)
End If
EnableWindow(GetDlgItem(hMainWnd, BackmButton), 1)
mciSendCommand(mop.wDeviceID, MCI_STOP, MCI_WAIT, dwCallBack)
CloseMciDevice()
GetTrackLong(TrackNum)
BeforeMusicLong = BeforeMusicLong + ((NowMusicMinute * 60) + NowMusicSecond)
SendMessage(hMainWnd, WM_COMMAND, PlayButton, 0)
Else TrackNum=AllTrackNum Then
SendMessage(hMainWnd, WM_COMMAND, StopButton, 0)
End If
End If
End Sub
Sub MainWnd_VersionButton_Click()
DialogBox(hMainWnd, "VerDlg")
End Sub
Sub MainWnd_QueryClose(ByRef cancel As Integer)
If mop.wDeviceID and IsWindowEnabled(GetDlgItem(hMainWnd, PlayButton))=FALSE Then
'もし再生中なら確認メッセージをだす。
'ユーザーが「いいえ」を選んだらcancel変数に1を格納し終了させない
If MessageBox(hMainWnd, "再生中です。終了しますか?", "LigthCDPlayer", MB_YESNO or MB_ICONQUESTION)=IDNO Then
cancel=1
End If
End If
End Sub
Sub MainWnd_Timer(TimerID As DWord)
If TimerID=ID_TIMER Then
Dim msep As MCI_SET_PARMS 'MCI_SET_PARMS構造体
Dim msp As MCI_STATUS_PARMS 'MCI_STATUS_PARMS構造体
Dim buffer[255] As Byte '文字列格納用
Dim MusicMinute As Long 'CDで現在再生している位置(分)
Dim MusicSecond As Long 'CDで現在再生している位置(秒)
Dim temp As DWord '数字一時格納用
Dim ReturnMinute As Long '現在位置取得の戻り値(分)
Dim ReturnSecond As Long '現在位置取得の戻り値(秒)
'時刻形式にMSFを設定
msep.dwTimeFormat = MCI_FORMAT_MSF
mciSendCommand(mop.wDeviceID, MCI_SET, MCI_SET_TIME_FORMAT, msep)
'再生中のトラックの現在位置を取得
msp.dwItem=MCI_STATUS_POSITION
mciSendCommand(mop.wDeviceID, MCI_STATUS, MCI_STATUS_ITEM, msp)
ReturnMinute=MCI_MSF_MINUTE(msp.dwReturn)
ReturnSecond=MCI_MSF_SECOND(msp.dwReturn)
'現在位置を計算する
If TrackNum<>1 Then
temp = NowMusicMinute * 60 + NowMusicSecond - (BeforeMusicLong - (ReturnMinute * 60 + ReturnSecond))
If temp >= 60 Then
MusicMinute = temp \ 60
MusicSecond = temp - (MusicMinute * 60)
Else
MusicMinute = 0
MusicSecond = temp
End If
Else
MusicMinute=ReturnMinute
MusicSecond=ReturnSecond
End If
'トラック情報を更新する
wsprintf(buffer, "Track:%02d - %d:%02d/%d:%02d", TrackNum, MusicMinute, MusicSecond, NowMusicMinute, NowMusicSecond)
SetDlgItemText(hMainWnd, Static_TrackInfo, buffer)
End If
End Sub