www.pudn.com > WinceWave.rar > WavGraph.cpp


// WavGraph.cpp : Defines the entry point for the application. 
// 
 
#include "stdafx.h" 
#include "WavGraph.h" 
#include  
#include  
#include  
 
#include  
#include "waveinfo.h" 
#include "winDev.h" 
 
#include "bitmap.h" 
 
#include "fft.h" 
 
#define MAX_LOADSTRING 100 
 
// Global Variables: 
HINSTANCE			hInst;					// The current instance 
HWND				hwndCB;					// The command bar handle 
 
HWND				g_hWnd; 
HDC					g_memdc; 
HBITMAP				g_bitmap; 
RGBTRIPLE			*g_buffer; 
long				g_bufsize; 
BOOL				g_started=FALSE; 
recctx				g_ctx; 
RECT				g_rect; 
BOOL				g_waveform=TRUE; 
BOOL				g_freqence=FALSE; 
DOUBLE				g_real[256],g_image[256]; 
 
static SHACTIVATEINFO s_sai; 
 
// Forward declarations of functions included in this code module: 
ATOM				MyRegisterClass	(HINSTANCE, LPTSTR); 
BOOL				InitInstance	(HINSTANCE, int); 
LRESULT CALLBACK	WndProc			(HWND, UINT, WPARAM, LPARAM); 
LRESULT CALLBACK	About			(HWND, UINT, WPARAM, LPARAM); 
HWND				CreateRpCommandBar(HWND); 
 
BOOL StartDevice(); 
void StopDevice(); 
int	cbdatain(recctx *pctx,unsigned char *buf,int buflen); 
void DrawWave(RGBTRIPLE *buffer,int width,int height,unsigned char *pts,long npt); 
void DrawFreq(RGBTRIPLE *buffer,int width,int height,unsigned char *pts,long npt); 
 
int WINAPI WinMain(	HINSTANCE hInstance, 
					HINSTANCE hPrevInstance, 
					LPTSTR    lpCmdLine, 
					int       nCmdShow) 
{ 
	MSG msg; 
	HACCEL hAccelTable; 
 
	// Perform application initialization: 
	if (!InitInstance (hInstance, nCmdShow))  
	{ 
		return FALSE; 
	} 
 
	hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WAVGRAPH); 
 
	// Main message loop: 
	while (GetMessage(&msg, NULL, 0, 0))  
	{ 
		if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))  
		{ 
			TranslateMessage(&msg); 
			DispatchMessage(&msg); 
		} 
	} 
 
	return msg.wParam; 
} 
 
// 
//  FUNCTION: MyRegisterClass() 
// 
//  PURPOSE: Registers the window class. 
// 
//  COMMENTS: 
// 
//    It is important to call this function so that the application  
//    will get 'well formed' small icons associated with it. 
// 
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass) 
{ 
	WNDCLASS	wc; 
 
    wc.style			= CS_HREDRAW | CS_VREDRAW; 
    wc.lpfnWndProc		= (WNDPROC) WndProc; 
    wc.cbClsExtra		= 0; 
    wc.cbWndExtra		= 0; 
    wc.hInstance		= hInstance; 
    wc.hIcon			= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WAVGRAPH)); 
    wc.hCursor			= 0; 
    wc.hbrBackground	= (HBRUSH) GetStockObject(WHITE_BRUSH); 
    wc.lpszMenuName		= 0; 
    wc.lpszClassName	= szWindowClass; 
 
	return RegisterClass(&wc); 
} 
 
// 
//  FUNCTION: InitInstance(HANDLE, int) 
// 
//  PURPOSE: Saves instance handle and creates main window 
// 
//  COMMENTS: 
// 
//    In this function, we save the instance handle in a global variable and 
//    create and display the main program window. 
// 
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow) 
{ 
	HWND	hWnd = NULL; 
	TCHAR	szTitle[MAX_LOADSTRING];			// The title bar text 
	TCHAR	szWindowClass[MAX_LOADSTRING];		// The window class name 
 
	hInst = hInstance;		// Store instance handle in our global variable 
	// Initialize global strings 
	LoadString(hInstance, IDC_WAVGRAPH, szWindowClass, MAX_LOADSTRING); 
	LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); 
 
	//If it is already running, then focus on the window 
	hWnd = FindWindow(szWindowClass, szTitle);	 
	if (hWnd)  
	{ 
		SetForegroundWindow ((HWND) (((DWORD)hWnd) | 0x01));     
		return 0; 
	}  
 
	MyRegisterClass(hInstance, szWindowClass); 
	 
	RECT	rect; 
	GetClientRect(hWnd, &rect); 
	 
	hWnd = CreateWindow(szWindowClass, szTitle, WS_VISIBLE, 
		CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL); 
	if (!hWnd) 
	{	 
		return FALSE; 
	} 
	//When the main window is created using CW_USEDEFAULT the height of the menubar (if one 
	// is created is not taken into account). So we resize the window after creating it 
	// if a menubar is present 
	{ 
		RECT rc; 
		GetWindowRect(hWnd, &rc); 
		rc.bottom -= MENU_HEIGHT; 
		if (hwndCB) 
			MoveWindow(hWnd, rc.left, rc.top, rc.right, rc.bottom, FALSE); 
	} 
 
 
	ShowWindow(hWnd, nCmdShow); 
	UpdateWindow(hWnd); 
 
	return TRUE; 
} 
 
// 
//  FUNCTION: WndProc(HWND, unsigned, WORD, LONG) 
// 
//  PURPOSE:  Processes messages for the main window. 
// 
//  WM_COMMAND	- process the application menu 
//  WM_PAINT	- Paint the main window 
//  WM_DESTROY	- post a quit message and return 
// 
// 
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	HDC hdc; 
	int wmId, wmEvent; 
	PAINTSTRUCT ps; 
	TCHAR szHello[MAX_LOADSTRING]; 
 
	switch (message)  
	{ 
		case WM_COMMAND: 
			wmId    = LOWORD(wParam);  
			wmEvent = HIWORD(wParam);  
			// Parse the menu selections: 
			switch (wmId) 
			{	 
				case ID_START: 
					if(!StartDevice()) 
						MessageBox(hWnd,L"Record device start failed",L"Error",MB_OK); 
					g_started=TRUE; 
					break; 
				case ID_STOP: 
					StopDevice(); 
					break; 
				case ID_WAVEFORM: 
					g_waveform=TRUE; 
					g_freqence=FALSE; 
					break; 
				case ID_FREQUENCE: 
					g_waveform=FALSE; 
					g_freqence=TRUE; 
					break; 
				case IDM_HELP_ABOUT: 
					DialogBox(hInst, (LPCTSTR)IDD_ABOUTBOX, hWnd, (DLGPROC)About); 
				    break; 
				case IDOK: 
					SendMessage(hWnd, WM_ACTIVATE, MAKEWPARAM(WA_INACTIVE, 0), (LPARAM)hWnd); 
					SendMessage (hWnd, WM_CLOSE, 0, 0); 
					break; 
				case ID_EXIT: 
					PostQuitMessage(0); 
					break; 
				default: 
				   return DefWindowProc(hWnd, message, wParam, lParam); 
			} 
			break; 
		case WM_CREATE: 
			hwndCB = CreateRpCommandBar(hWnd); 
			{ 
				g_hWnd=hWnd; 
				GetClientRect(g_hWnd,&g_rect); 
				::InflateRect(&g_rect, 
							  -(g_rect.right-g_rect.left-256), 
							  -(g_rect.bottom-g_rect.top-256)); 
				HDC hdc=GetDC(hWnd); 
				g_memdc=CreateCompatibleDC(hdc); 
				g_bitmap=CreateBgBitmap(g_memdc,g_rect.right-g_rect.left,g_rect.bottom-g_rect.top,24,(void **)&g_buffer,&g_bufsize); 
				SelectObject(g_memdc,g_bitmap); 
				ReleaseDC(hWnd,hdc); 
			} 
			break; 
		case WM_PAINT: 
			RECT rt; 
			hdc = BeginPaint(hWnd, &ps); 
			GetClientRect(hWnd, &rt); 
			LoadString(hInst, IDS_HELLO, szHello, MAX_LOADSTRING); 
			DrawText(hdc, szHello, _tcslen(szHello), &rt,  
				DT_SINGLELINE | DT_VCENTER | DT_CENTER); 
			EndPaint(hWnd, &ps); 
			break;  
		case WM_DESTROY: 
			StopDevice(); 
			DestroyBgBitmap(g_bitmap); 
			CommandBar_Destroy(hwndCB); 
			PostQuitMessage(0); 
			break; 
		case WM_SETTINGCHANGE: 
			SHHandleWMSettingChange(hWnd, wParam, lParam, &s_sai); 
     		break; 
		default: 
			return DefWindowProc(hWnd, message, wParam, lParam); 
   } 
   return 0; 
} 
 
HWND CreateRpCommandBar(HWND hwnd) 
{ 
	SHMENUBARINFO mbi; 
 
	memset(&mbi, 0, sizeof(SHMENUBARINFO)); 
	mbi.cbSize     = sizeof(SHMENUBARINFO); 
	mbi.hwndParent = hwnd; 
	mbi.nToolBarId = IDM_MENU; 
	mbi.hInstRes   = hInst; 
	mbi.nBmpId     = 0; 
	mbi.cBmpImages = 0; 
 
	if (!SHCreateMenuBar(&mbi))  
		return NULL; 
 
	return mbi.hwndMB; 
} 
 
// Mesage handler for the About box. 
LRESULT CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) 
{ 
	SHINITDLGINFO shidi; 
 
	switch (message) 
	{ 
		case WM_INITDIALOG: 
			// Create a Done button and size it.   
			shidi.dwMask = SHIDIM_FLAGS; 
			 shidi.dwFlags = SHIDIF_DONEBUTTON | SHIDIF_SIPDOWN | SHIDIF_SIZEDLGFULLSCREEN; 
			shidi.hDlg = hDlg; 
			SHInitDialog(&shidi); 
			return TRUE;  
 
		case WM_COMMAND: 
			if (LOWORD(wParam) == IDOK) { 
				EndDialog(hDlg, LOWORD(wParam)); 
				return TRUE; 
			} 
			break; 
	} 
    return FALSE; 
} 
 
BOOL StartDevice() 
{ 
	if(!g_started) 
	{ 
		memset(&g_ctx,0,sizeof(recctx)); 
		g_ctx.devid=WAVE_MAPPER; 
		g_ctx.info.channel=1; 
		g_ctx.info.freq=11025; 
		g_ctx.info.bitspersample=8; 
		g_ctx.userdata=(unsigned long)g_hWnd; 
 
		return startrecord(&g_ctx,cbdatain); 
	} 
	else 
	{ 
		return FALSE; 
	} 
} 
 
void StopDevice() 
{ 
	if(g_started) 
		stoprecord(&g_ctx); 
} 
 
int	cbdatain(recctx *pctx,unsigned char *buf,int buflen) 
{ 
	HWND hWnd=(HWND)pctx->userdata; 
	if(hWnd != NULL) 
	{ 
		HDC hdc=GetDC(hWnd); 
 
		memset(g_buffer,255,g_bufsize); 
		if(g_waveform) 
		{ 
			DrawWave(g_buffer,g_rect.right-g_rect.left,g_rect.bottom-g_rect.top,buf,buflen); 
		} 
		if(g_freqence) 
		{ 
			int i; 
 
			for(i=0;i<256;i++) 
			{ 
				g_real[i]=(double)buf[i]; 
				g_image[i]=0.0; 
			} 
			fft(g_real,g_image,8); 
			int power; 
			buflen=buflen>>1; 
			for(i=0;i 255) 
					power=255; 
				buf[i]=power; 
			} 
			DrawFreq(g_buffer,g_rect.right-g_rect.left,g_rect.bottom-g_rect.top,buf,buflen); 
		} 
 
		BitBlt(hdc,g_rect.left,g_rect.top,g_rect.right-g_rect.left,g_rect.bottom-g_rect.top, 
			   g_memdc,0,0,SRCCOPY); 
 
		ReleaseDC(hWnd,hdc); 
	} 
 
	return 0; 
} 
 
void DrawWave(RGBTRIPLE *buffer,int width,int height,unsigned char *pts,long npt) 
{ 
	int i,j; 
	int sub,hh=height>>1; 
	long npixels=width*height; 
	RGBTRIPLE *base,*p,*up,*down; 
 
	up=buffer+npixels; 
	down=buffer; 
 
	if(npt > width) 
		npt=width; 
 
	base=buffer+(npixels>>1); 
	 
	for(i=0;irgbtBlue=0; 
				p->rgbtGreen=0; 
				p->rgbtRed=0; 
 
				p-=width; 
			} 
		} 
		else if(sub > 0) 
		{ 
			if(sub>hh) 
				sub=hh; 
			for(j=0;jrgbtBlue=0; 
				p->rgbtGreen=0; 
				p->rgbtRed=0; 
 
				p+=width; 
			} 
		} 
 
		base++; 
	} 
} 
 
void DrawFreq(RGBTRIPLE *buffer,int width,int height,unsigned char *pts,long npt) 
{ 
	int i,j; 
	int sub; 
	long npixels=width*height; 
	RGBTRIPLE *base,*p,*up,*down; 
 
	up=buffer+npixels; 
	down=buffer; 
 
	if(npt > width) 
		npt=width; 
 
	base=buffer+width; 
	 
	for(i=0;iheight) 
			sub=height; 
		for(j=0;jrgbtBlue=0; 
			p->rgbtGreen=0; 
			p->rgbtRed=0; 
 
			p+=width; 
		} 
 
		base+=2; 
	} 
}