www.pudn.com > MyGiftPiano.rar > MyGiftPiano.asm


; MyGiftVisulPiano 
; Ver 1.0.0.0 
; 版权所有(C) 谷穗, 2004 
; 最后修改: 2004.12.7.(农历10.26) 
.386 
.model flat,stdcall 
option casemap:none 
 
WinMain proto :DWORD,:DWORD,:DWORD,:DWORD 
 
include \masm32\include\windows.inc 
include \masm32\include\user32.inc 
include \masm32\include\kernel32.inc 
include \masm32\include\gdi32.inc 
include \masm32\include\winmm.inc 
 
includelib \masm32\lib\user32.lib 
includelib \masm32\lib\kernel32.lib 
includelib \masm32\lib\gdi32.lib 
includelib \masm32\lib\winmm.lib 
 
 
 
.data 
ClassName db "SimpleWinClass",0 
AppName  db "MyGiftPiano 1.0",0 
szText   db "BestGiftBestFriend:MyGiftPiano,帮助请按ESC键!",0h 
szCaption	db	'祝鹏娟生日快乐!',0 
szText2		db	'数字1234567对应1个音阶的七个音.用abcde控制音阶的声高.qwrty为半音,更多信息请看同目录下的readme.txt文件!',0 
.data? 
hInstance HINSTANCE ? 
hdc HDC ? 
midiFlag BYTE ? 
midiPu DWORD ?	;MIDI消息,四个字节,处理用户按键时会用相应的信息填充进去 
				;再把此消息发送到消息队列中去,这样就把用户的按键转化为了相应的声音 
midiYu DWORD ? 
midiPlayFlag BYTE ? 
 
 
 
.code 
start: 
	;得到实例(或叫应用程序)句柄.放入eax中 
	invoke GetModuleHandle, NULL 
	mov    hInstance,eax 
	;调用WinMain主过程 
	invoke WinMain, hInstance,NULL,NULL,SW_SHOWDEFAULT 
	;结束窗口程序 
	invoke ExitProcess,eax       
 
WinMain proc hInst:HINSTANCE,hPrevInst:HINSTANCE,CmdLine:LPSTR,CmdShow:DWORD 
	LOCAL wc:WNDCLASSEX 
	LOCAL msg:MSG 
	LOCAL hwnd:HWND 
	mov   wc.cbSize,SIZEOF WNDCLASSEX 
	mov   wc.style, CS_HREDRAW or CS_VREDRAW 
	mov   wc.lpfnWndProc, OFFSET WndProc 
	mov   wc.cbClsExtra,NULL 
	mov   wc.cbWndExtra,NULL 
	push  hInst 
	pop   wc.hInstance 
	mov   wc.hbrBackground,COLOR_WINDOW+1 
	mov   wc.lpszMenuName,NULL 
	mov   wc.lpszClassName,OFFSET ClassName 
	invoke LoadIcon,NULL,IDI_APPLICATION 
	mov   wc.hIcon,eax 
	mov   wc.hIconSm,eax 
	invoke LoadCursor,NULL,IDC_ARROW 
	mov   wc.hCursor,eax 
	;注册窗口类 
	invoke RegisterClassEx, addr wc 
	;建立窗口. 
	INVOKE CreateWindowEx,NULL,ADDR ClassName,ADDR AppName,\ 
           WS_OVERLAPPEDWINDOW,CW_USEDEFAULT,\ 
           CW_USEDEFAULT,CW_USEDEFAULT,CW_USEDEFAULT,NULL,NULL,\ 
           hInst,NULL 
	mov   hwnd,eax 
	;显示窗口 
	INVOKE ShowWindow, hwnd,SW_SHOWNORMAL 
	;刷新窗口客户区. 
	INVOKE UpdateWindow, hwnd 
	;打开一个MIDI输出设备.(Musical Instrument Digital Interface), 
	;hdc为设备句柄 
      invoke midiOutOpen,ADDR hdc,-1,NULL,NULL,NULL 
      mov   midiYu,0h 
      mov   midiPlayFlag,1h 
	.WHILE TRUE 
				;取得、转换(如:将扫描码转换成ASCII码)、分派消息. 
				;这三者组成一个消息循环,不断循环的来处理WINDOWS消息 
                INVOKE GetMessage, ADDR msg,NULL,0,0 
				;eax是用来控制当消息队列为空时把程序的控制权交给程序, 
				;如果不这样将会导致窗口会陷入无穷无尽的消息循环当中的!! 
                .BREAK .IF (!eax) 
                INVOKE TranslateMessage, ADDR msg 
                INVOKE DispatchMessage, ADDR msg 
	.ENDW 
	mov     eax,msg.wParam 
	ret 
WinMain endp 
;窗口过程.处理消息的.HWND为windows回调时基于的窗口的窗口句柄. 
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM 
		local	 @stPs:PAINTSTRUCT 
		local	 @stRect:RECT 
		local	 @hDc   
            local   @playf:WORD 
 
	.IF uMsg==WM_DESTROY 
             invoke midiOutClose,hdc 
		    invoke PostQuitMessage,NULL 
                     
      .ELSEIF uMsg ==WM_PAINT 
			;发送WM_ERASEBKGND消息来擦除背景. 
			;WM_ERASEBKGND消息是用窗口类结构中的hbrBackground刷子来绘画窗口背景 
			invoke	BeginPaint,hWnd,addr @stPs 
			mov	      @hDc,eax 
			invoke	GetClientRect,hWnd,addr @stRect 
			invoke	DrawText,@hDc,addr szText,-1,\ 
				addr @stRect,\ 
				DT_SINGLELINE or DT_CENTER or DT_VCENTER 
			invoke	EndPaint,hWnd,addr @stPs 
      .ELSEIF uMsg==WM_CHAR 
      mov @playf,0h 
      push wParam 
      pop midiPu 
;===============ESC键的功能: 弹出一个消息框================ 
          .if midiPu==WM_DEVMODECHANGE                  ;1bh 
          ; invoke midiOutClose,hdc 
 
	    	invoke	MessageBox,NULL,offset szText2,offset szCaption,MB_OK 
          .ENDIF 
;---------------------------------------- 
 
		;用abcde控制音阶的声高 
        .if midiPu==61h;按下a 
        mov midiYu,-24 
        .elseif midiPu==62h;按下b 
        mov midiYu,-12 
        .elseif midiPu==63h;按下c 
        mov midiYu,0 
        .elseif midiPu==64h;按下d 
        mov midiYu,12 
        .elseif midiPu==65h;按下f 
        mov midiYu,24 
       
        ;===============全音============================ 
        .elseif midiPu==31h;按下1 
        mov midiPu,3ch 
        mov @playf,1 
        .elseif midiPu==32h 
        mov midiPu,3eh 
        mov @playf,1 
        .elseif midiPu==33h 
        mov midiPu,40h 
        mov @playf,1 
        .elseif midiPu==34h 
        mov midiPu,41h 
        mov @playf,1 
        .elseif midiPu==35h 
        mov midiPu,43h 
        mov @playf,1 
        .elseif midiPu==36h 
        mov midiPu,45h 
        mov @playf,1 
        .elseif midiPu==37h 
        mov midiPu,47h 
        mov @playf,1 
        ;================半音=========================== 
         .elseif  midiPu==71h;按下q 
         mov midiPu,3dh 
         mov @playf,1 
         .elseif  midiPu==77h;按下w 
         mov midiPu,3fh 
         mov @playf,1 
         .elseif  midiPu==72h;按下r 
         mov midiPu,42h 
         mov @playf,1 
         .elseif  midiPu==74h;按下t 
         mov midiPu,44h 
         mov @playf,1 
         .elseif  midiPu==79h;按下y 
         mov midiPu,46h 
         mov @playf,1 
         .endif 
        ;----------处理半音------------------- 
          .if @playf==1 
            mov eax,midiYu 
            add midiPu,eax 
            mov cl,8 
            shl midiPu,cl 
            and midiPu,0ff00h 
            add midiPu,680090h 
           .if midiPlayFlag==1h 
            ;================调用声卡的代码======================       
         
            invoke midiOutShortMsg,hdc,midiPu 
            mov  midiPlayFlag,0h 
            ;-------------------声卡代码结束------------------------ 
            .endif 
            .endif 
	.ELSEIF uMsg==WM_KEYUP 
      	    mov midiPlayFlag,1h 
	.ELSE 
		invoke DefWindowProc,hWnd,uMsg,wParam,lParam 
		ret 
	.ENDIF 
	xor    eax,eax 
	ret 
WndProc endp 
end start