Hi, All! (https://wasm.in/styles/smiles_s/smile3.gif)
PlaySound with SND_MEMORY is not suitable.
Preferably via mciwioOpen/mciwioPlay or any other options. . .
Thank you!
Hi Mikl__,
did you already gave BASS.DLL (http://www.un4seen.com/) a try ?
Hello, Greenhorn!
Thanks for the tip, no, I haven't tried it, now I'll read about this dll
Hi Mikl,
; #########################################################################
;
; This demo shows how to use the new bitmap button custom control in
; MASM32 library. This control allows you to use any UP & DOWN bitmap
; you like so you can use non rectangular shapes if you bother to
; match the bitmap back colour to the colour of the client area.
;
; These 2 bitmaps were created by "Novatrix" from New Zealand.
;
; #########################################################################
.386
.model flat, stdcall ; 32 bit memory model
option casemap :none ; case sensitive
include bmpbutns.inc ; local includes for this file
include \masm32\include\winmm.inc
Include \masm32\macros\macros.asm
includelib \masm32\lib\winmm.lib
; #########################################################################
; --------------------------------------------------------
PlayMp3File PROTO :DWORD,:DWORD
; --------------------------------------------------------
.data
Mp3DeviceID DD 0
Mp3Device DB "MPEGVideo",0
.data?
.code
start:
invoke GetModuleHandle, NULL
mov hInstance, eax
invoke GetCommandLine
mov CommandLine, eax
invoke WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
invoke ExitProcess,eax
; #########################################################################
WinMain proc hInst :DWORD,
hPrevInst :DWORD,
CmdLine :DWORD,
CmdShow :DWORD
;====================
; Put LOCALs on stack
;====================
LOCAL wc :WNDCLASSEX
LOCAL msg :MSG
LOCAL Wwd :DWORD
LOCAL Wht :DWORD
LOCAL Wtx :DWORD
LOCAL Wty :DWORD
;==================================================
; Fill WNDCLASSEX structure with required variables
;==================================================
invoke LoadIcon,hInst,500 ; icon ID
mov hIcon, eax
szText szClassName,"Project_Class"
mov wc.cbSize, sizeof WNDCLASSEX
mov wc.style, CS_BYTEALIGNWINDOW
mov wc.lpfnWndProc, offset WndProc
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
m2m wc.hInstance, hInst
mov wc.hbrBackground, COLOR_BTNFACE+1
mov wc.lpszMenuName, NULL
mov wc.lpszClassName, offset szClassName
m2m wc.hIcon, hIcon
invoke LoadCursor,NULL,IDC_ARROW
mov wc.hCursor, eax
m2m wc.hIconSm, hIcon
invoke RegisterClassEx, ADDR wc
;================================
; Centre window at following size
;================================
mov Wwd, 300
mov Wht, 255
invoke GetSystemMetrics,SM_CXSCREEN
invoke TopXY,Wwd,eax
mov Wtx, eax
invoke GetSystemMetrics,SM_CYSCREEN
invoke TopXY,Wht,eax
mov Wty, eax
invoke CreateWindowEx,WS_EX_LEFT,
ADDR szClassName,
ADDR szDisplayName,
WS_OVERLAPPEDWINDOW,
Wtx,Wty,Wwd,Wht,
NULL,NULL,
hInst,NULL
mov hWnd,eax
invoke LoadMenu,hInst,600 ; menu ID
invoke SetMenu,hWnd,eax
invoke ShowWindow,hWnd,SW_SHOWNORMAL
invoke UpdateWindow,hWnd
;===================================
; Loop until PostQuitMessage is sent
;===================================
StartLoop:
invoke GetMessage,ADDR msg,NULL,0,0
cmp eax, 0
je ExitLoop
invoke TranslateMessage, ADDR msg
invoke DispatchMessage, ADDR msg
jmp StartLoop
ExitLoop:
return msg.wParam
WinMain endp
; #########################################################################
WndProc proc hWin :DWORD,
uMsg :DWORD,
wParam :DWORD,
lParam :DWORD
LOCAL var :DWORD
LOCAL caW :DWORD
LOCAL caH :DWORD
LOCAL Rct :RECT
LOCAL hDC :DWORD
LOCAL hBmp1 :DWORD
LOCAL hBmp2 :DWORD
LOCAL Ps :PAINTSTRUCT
LOCAL buffer1[128]:BYTE ; these are two spare buffers
LOCAL buffer2[128]:BYTE ; for text manipulation etc..
.if uMsg == WM_CREATE
szText msg2,"sample.mp3"
Invoke PlayMp3File, hWin, Addr msg2
.endif
.if uMsg == WM_COMMAND
.if wParam == 500
szText msg1,"Hi, you clicked the bitmap button"
invoke MessageBox,hWin,ADDR msg1,ADDR szDisplayName,MB_OK
.endif
;======== menu commands ========
.elseif uMsg == WM_CREATE
; ------------------------------------
; the one and only bitmap button call
; ------------------------------------
invoke BmpButton,hWin,0,0,203,204,500
.elseif uMsg == WM_SIZE
.elseif uMsg == WM_PAINT
invoke BeginPaint,hWin,ADDR Ps
mov hDC, eax
invoke Paint_Proc,hWin,hDC
invoke EndPaint,hWin,ADDR Ps
return 0
.elseif uMsg == WM_CLOSE
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
return 0
.endif
invoke DefWindowProc,hWin,uMsg,wParam,lParam
ret
WndProc endp
; ########################################################################
TopXY proc wDim:DWORD, sDim:DWORD
shr sDim, 1 ; divide screen dimension by 2
shr wDim, 1 ; divide window dimension by 2
mov eax, wDim ; copy window dimension into eax
sub sDim, eax ; sub half win dimension from half screen dimension
return sDim
TopXY endp
; #########################################################################
Paint_Proc proc hWin:DWORD, hDC:DWORD
LOCAL btn_hi :DWORD
LOCAL btn_lo :DWORD
LOCAL Rct :RECT
invoke GetSysColor,COLOR_BTNHIGHLIGHT
mov btn_hi, eax
invoke GetSysColor,COLOR_BTNSHADOW
mov btn_lo, eax
return 0
Paint_Proc endp
; ########################################################################
; ###############################################################
PlayMp3File proc hWin:DWORD,NameOfFile:DWORD
LOCAL mciOpenParms:MCI_OPEN_PARMS,mciPlayParms:MCI_PLAY_PARMS
mov eax,hWin
mov mciPlayParms.dwCallback,eax
mov eax,OFFSET Mp3Device
mov mciOpenParms.lpstrDeviceType,eax
mov eax,NameOfFile
mov mciOpenParms.lpstrElementName,eax
invoke mciSendCommand,0,MCI_OPEN,MCI_OPEN_TYPE or MCI_OPEN_ELEMENT,ADDR mciOpenParms
mov eax,mciOpenParms.wDeviceID
mov Mp3DeviceID,eax
invoke mciSendCommand,Mp3DeviceID,MCI_PLAY,MCI_NOTIFY,ADDR mciPlayParms
ret
PlayMp3File endp
; ###############################################################
end start
Check DSound (https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee418035(v=vs.85)), in particular IDirectSound8::CreateSoundBuffer (https://docs.microsoft.com/en-us/previous-versions/windows/desktop/ee418039(v=vs.85)) and IDirectSoundBuffer8::Play
Hi, jj2007, LiaoMi,
thank you very much!!!
Hi LiaoMi
Thanks for the code you posted above. It's cool.
Quick question. In the _mp3ringtone.zip file there are two .bmp files that are used for the button.
These two images seem to be identical. Are they supposed to be like that?
Regards
Hi, Caché GB!
masm32 --> examples --> Bill_Cravener --> PlayMP3
masm32 --> examples --> exampl01 --> bmbutton
The drawings are slightly different. There is a unpressed button in one image. There is the pressed button in another image.
Hi Mikl__
Thanks a lot.
Regards
Hi
A quick 64 bit interpretation of the two functions from BmpButton.asm, BmpButton proc
and its window procedure BmpButnProc proc.
Remember to replace the _UTF_16 macro with what ever string generation macro you use.
TITLE BmpButton in x64.
.code
;#############################################################################################################
BmpButton proc public hParent:qword, topX:dword, topY:dword, rnum1:dword, rnum2:DWORD, ID:DWORD
; parameters are,
; 1. Parent handle
; 2/3 top X & Y co-ordinates
; 4/5 resource ID numbers or identifiers for UP & DOWN bitmaps
; 6 ID number for control
local hButn1:qword
local hImage :qword
local hModule:qword
local wid:dword
local hgt:dword
local hBmpU:qword
local hBmpD:qword
local Rct:RECT
local wc:WNDCLASSEX
mov hParent, rcx
mov topX, edx
mov topY, r8d
mov rnum1, r9d
add rsp,-068h
and rsp,-10h
invoke GetModuleHandle, null
mov hModule, rax
invoke LoadBitmap, hModule, rnum1
mov hBmpU, rax
invoke LoadBitmap, hModule, rnum2
mov hBmpD, rax
_UTF_16 Bmp_Button_Class, "Bmp_Button_Class"
mov wc.cbSize, sizeof(WNDCLASSEX)
mov wc.style, CS_BYTEALIGNWINDOW
lea rax, BmpButnProc
mov wc.lpfnWndProc, rax
mov wc.cbClsExtra, null
mov wc.cbWndExtra, 16
mov rax, hModule
mov wc.hInstance, rax
mov wc.hbrBackground, COLOR_BTNFACE+1
mov wc.lpszMenuName, null
lea rax, Bmp_Button_Class
mov wc.lpszClassName, rax
mov wc.hIcon, null
invoke LoadCursor, null, IDC_ARROW
mov wc.hCursor, rax
mov wc.hIconSm, null
invoke RegisterClassEx, &wc
mov qword ptr[rsp+58h], null
mov rdx, hModule
mov qword ptr[rsp+50h], rdx
mov edx, ID
mov qword ptr[rsp+48h], rdx
mov rdx, hParent
mov qword ptr[rsp+40h], rdx
mov qword ptr[rsp+38h], 100
mov qword ptr[rsp+30h], 100
mov edx, topY
mov qword ptr[rsp+28h], rdx
mov edx, topX
mov qword ptr[rsp+20h], rdx
mov r9, WS_CHILD or WS_VISIBLE
mov r8, null
lea rdx, Bmp_Button_Class
mov rcx, WS_EX_TRANSPARENT
invoke CreateWindowEx
mov hButn1, rax
invoke SetWindowLong, hButn1, 0, hBmpU
invoke SetWindowLong, hButn1, 4, hBmpD
_UTF_16 ButnImageClass, "STATIC"
mov qword ptr[rsp+58h], null
mov rdx, hModule
mov qword ptr[rsp+50h], rdx
mov edx, ID
mov qword ptr[rsp+48h], rdx
mov rdx, hButn1
mov qword ptr[rsp+40h], rdx
mov qword ptr[rsp+38h], 0
mov qword ptr[rsp+30h], 0
mov qword ptr[rsp+28h], 0
mov qword ptr[rsp+20h], 0
mov r9, WS_CHILD or WS_VISIBLE or SS_BITMAP
mov r8, null
lea rdx, ButnImageClass
mov rcx, 0
invoke CreateWindowEx
mov hImage, rax
invoke SendMessage, hImage, STM_SETIMAGE, IMAGE_BITMAP, hBmpU
invoke GetWindowRect, hImage, &Rct
invoke SetWindowLong, hButn1, 8, hImage
mov eax, Rct.bottom
mov edx, Rct.top
sub eax, edx
mov hgt, eax
mov eax, Rct.right
mov edx, Rct.left
sub eax, edx
mov wid, eax
invoke SetWindowPos, hButn1, HWND_TOP, 0, 0, wid, hgt, SWP_NOMOVE
invoke ShowWindow, hButn1, SW_SHOW
mov rax, hButn1
ret
BmpButton endp
;#############################################################################################################
BmpButnProc proc hWin:qword, uMsg:qword, wParam:qword, lParam:qword
local hBmpU :qword
local hBmpD :qword
local hImage:qword
local hParent:qword
local ID:sdword
local ptX:dword
local ptY:dword
local bWid:dword
local bHgt:dword
local Rct:RECT
mov hWin, rcx
mov uMsg, rdx
mov wParam, r8
mov lParam, r9
add rsp,-38h
and rsp,-10h
.data
cFlag dd 0 ; a GLOBAL variable for the "clicked" setting
.code
cmp uMsg, WM_LBUTTONDOWN
jne @B0020
invoke GetWindowLong, hWin, 4
mov hBmpD, rax
invoke GetWindowLong, hWin, 8
mov hImage, rax
invoke SendMessage, hImage, STM_SETIMAGE, IMAGE_BITMAP, hBmpD
invoke SetCapture, hWin
mov cFlag, true
jmp @C0010
@B0020:
cmp uMsg, WM_LBUTTONUP
jne @C0010
cmp cFlag, false
jne @B0022
ret
@B0022:
mov cFlag, false
invoke GetWindowLong, hWin, 0
mov hBmpU, rax
invoke GetWindowLong, hWin, 8
mov hImage, rax
invoke SendMessage, hImage, STM_SETIMAGE, IMAGE_BITMAP, hBmpU
mov rax, lParam
cwde
mov ptX, eax
mov rax, lParam
rol eax, 16
cwde
mov ptY, eax
invoke GetWindowRect, hWin, &Rct
mov eax, Rct.right
mov edx, Rct.left
sub eax, edx
mov bWid, eax
mov eax, Rct.bottom
mov edx, Rct.top
sub eax, edx
mov bHgt, eax
; --------------------------------
; exclude button releases outside of the button
; rectangle from sending message back to parent
; --------------------------------
cmp ptX, 0
jle @B0040
cmp ptY, 0
jle @B0040
mov eax, bWid
cmp ptX, eax
jge @B0040
mov eax, bHgt
cmp ptY, eax
jge @B0040
invoke GetParent, hWin
mov hParent, rax
invoke GetDlgCtrlID, hWin
mov ID, eax
invoke SendMessage, hParent, WM_COMMAND, ID, hWin
@B0040:
invoke ReleaseCapture
@C0010:
invoke DefWindowProc, hWin, uMsg, wParam, lParam
ret
BmpButnProc endp
;#############################################################################################################
Hi All!
I play in synchronous mode a wav-file from a buffer in memory. The low-level functions waveOutPrepareHeader, waveOutUnprepareHeader, waveOutOpen, waveOutClose, waveOutWrite are used. There are wav-/source-/exe-files in attached; GUI #
include win64a.inc
WAVEHDR struct
lpData QWORD ?
dwBufferLength DWORD ?
dwBytesRecorded DWORD ?
dwUser QWORD ?
dwFlags DWORD ?
dwLoops DWORD ?
lpNext QWORD ?
reserved qword ?
WAVEHDR ends
WHDR_DONE equ 1
.code
WinMain proc
local hGout:qword
local p:qword
local FSize:dword
local hFile:dword
local szReadWrite:qword
local hWaveOut:qword
local lpwiocb:WAVEHDR
mov ecx,offset wav_file
invoke CreateFile,,GENERIC_READ,0,0,OPEN_EXISTING,\
FILE_ATTRIBUTE_ARCHIVE,0
mov hFile,eax
invoke GetFileSize,eax,0
mov FSize,eax
invoke GlobalAlloc,GHND or GMEM_DDESHARE,eax
mov hGout,rax
invoke GlobalLock,eax
mov p,rax
lea r9d,szReadWrite
invoke ReadFile,hFile,eax,FSize,,0
invoke CloseHandle,hFile
invoke GlobalUnlock,hGout
lea ecx,hWaveOut
xor r9,r9
mov [rsp+20h],r9
mov qword ptr[rsp+28h],WAVE_ALLOWSYNC
mov r8,p
add r8d,14h
or edx,WAVE_MAPPER
invoke waveOutOpen
lea edx,lpwiocb
mov edi,edx
xor eax,eax
mov ecx,(sizeof WAVEHDR)/8
rep stosq
mov rax,p
add rax,2Ch
mov [rdx].WAVEHDR.lpData,rax
mov eax,FSize
sub eax,2Ch
mov [rdx].WAVEHDR.dwBufferLength,eax
invoke waveOutPrepareHeader,hWaveOut,,sizeof WAVEHDR
lea edx,lpwiocb
invoke waveOutWrite,hWaveOut,,sizeof WAVEHDR
@@: test lpwiocb.dwFlags,WHDR_DONE
jz @b
lea edx,lpwiocb
invoke waveOutUnprepareHeader,hWaveOut,,sizeof WAVEHDR
invoke waveOutClose,hWaveOut
invoke RtlExitUserProcess,NULL
WinMain endp
wav_file db '03.wav',0
end
Hi Mikl,
Looks good, and looks simple :thumbsup:
What about mp3 then? There is some code here (https://windowsquestions.com/2021/08/22/playing-an-mp3-file-in-win32-using-winmm/), but the guy never got an answer :cool:
JJ, that link doesn't work. Did windowsquestions.com go off the air?