//NetTalk
/*------------------------------------------------------------------------------*\
 =============================
   模块名称: Main.cpp
 =============================
 
 [版权]
 
   2000-2002  115软件工厂  版权所有
                                              
\*------------------------------------------------------------------------------*/
#include "wndx.h"
#include <Windowsx.h>
#include <VFW.h>
#include <stdio.h>

#include "waveshow.h"
#include "resource.h"
#include "Splash.h"
#include "AVIOMgr.h"
#include "VolumeOutWave.h"
#include "VolumeInXXX.h"
#include "VideoWnd.h"
#include "TrayNotify.h"
#include "SlideBar.h"
#include "AddrBook.h"
#include "GraphDlg.h"
#include "RippleWnd.h"
#include "NewMsgBox.h"
#include "MsgTalk.h"
#include "Main.h"


/*------------------------------------------------------------------------------*/
#define PORT 1159//the default port is 1159
CMainWnd MainWnd;
CAVIOMgr  AVIO;
SETUP CSetupDlg::Setup;

/*------------------------------------------------------------------------------*/
//
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nCmdShow)
{
	//初始化WndX系统
	InitXSystem(hInstance);

	/* INITIALIZE COMMON CONTROLS */
	INITCOMMONCONTROLSEX iccex;     
    iccex.dwICC = ICC_WIN95_CLASSES;
    iccex.dwSize = sizeof(INITCOMMONCONTROLSEX);
    InitCommonControlsEx(&iccex);

	//确保只有一个实例
	HANDLE hMutex=CreateMutex(0,FALSE,"NETTALK_MUTEX_ONCE");
	if(hMutex)
	{
		if(GetLastError()==ERROR_ALREADY_EXISTS)
			return 0;
	}
	//显示软件封面	
	CSplash* Splash=new CSplash(3000);
	Splash->CreateSplash(IDD_SPLASH);
	//初始化Socket
	InitializeSocket();
	//初始化AVIO(将Socket绑定到某个Port)
	if(!AVIO.Init(PORT))
	{
		//如果失败，退出
		CMsgBox::MessageBox(0,IDS_ERR_INIT,IDS_ERR,0,IDI_ERR);
		return 0;	
	}
	//创建主窗口
	MainWnd.Create(LPCTSTR(IDD_MAIN_DLG),0);
	//
	AVIO.SetMainWnd(MainWnd);
	
	MSG msg;
	
	while(GetMessage(&msg,0,0,0))
	{
		PreTranslateMessageX(&msg);
		TranslateMessage(&msg);
		DispatchMessage(&msg);
	}

	AVIO.Destroy();

	CleanUpSocket();
	return msg.wParam;
	
}

/*------------------------------------------------------------------------------*/

CMainWnd::CMainWnd()
{
	m_bHilightTitleBar=0;
	SetRect(&m_rcDataRate,20,218,140,231);
	SetRect(&m_rcFps,10,175,45,189);
	SetRect(&m_rcVideo,6,28,182,172);
	
	
	m_bmpVideo=0;
	m_bSendVideo=TRUE;
		
}

/*------------------------------------------------------------------------------*/

CMainWnd::~CMainWnd()
{
}

/*------------------------------------------------------------------------------*/
//主窗口消息
LRESULT CMainWnd::WndProc(UINT uMsg,WPARAM wParam,LPARAM lParam)
{
	
	switch(uMsg)
	{
	case WM_HOTKEY://热键弹出
		if(wParam==1)
		{
			ShowWindow(m_hWnd,SW_SHOWNORMAL);
			SetForegroundWindow(m_hWnd);
			SetActiveWindow(m_hWnd);
		}
		break;
	case WM_USER_SETUP:
		OnSetup((SETUP*)lParam);
		break;
	case WM_TRAYNOTIFY:
		OnTrayNotify(wParam,lParam);
		break;
	case IOM_AUDIO:
		OnAudioData((BOOL)wParam,(CAVIOMgr*)lParam);
		break;
	case WM_INITDIALOG:
		return OnInitDialog();
	case WM_DESTROY:
		OnDestroy();
		break;
	case WM_CLOSE:
		OnClose();
		break;
	
	case WM_LBUTTONDOWN:
		{
			POINT point;
			point.x=GET_X_LPARAM(lParam); 
			point.y=GET_Y_LPARAM(lParam); 
			OnLButtonDown(wParam,point);		
		}break;
	
	case WM_LBUTTONUP:
		{
			POINT point;
			point.x=GET_X_LPARAM(lParam); 
			point.y=GET_Y_LPARAM(lParam); 
			OnLButtonUp(wParam,point);	
		}break;
	case WM_MOUSEMOVE:
		{
			POINT point;
			point.x=GET_X_LPARAM(lParam); 
			point.y=GET_Y_LPARAM(lParam); 
			OnMouseMove(wParam,point);	
			
		}break;
	case WM_COMMAND:
		return OnCommand(wParam,lParam);
		break;
	case WM_ERASEBKGND:
		OnEraseBkgnd((HDC)wParam);
		return TRUE;
	case WM_TIMER:
		OnTimer(wParam);
		break;
	case WM_SETCURSOR:
		return OnSetCursor((HWND)wParam,LOWORD(lParam),HIWORD(lParam));
		break;
	case WM_CTLCOLOREDIT:
		return (LRESULT)OnCtrlColorEdit((HDC)wParam,(HWND)lParam);
		break;
	case WM_CTLCOLORSTATIC:
		return (LRESULT)OnCtrlColorStatic((HDC)wParam,(HWND)lParam);	
		break;
	
	case IOM_NOTIFY:
		OnIOMNotify(wParam,lParam);
		break;
	case WM_SLD:
		{
			if(((HWND)lParam)==((HWND)m_sldAudioOut))
			{
				//设置输出音量
				m_VoOutCtrl.SetCurrentVolume((m_VoOutCtrl.GetMaximalVolume()-m_VoOutCtrl.GetMinimalVolume())*m_sldAudioOut.GetPos()/100);
			}
			else
			if(((HWND)lParam)==((HWND)m_sldAudioIn))
			{
				//设置输入音量
				m_VoInCtrl.SetCurrentVolume((m_VoInCtrl.GetMaximalVolume()-m_VoInCtrl.GetMinimalVolume())*m_sldAudioIn.GetPos()/100);
			}
			else
			if(((HWND)lParam)==((HWND)m_sldVideoQ))
			{
				//设置视频质量
				m_VQ=m_sldVideoQ.GetPos();
				AVIO.SetVideoQuality(m_VQ);
			}
		}
		break;
	default:
		return CDialogX::WndProc(uMsg,wParam,lParam);
	}
	return TRUE;

}

/*------------------------------------------------------------------------------*/
BOOL CMainWnd::OnInitDialog()
{
	
	HDC hdc=GetDC(m_hWnd);
	m_bmpVideo=CreateCompatibleBitmap(hdc,176,144);
	ReleaseDC(m_hWnd,hdc);
//set window region
	POINT pt[13]={{0,10},{10,0},{262,0},{262,32},{269,39},{269,160},
	{265,164},{265,228},{256,237},{20,237},{11,228},{11,221},{0,210}};
	HRGN hRgn=CreatePolygonRgn(pt,13,ALTERNATE);	
	SetWindowRgn(m_hWnd,hRgn,FALSE);	
	
//set window style
	DWORD dwStyle=GetWindowLong(m_hWnd,GWL_STYLE);
	SetWindowLong(m_hWnd,GWL_STYLE,dwStyle|WS_SYSMENU|WS_MINIMIZEBOX);
//set window caption and icon
	SetWindowText(m_hWnd,"NetTalk");		
	SendMessage(m_hWnd,WM_SETICON,ICON_BIG,(LPARAM)LoadIcon(hInstX,LPCTSTR(IDI_MAIN)));
//title bar region
	POINT pt2[5]={{11,4},{170,4},{151,23},{4,23},{4,11}};
	m_hrgnTitle=CreatePolygonRgn(pt2,5,ALTERNATE);

	m_TrayNotify.SetHwnd(m_hWnd);
	m_TrayNotify.SetIcon(LoadIcon(hInstX,LPCTSTR(IDI_MAIN)));
	m_TrayNotify.SetTip("NetTalk-115软件工厂");
	m_TrayNotify.SetMsg(WM_TRAYNOTIFY);
	m_TrayNotify.SetID(1);
	m_TrayNotify.ShowIcon(TRUE);
	
//
	m_hbCtrlBg=CreateSolidBrush(0);
	m_hbFpsBg=CreateSolidBrush(0x00b9b4b3);

//initialize buttons(load the bitmaps,set the position)
	m_btnCall.LoadBitmaps(IDB_CALL1,IDB_CALL2,IDB_CALL3);
	m_btnCall.Associate(m_hWnd,IDC_CALL);
	SetWindowPos(m_btnCall,0,0,0,64,24,SWP_NOMOVE);

	m_btnHang.LoadBitmaps(IDB_HANG1,IDB_HANG2,IDB_HANG3);
	m_btnHang.Associate(m_hWnd,IDC_HANG);
	SetWindowPos(m_btnHang,0,0,0,64,24,SWP_NOMOVE);

	m_btnAddr.LoadBitmaps(IDB_ADDR1,IDB_ADDR2,IDB_ADDR3);
	m_btnAddr.Associate(m_hWnd,IDC_ADDR);
	SetWindowPos(m_btnAddr,0,0,0,64,24,SWP_NOMOVE);

	m_btnSetup.LoadBitmaps(IDB_SETUP1,IDB_SETUP2,IDB_SETUP3);
	m_btnSetup.Associate(m_hWnd,IDC_SETUP);
	SetWindowPos(m_btnSetup,0,0,0,64,24,SWP_NOMOVE);
	
	m_btnClose.LoadBitmaps(IDB_CLOSE1,IDB_CLOSE2,IDB_CLOSE3);
	m_btnClose.Associate(m_hWnd,IDC_CLOSE);
	SetWindowPos(m_btnClose,0,0,0,11,11,SWP_NOMOVE);

	m_btnMin.LoadBitmaps(IDB_MIN1,IDB_MIN2,IDB_MIN3);
	m_btnMin.Associate(m_hWnd,IDC_MIN);
	SetWindowPos(m_btnMin,0,0,0,11,11,SWP_NOMOVE);

	m_btnHelp.LoadBitmaps(IDB_HELP1,IDB_HELP2,IDB_HELP3);
	m_btnHelp.Associate(m_hWnd,IDC_HP);
	SetWindowPos(m_btnHelp,0,0,0,11,11,SWP_NOMOVE);

	m_btnAbout.LoadBitmaps(IDB_ABOUT1,IDB_ABOUT2,IDB_ABOUT3);
	m_btnAbout.Associate(m_hWnd,IDC_ABOUT);
	SetWindowPos(m_btnAbout,0,0,0,11,11,SWP_NOMOVE);

	m_btnLocal.LoadBitmaps(IDB_VIDEO_LOCAL1,IDB_VIDEO_LOCAL2,IDB_VIDEO_LOCAL3);
	m_btnLocal.Associate(m_hWnd,IDC_VIDEO_LOCAL);
	SetWindowPos(m_btnLocal,0,0,0,15,15,SWP_NOMOVE);

	m_btnOnoff.LoadBitmaps(IDB_VIDEO_ONOFF4,IDB_VIDEO_ONOFF5,IDB_VIDEO_ONOFF6);
	m_btnOnoff.Associate(m_hWnd,IDC_VIDEO_ONOFF);
	SetWindowPos(m_btnOnoff,0,0,0,15,15,SWP_NOMOVE);

	m_btnOutview.LoadBitmaps(IDB_VIDEO_OUTVIEW1,IDB_VIDEO_OUTVIEW2,IDB_VIDEO_OUTVIEW3);
	m_btnOutview.Associate(m_hWnd,IDC_VIDEO_OUTVIEW);
	SetWindowPos(m_btnOutview,0,0,0,15,15,SWP_NOMOVE);
	
	m_btnMsg.LoadBitmaps(IDB_MSG1,IDB_MSG2,IDB_MSG3);
	m_btnMsg.Associate(m_hWnd,IDC_MSG);
	SetWindowPos(m_btnMsg,0,0,0,15,15,SWP_NOMOVE);
//initialize the slide bar
	RECT rc;
	SetRect(&rc,174,180,250,188);
	m_sldAudioOut.Create(rc,m_hWnd,0);
	
	SetRect(&rc,174,195,250,203);
	m_sldAudioIn.Create(rc,m_hWnd,0);
	
	SetRect(&rc,51,194,141,203);
	m_sldVideoQ.Create(rc,m_hWnd,0);
	

//initialize the wave show	
	SetRect(&rc,164,211,202,229);
	m_WaveShowOut.Create(rc,m_hWnd);
	
	SetRect(&rc,218,211,256,229);
	m_WaveShowIn.Create(rc,m_hWnd);

//Create the video wnd
	m_LocalVideoWnd.Create(IDD_VIDEO,m_hWnd,TRUE);
	m_RemoteVideoWnd.Create(IDD_VIDEO,m_hWnd,FALSE);
	GetWindowRect(m_hWnd,&rc);
	SetWindowPos(m_LocalVideoWnd,0,rc.right+20,rc.top-100,0,0,SWP_NOSIZE);
	SetWindowPos(m_RemoteVideoWnd,0,rc.left-200,rc.top,0,0,SWP_NOSIZE);
//Create the txt chat wnd
	m_MsgTalk.Create(m_hWnd);
	SetWindowPos(m_MsgTalk,0,rc.right+20,rc.top+100,0,0,SWP_NOSIZE);
//add the tooltips for ctrls
	char szTip[30];
	
	TOOLINFO ti;
    /* CREATE A TOOLTIP WINDOW */
    m_hwndTT = CreateWindowEx(WS_EX_TOPMOST,
        TOOLTIPS_CLASS,
        NULL,
        WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP,		
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        CW_USEDEFAULT,
        m_hWnd,
        NULL,
        hInstX,
        NULL
        );

    SetWindowPos(m_hwndTT,HWND_TOPMOST,0,0,0,0,SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);
  	
    /* INITIALIZE MEMBERS OF THE TOOLINFO STRUCTURE */
    ti.cbSize = sizeof(TOOLINFO);
    ti.uFlags = TTF_SUBCLASS;
    
    ti.hinst = hInstX;
    ti.uId = 0;
	ti.lpszText = szTip;
      //
    ti.hwnd = m_btnClose;
	GetClientRect(m_btnClose,&ti.rect);
	strcpy(szTip,"关闭NetTalk");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_btnMin;
	GetClientRect(m_btnMin,&ti.rect);
	strcpy(szTip,"最小化");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_btnHelp;
	GetClientRect(m_btnHelp,&ti.rect);
	strcpy(szTip,"帮助");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_btnAbout;
	GetClientRect(m_btnAbout,&ti.rect);
	strcpy(szTip,"关于...");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_btnLocal;
	GetClientRect(m_btnLocal,&ti.rect);
	strcpy(szTip,"本地视频");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_btnOutview;
	GetClientRect(m_btnOutview,&ti.rect);
	strcpy(szTip,"对方视频");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_btnOnoff;
	GetClientRect(m_btnOnoff,&ti.rect);
	strcpy(szTip,"传送/不传送本地视频");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_btnMsg;
	GetClientRect(m_btnMsg,&ti.rect);
	strcpy(szTip,"文本对话");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_sldAudioIn;
	GetClientRect(m_sldAudioIn,&ti.rect);
	strcpy(szTip,"调节麦克风音量");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_sldAudioOut;
	GetClientRect(m_sldAudioOut,&ti.rect);
	strcpy(szTip,"调节输出音量");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	ti.hwnd = m_sldVideoQ;
	GetClientRect(m_sldVideoQ,&ti.rect);
	strcpy(szTip,"调节视频质量");
    SendMessage(m_hwndTT, TTM_ADDTOOL, 0, (LPARAM) (LPTOOLINFO) &ti);
	
//volume control,
	m_VoOutCtrl.RegisterNotificationSink(OutVolumeChanged,(DWORD)this);
	m_VoInCtrl.RegisterNotificationSink(InVolumeChanged,(DWORD)this);

	m_sldAudioOut.SetPos(100*m_VoOutCtrl.GetCurrentVolume()/
		(m_VoOutCtrl.GetMaximalVolume()-m_VoOutCtrl.GetMinimalVolume()));
	m_sldAudioIn.SetPos(100*m_VoInCtrl.GetCurrentVolume()/
		(m_VoInCtrl.GetMaximalVolume()-m_VoInCtrl.GetMinimalVolume()));
//get the video quality from the ini file	
	m_VQ=GetPrivateProfileInt("Video","Q",50,"NetTalk.ini");
	if(m_VQ>100||m_VQ<0)
		m_VQ=100;
	AVIO.SetVideoQuality(m_VQ);
	m_sldVideoQ.SetPos(m_VQ);
//create the video display wnd	
	m_vs.Create(m_rcVideo,m_hWnd);

//to get the data from AVIO,set some wnds related to AVIO
	AVIO.SetRemoteVideoRcvWnd(m_vs);
	AVIO.SetLocalVideoRcvWnd(m_LocalVideoWnd.m_vs);
	AVIO.SetLocalAudioRcvWnd(m_hWnd);
	AVIO.SetRemoteAudioRcvWnd(m_hWnd);

	MoveWindow(GetDlgItem(m_hWnd,IDC_DATARATE),m_rcDataRate.left,m_rcDataRate.top,m_rcDataRate.Width(),m_rcDataRate.Height(),false);
	MoveWindow(GetDlgItem(m_hWnd,IDC_FPS),m_rcFps.left,m_rcFps.top,m_rcFps.Width(),m_rcFps.Height(),false);

//load the setup
	CSetupDlg::LoadSetup();
	OnSetup(&CSetupDlg::Setup);

	if(CSetupDlg::Setup.bInitShow)
		ShowWindow(m_hWnd,SW_SHOW);
	return FALSE ;

}

/*------------------------------------------------------------------------------*/
//
void CMainWnd::OnDestroy()
{
	
	if(m_hbCtrlBg)
		DeleteObject(m_hbCtrlBg);
	if(m_hbFpsBg)
		DeleteObject(m_hbFpsBg);
	if(m_bmpVideo)
		DeleteObject(m_bmpVideo);
	char s[5];
	sprintf(s,"%d",m_VQ);
	WritePrivateProfileString("Video","Q",s,"NetTalk.ini");
}

/*------------------------------------------------------------------------------*/
//when close ,warning
void CMainWnd::OnClose()
{
	if(AVIO.GetStatus()==STA_BUSY)
	{
		if(CMsgBox::MessageBox(m_hWnd,IDS_MSG_CLOSE_BUSY,IDS_WAR,MB_YESNO,IDI_INFO)==IDYES)
		{
			DestroyWindow(m_hWnd);
			PostQuitMessage(0);
		}
	}
	else
	if(CMsgBox::MessageBox(m_hWnd,IDS_MSG_CLOSE_FREE,IDS_WAR,MB_YESNO,IDI_INFO)==IDYES)
	{
		DestroyWindow(m_hWnd);
		PostQuitMessage(0);
	}
}

/*------------------------------------------------------------------------------*/

void CMainWnd::OnLButtonDown(UINT nFlags, POINT &point)
{
	if(PtInRegion(m_hrgnTitle,point.x,point.y))
	{
		SetCapture(m_hWnd);
		
		RECT rc;
		GetWindowRect(m_hWnd,&rc);
		MSG msg;
		while(GetMessage(&msg, NULL, 0, 0))
		{
			if (GetCapture()!=m_hWnd)
			{
				DispatchMessage(&msg);
				break;
			}
			switch(msg.message)
			{
			case WM_MOUSEMOVE:
				{
					POINT pt;
					pt.x=GET_X_LPARAM(msg.lParam);
					pt.y=GET_Y_LPARAM(msg.lParam);
					rc.left+=pt.x-point.x;
					rc.top+=pt.y-point.y;
					SetWindowPos(m_hWnd,0,rc.left,
						rc.top,0,0,SWP_NOSIZE);
				}
				break;
			case WM_LBUTTONUP:
				
				goto EXITLOOP;					
				
			default:
				DispatchMessage(&msg);
				break;
				
			}
		}
EXITLOOP:
		ReleaseCapture();
	}
	
}

/*------------------------------------------------------------------------------*/

void CMainWnd::OnLButtonUp(UINT nFlags, POINT &point)
{

}
/*------------------------------------------------------------------------------*/
//hilight the title bar
void CMainWnd::OnMouseMove(UINT nFlags, POINT point)
{
	if(PtInRegion(m_hrgnTitle,point.x,point.y)&&!m_bHilightTitleBar)
	{
		RECT rc;
		SetRect(&rc,5,5,168,22);
		m_bHilightTitleBar=TRUE;
		HDC hdc=GetDC(m_hWnd);
		HBITMAP hb=LoadBitmap(hInstX,LPCTSTR(IDB_TITLE2));
		DrawTransBmpX(hdc,rc,hb,0,0,0);
		DeleteObject(hb);
		ReleaseDC(m_hWnd,hdc);
		SetTimer(m_hWnd,1,50,0);
		
	}
	
}

/*------------------------------------------------------------------------------*/
BOOL CMainWnd::OnCommand(WPARAM wParam, LPARAM lParam)
{
	switch(LOWORD(wParam))
	{
	case IDC_CLOSE:
		OnClose();
		break;
	case IDC_MIN:
		ShowWindow(m_hWnd,SW_MINIMIZE);
		if(CSetupDlg::Setup.bMiniHide)
			ShowWindow(m_hWnd,SW_HIDE);
		break;
	case IDC_HP:
		{
			//打开帮助文件
			char szPath[256];
			GetModuleFileName(0,szPath,255);
			int i;
			for(i=strlen(szPath);i>0;i--)
			{
				if(szPath[i]=='\\')
				{
					szPath[i+1]=0;
					break;
				}
			}
			strcpy(szPath+strlen(szPath),"help\\help.htm");
			ShellExecute(0,"open",szPath,0,0,SW_SHOWNORMAL);
		}
		break;
	case IDC_ABOUT:
		{
			CAboutDlg abt;
			abt.DoModal(LPCTSTR(IDD_ABOUT_DLG),m_hWnd);
			
		}
		break;
	case IDC_ADDR:
		{
			CAddrBook ab;
			ab.DoModal(LPCTSTR(IDD_ADDR),m_hWnd);
		}
		break;
	case 0:
		{
			//呼叫
			if(!AVIO.Call((char*)lParam,PORT))
				CMsgBox::MessageBox(m_hWnd,IDS_MSG_CALL_BUSY,IDS_ERR,MB_OK,IDI_INFO);
			else
			{
				if(!m_CallDlg.DoModal(m_hWnd,(char*)lParam))
				{
					if(AVIO.GetStatus()==STA_BUSY)
					{
						ShowWindow(m_vs,SW_HIDE);
						ShowWindow(m_LocalVideoWnd.m_vs,SW_HIDE);
						ShowWindow(m_RemoteVideoWnd.m_vs,SW_HIDE);
						KillTimer(m_hWnd,2);
						DrawFps("");
						DrawDataRate("");				
						
					}
					AVIO.EndTalk();
					
				}
			}
		}
		break;
	case IDC_CALL:
		{

			CIPInput ip;
			if(ip.DoModal(LPCTSTR(IDD_IPINPUT),m_hWnd))
			{
				SendMessage(m_hWnd,WM_COMMAND,0,(LPARAM)ip.m_szIP);
			}
		}
		break;
	case IDC_HANG:
		{
			//挂断
			if(AVIO.GetStatus()==STA_BUSY)
			{
				if(CMsgBox::MessageBox(m_hWnd,IDS_MSG_IFENDTALK,IDS_WAR,MB_YESNO,IDI_INFO)==IDYES)
				{
					AVIO.EndTalk();
					
					KillTimer(m_hWnd,2);
					DrawFps("");
					DrawDataRate("");
					ShowWindow(m_vs,SW_HIDE);
					ShowWindow(m_LocalVideoWnd.m_vs,SW_HIDE);
					ShowWindow(m_RemoteVideoWnd.m_vs,SW_HIDE);				
				}
			}
			else
				AVIO.EndTalk();
		}
		break;
	case IDC_SETUP:
		{
			CSetupDlg sd;
			sd.DoModal(LPCTSTR(IDD_SETUP),m_hWnd);
		}
		break;
	case IDC_VIDEO_LOCAL:
		{
			if(IsWindowVisible(m_LocalVideoWnd))
			{
				AVIO.EnablePreview(FALSE);
				ShowWindow(m_LocalVideoWnd,SW_HIDE);
				
			}
			else
			{
				ShowWindow(m_LocalVideoWnd,SW_SHOW);
				AVIO.EnablePreview(TRUE);
				
			}
		}
		break;
	case IDC_VIDEO_OUTVIEW:
		{
			if(IsWindowVisible(m_RemoteVideoWnd))
			{
				ShowWindow(m_RemoteVideoWnd,SW_HIDE);
				AVIO.SetRemoteVideoRcvWnd(m_vs);
				ShowWindow(m_RemoteVideoWnd.m_vs,SW_HIDE);
				m_btnOutview.LoadBitmaps(IDB_VIDEO_OUTVIEW1,IDB_VIDEO_OUTVIEW2,IDB_VIDEO_OUTVIEW3);
			}
			else
			{
				ShowWindow(m_RemoteVideoWnd,SW_SHOW);
				AVIO.SetRemoteVideoRcvWnd(m_RemoteVideoWnd.m_vs);
				ShowWindow(m_vs,SW_HIDE);
				m_btnOutview.LoadBitmaps(IDB_VIDEO_OUTVIEW4,IDB_VIDEO_OUTVIEW5,IDB_VIDEO_OUTVIEW6);
				
			}
			InvalidateRect(m_btnOutview,0,FALSE);
		}
		break;
	case IDC_VIDEO_ONOFF:
		{//是否发送视频
			if(m_bSendVideo)
			{
				m_bSendVideo=FALSE;
				AVIO.VideoSend(FALSE);
				m_btnOnoff.LoadBitmaps(IDB_VIDEO_ONOFF1,IDB_VIDEO_ONOFF2,IDB_VIDEO_ONOFF3);
				
			}
			else
			{			
				m_bSendVideo=TRUE;
				AVIO.VideoSend(TRUE);
				m_btnOnoff.LoadBitmaps(IDB_VIDEO_ONOFF4,IDB_VIDEO_ONOFF5,IDB_VIDEO_ONOFF6);
			}
		}break;
	case IDC_SEND:
		{
			//发送文字信息
			char ip[50];
			GetDlgItemText(m_MsgTalk,IDC_OBJ,ip,50);
			AVIO.SendTxt(ip,PORT,(char*)lParam);
		}break;
	case IDC_MSG:
		{

			if(IsWindowVisible(m_MsgTalk))
				ShowWindow(m_MsgTalk,SW_HIDE);
			else
				ShowWindow(m_MsgTalk,SW_SHOW);
		}break;
	}
	return TRUE;
}
/*------------------------------------------------------------------------------*/
//画主窗口界面
void CMainWnd::OnEraseBkgnd(HDC hdc)
{
	
	RECT rc;
	GetClientRect(m_hWnd,&rc);	
	HDC hMemDC=CreateCompatibleDC(hdc);

	HBITMAP hFace=LoadBitmap(hInstX,LPCTSTR(IDB_FACE));
	HBITMAP hob=(HBITMAP)SelectObject(hMemDC,hFace);

	//画标题条(如果被Hilight的话)
	if(m_bHilightTitleBar)
	{
		RECT rc;
		SetRect(&rc,5,5,168,22);
		m_bHilightTitleBar=TRUE;
		
		HBITMAP hb=LoadBitmap(hInstX,LPCTSTR(IDB_TITLE2));
		DrawTransBmpX(hMemDC,rc,hb,0,0,0);
		DeleteObject(hb);
		
	}
	BitBlt(hdc,0,0,rc.right-rc.left,
		rc.bottom-rc.top,hMemDC,0,0,SRCCOPY);


	SelectObject(hMemDC,hob);
	DeleteObject(hFace);
	DeleteDC(hMemDC);
	
}

/*------------------------------------------------------------------------------*/
void CMainWnd::OnTimer(UINT nIDEvent)
{
	switch(nIDEvent)
	{
	case 1:
		POINT pt;
		GetCursorPos(&pt);
		ScreenToClient(m_hWnd,&pt);
		if(m_bHilightTitleBar&&!PtInRegion(m_hrgnTitle,pt.x,pt.y))
		{
			m_bHilightTitleBar=FALSE;
			RECT rc;
			SetRect(&rc,5,5,168,22);
			HDC hdc=GetDC(m_hWnd);
			HBITMAP hb=LoadBitmap(hInstX,LPCTSTR(IDB_TITLE1));
			DrawTransBmpX(hdc,rc,hb,0,0,0);
			DeleteObject(hb);
			ReleaseDC(m_hWnd,hdc);
			KillTimer(m_hWnd,nIDEvent);
			
		}
		break;
	case 2://draw fps and datarate
		{
			
			//得到发送的数据和接收的数据量
			DWORD ds=AVIO.GetDataSend();
			DWORD dr=AVIO.GetDataRcv();	
			
			DWORD t=GetTickCount();
				
			//画帧频率
			char sz[60];
			sprintf(sz,"%dfps",AVIO.GetFps());
			DrawFps(sz);
			//累计通话时间
			m_uTalkTime++;
			sprintf(sz,"%.1fkbps  %d%d:%d%d:%d%d",
				((float)ds-m_nDataSend+(float)dr-m_nDataRcv)*8000.0/((float)t-m_nTimePass)/1024.0,
				m_uTalkTime/36000,
				(m_uTalkTime/3600)%10,
				((m_uTalkTime/60)%60)/10,
				((m_uTalkTime/60)%60)%10,
				(m_uTalkTime%60)/10,
				(m_uTalkTime%60)%10);
			//画比特率和通话时间
			DrawDataRate(sz);

			//如果连续5次接收到的数据为0的话,结束通话
			if(dr-m_nDataRcv==0)
				m_iZeroCount++;
			else
				m_iZeroCount=0;
			
			if(m_iZeroCount>5)
			{
				
				AVIO.EndTalk();
				KillTimer(m_hWnd,2);
				ShowWindow(m_vs,SW_HIDE);
				ShowWindow(m_LocalVideoWnd.m_vs,SW_HIDE);
				ShowWindow(m_RemoteVideoWnd.m_vs,SW_HIDE);
				KillTimer(m_hWnd,2);
				DrawFps("");
				DrawDataRate("");
				CMsgBox::MessageBox(m_hWnd,IDS_ERR_NET_BLOCK,IDS_ERR,MB_OK,IDI_CUT);
			}
			
			m_nDataSend=ds;
			m_nDataRcv=dr;
			m_nTimePass=t;
			
		}
		break;
		
		
	}
}
/*------------------------------------------------------------------------------*/

BOOL CMainWnd::OnSetCursor(HWND hWnd, UINT nHitTest, UINT message)
{
	
	return FALSE;
}



/*------------------------------------------------------------------------------*/


HBRUSH CMainWnd::OnCtrlColorEdit(HDC hdc, HWND hwnd)
{
    SetTextColor(hdc,0x00ffffff);
	SetBkColor(hdc,0);
	return m_hbCtrlBg;
}

/*------------------------------------------------------------------------------*/

void CMainWnd::DrawFps(char* pszFps)
{
	SetDlgItemText(m_hWnd,IDC_FPS,pszFps);
	
}


/*------------------------------------------------------------------------------*/
//
void CMainWnd::OnAudioData(BOOL flag,CAVIOMgr* pMgr)
{
	
	if(!flag)//local
	{
		HDC hdc=GetDC(m_WaveShowIn);
		UINT len;
		char* p=pMgr->GetLocalAudio(len);
		m_WaveShowIn.Paint(hdc,p,len);
		ReleaseDC(m_WaveShowIn,hdc);
	}
	else
	{
		HDC hdc=GetDC(m_WaveShowOut);
		UINT len;
		char* p=pMgr->GetRemoteAudio(len);
		m_WaveShowOut.Paint(hdc,p,len);
		ReleaseDC(m_WaveShowOut,hdc);
	}
	
}

/*------------------------------------------------------------------------------*/

void CMainWnd::DrawDataRate(char* pszDataRate)
{
	SetDlgItemText(m_hWnd,IDC_DATARATE,pszDataRate);
	
}

/*------------------------------------------------------------------------------*/
HBRUSH CMainWnd::OnCtrlColorStatic(HDC hdc, HWND hwnd)
{
	if(hwnd==GetDlgItem(m_hWnd,IDC_FPS))
	{
		SetBkColor(hdc,0x00b9b4b3);
		SetTextColor(hdc,0x00ffffff);
		return m_hbFpsBg;
	}
	
	SetBkColor(hdc,0);
	SetTextColor(hdc,0x00aaeeff);  
	
	return m_hbCtrlBg;
}
/*------------------------------------------------------------------------------*/
//AVIOMgr的通知消息处理
void CMainWnd::OnIOMNotify(WPARAM wParam, LPARAM lParam)
{
	
	switch(LOWORD(wParam))
	{
	case IOMN_CALL://呼叫到来
		{
			sockaddr_in sc=AVIO.GetRemoteAddr();
			char sz[50];
			sprintf(sz,"%d.%d.%d.%d",
				sc.sin_addr.S_un.S_un_b.s_b1,
				sc.sin_addr.S_un.S_un_b.s_b2,
				sc.sin_addr.S_un.S_un_b.s_b3,
				sc.sin_addr.S_un.S_un_b.s_b4);
			SetActiveWindow(m_hWnd);
			
			if(m_RingDlg.DoModal(m_hWnd,sz))
			{
				
				ShowWindow(m_LocalVideoWnd,SW_SHOWNORMAL);
				ShowWindow(m_hWnd,SW_SHOWNORMAL);
				SetForegroundWindow(m_hWnd);
				SetActiveWindow(m_hWnd);
				m_uTalkTime=0;
				m_nTimePass=GetTickCount();
				m_nDataRcv=0;

				m_nDataSend=0;
				m_nFrameCount=0;
				m_iZeroCount=0;
				SetTimer(m_hWnd,2,1000,0);				
				AVIO.Accept();
				//接受了呼叫,把该次事件记录到log文件中
				char szPath[256];
				GetModuleFileName(0,szPath,255);
				int i;
				for(i=strlen(szPath);i>0;i--)
				{
					if(szPath[i]=='\\')
					{
						szPath[i+1]=0;
						break;
					}
				}
				
				strcpy(szPath+strlen(szPath),"log.txt");
				SYSTEMTIME st;
				GetLocalTime(&st);
				char szDate[20];
				char szTime[20];
				sprintf(szDate,"%d-%d-%d",st.wYear,st.wMonth,st.wDay);
				sprintf(szTime,"%d:%d:%d",st.wHour,st.wMinute,st.wSecond);
				char szLog[100];
				sprintf(szLog,"接受了%s的通话请求",sz);
				WritePrivateProfileString(szDate,szTime,szLog,szPath);
							
				

			}
			else
				AVIO.Refuse();
		}break;
		//the request is accepted,so begin to talk
	case IOMN_ACCEPT:
		{
			SendMessage(m_CallDlg,WM_COMMAND,IDC_OK,0);
			ShowWindow(m_LocalVideoWnd,SW_SHOWNORMAL);
			ShowWindow(m_hWnd,SW_SHOWNORMAL);
			AVIO.OnAccept();			
			
			m_uTalkTime=0;
			m_nTimePass=GetTickCount();
			m_nDataRcv=0;
			m_nDataSend=0;
			m_nFrameCount=0;
			m_iZeroCount=0;
			SetTimer(m_hWnd,2,1000,0);
			//write the talking event into log file
			sockaddr_in sc=AVIO.GetRemoteAddr();
			char sz[50];
			sprintf(sz,"%d.%d.%d.%d",
				sc.sin_addr.S_un.S_un_b.s_b1,
				sc.sin_addr.S_un.S_un_b.s_b2,
				sc.sin_addr.S_un.S_un_b.s_b3,
				sc.sin_addr.S_un.S_un_b.s_b4);
			char szPath[256];
			GetModuleFileName(0,szPath,255);
			int i;
			for(i=strlen(szPath);i>0;i--)
			{
				if(szPath[i]=='\\')
				{
					szPath[i+1]=0;
					break;
				}
			}
			
			strcpy(szPath+strlen(szPath),"log.txt");
			SYSTEMTIME st;
			GetLocalTime(&st);
			char szDate[20];
			char szTime[20];
			sprintf(szDate,"%d-%d-%d",st.wYear,st.wMonth,st.wDay);
			sprintf(szTime,"%d:%d:%d",st.wHour,st.wMinute,st.wSecond);
			char szLog[100];
			sprintf(szLog,"%s接受了你的通话请求",sz);
			WritePrivateProfileString(szDate,szTime,szLog,szPath);
		}
		break;
	case IOMN_CONNECTED:
		{
			if(IsWindow(m_CallDlg))
			{
				m_CallDlg.Connected();
			}
		}
		break;

	case IOMN_END:
		{
			AVIO.EndTalk();
			KillTimer(m_hWnd,2);
			DrawFps("");
			DrawDataRate("");
			ShowWindow(m_vs,SW_HIDE);
			ShowWindow(m_LocalVideoWnd.m_vs,SW_HIDE);
			ShowWindow(m_RemoteVideoWnd.m_vs,SW_HIDE);
			if(IsWindow(m_RingDlg))
				EndDialog(m_RingDlg,FALSE);
			else
			{
				if(HIWORD(wParam)==E_USER)
				{
					CMsgBox::MessageBox(m_hWnd,IDS_MSG_ENDTALK,IDS_MSG,MB_OK,IDI_INFO);
					
				}
			}
			
		}
		break;
	case IOMN_REFUSE:
		{
			switch(HIWORD(wParam))
			{
			case R_TIMEOUT:
				{					
					m_CallDlg.FailConnect();
				}
				break;
			case R_USER:
				{
					m_CallDlg.Refuse();
				}				
				break;
			case R_BUSY:
				{
					m_CallDlg.Busy();
				}
				break;
			}
			
		}
		break;
		//the error of aviomgr
	case IOMN_ERR:
		{
			switch(HIWORD(wParam))
			{
			case IOME_SOCKET:
				CMsgBox::MessageBox(m_hWnd,IDS_ERR_NET_SOCKET,IDS_ERR,MB_OK,IDI_ERR);
				break;
			case IOME_AUDIO_IN:
				CMsgBox::MessageBox(m_hWnd,IDS_ERR_AUDIO_IN,IDS_ERR,MB_OK,IDI_ERR);
				break;
			case IOME_AUDIO_OUT:
				CMsgBox::MessageBox(m_hWnd,IDS_ERR_AUDIO_OUT,IDS_ERR,MB_OK,IDI_ERR);
				break;
			case IOME_VIDEO_IN:
				m_LocalVideoWnd.SetErrTxt("无法打开视频输入设备");
				break;
			case IOME_VIDEO_OUT:
				//always good
				break;
			case IOME_AUDIO_CODEC:
				CMsgBox::MessageBox(m_hWnd,IDS_ERR_AUDIO_CODEC,IDS_ERR,MB_OK,IDI_ERR);
				break;
			case IOME_VIDEO_CODEC:
				CMsgBox::MessageBox(m_hWnd,IDS_ERR_VIDEO_CODEC,IDS_ERR,MB_OK,IDI_ERR);
				break;
			}
		}break;
		//Txt msg come,or notify that the txt msg has been confermed received
	case IOMN_TXT:
		{
			if(HIWORD(wParam))
			{
				char sz[500];
				sprintf(sz,"%s:%s","我",(char*)lParam);
				m_MsgTalk.AddMsg(sz);
			}
			else
			{
				sockaddr_in sc=AVIO.GetCurrentAddr();
				char sz[500];
				sprintf(sz,"%d.%d.%d.%d:%s",
					sc.sin_addr.S_un.S_un_b.s_b1,
					sc.sin_addr.S_un.S_un_b.s_b2,
					sc.sin_addr.S_un.S_un_b.s_b3,
					sc.sin_addr.S_un.S_un_b.s_b4,(char*)lParam);
				m_MsgTalk.AddMsg(sz);
				if(CSetupDlg::Setup.bAutoMsg)
				{
					ShowWindow(m_MsgTalk,SW_SHOW);
					SetForegroundWindow(m_MsgTalk);
					SetActiveWindow(m_MsgTalk);
				}
			}
		}break;
		//the video quality was set by aviomgr automatically
	case IOMN_VQSET:
		{
			m_sldVideoQ.SetPos(HIWORD(wParam));

		}break;
	}
}
/*------------------------------------------------------------------------------*/
//when the output volume was changed,this would be invoked
void CALLBACK CMainWnd::OutVolumeChanged( DWORD dwCurrentVolume, DWORD dwUserValue )
{
	CMainWnd* p=(CMainWnd*)dwUserValue;
	p->m_sldAudioOut.SetPos(dwCurrentVolume*100/
		(p->m_VoOutCtrl.GetMaximalVolume()-p->m_VoOutCtrl.GetMinimalVolume()));
	
}
/*------------------------------------------------------------------------------*/
void CALLBACK CMainWnd::InVolumeChanged( DWORD dwCurrentVolume, DWORD dwUserValue )
{
	CMainWnd* p=(CMainWnd*)dwUserValue;
	p->m_sldAudioIn.SetPos(dwCurrentVolume*100/
		(p->m_VoInCtrl.GetMaximalVolume()-p->m_VoInCtrl.GetMinimalVolume()));

}
/*------------------------------------------------------------------------------*/
//when the setup was changed,this would be call
void CMainWnd::OnSetup(SETUP *Setup)
{
	char sz[20];
	sz[1]=0;
	//autorun
	if(Setup->bAutoRun)
	{
		sz[0]='1';
		HKEY  hKey=NULL;
		DWORD dwValueType=REG_SZ;
		DWORD dwStrCb=128;
		DWORD  dwDisposition;
		char szPath[256];
		GetModuleFileName(0,szPath,255);
		if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"),0,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKey)!=ERROR_SUCCESS)
		{	
			RegCreateKeyEx(HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"),0, NULL, REG_OPTION_NON_VOLATILE, KEY_WRITE, 
				NULL, &hKey, &dwDisposition);
			
		}
		if (RegSetValueEx(hKey,"NetTalk",0,REG_SZ,(const BYTE*)szPath,dwStrCb)!=ERROR_SUCCESS) 
		{
			RegCloseKey(hKey);
			
		}
	}
	else
	{
		sz[0]='0';
		HKEY  hKey=NULL;
		if(RegOpenKeyEx(HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Run"),0,KEY_QUERY_VALUE|KEY_SET_VALUE,&hKey)==ERROR_SUCCESS)
		{
			RegDeleteValue(hKey,"NetTalk");
		}

	}
	//
	AVIO.EnableBandAdjust(Setup->bBandAdjust);
	//
	AVIO.Enable(!Setup->bRefuseCall);	
	//when refuse call,the avio was disable,change the notify-try icon
	if(Setup->bRefuseCall)
	{
		m_TrayNotify.SetIcon(LoadIcon(hInstX,LPCTSTR(IDI_DISABLE)));
		m_TrayNotify.Refresh();
	}
	else
	{
		m_TrayNotify.SetIcon(LoadIcon(hInstX,LPCTSTR(IDI_MAIN)));
		m_TrayNotify.Refresh();
	}
	//unregister the old hotkey,and register the new hotkey
	UnregisterHotKey(m_hWnd,1);
	UINT Mod=0;
	if(HOTKEYF_ALT&HIBYTE(Setup->wHotKey))
		Mod|=MOD_ALT;
	if(HOTKEYF_CONTROL&HIBYTE(Setup->wHotKey))
		Mod|=MOD_CONTROL;
	if(HOTKEYF_SHIFT&HIBYTE(Setup->wHotKey))
		Mod|=MOD_SHIFT;	
	if(!RegisterHotKey(m_hWnd,1,Mod,LOBYTE(Setup->wHotKey)))
		CMsgBox::MessageBox(m_hWnd,IDS_ERR_HOTKEY,IDS_ERR,MB_OK,IDI_INFO);
}
/*------------------------------------------------------------------------------*/
//
void CMainWnd::OnTrayNotify(WPARAM wParam, LPARAM lParam)
{
	switch(lParam)
	{
	case WM_LBUTTONDBLCLK:
		{
			ShowWindow(m_hWnd,SW_SHOWNORMAL);
			SetForegroundWindow(m_hWnd);
			SetActiveWindow(m_hWnd);
		}
		break;
	case WM_RBUTTONDOWN:
		{
			HMENU hMenu=LoadMenu(hInstX,LPCTSTR(IDR_POP));
			HMENU hSub=GetSubMenu(hMenu,0);
			SetForegroundWindow(m_hWnd);
			

			POINT pt;
			GetCursorPos(&pt);
			
			DWORD dwID=TrackPopupMenu(hSub,TPM_RIGHTALIGN|TPM_BOTTOMALIGN|TPM_RETURNCMD,pt.x,pt.y,0,m_hWnd,0);
			{
				switch(dwID)
				{
				case ID_SHOWCHATER:
					SendMessage(m_hWnd,WM_COMMAND,IDC_MSG,0);
					break;
				case ID_SHOW:
					ShowWindow(m_hWnd,SW_SHOWNORMAL);
					SetForegroundWindow(m_hWnd);
					SetActiveWindow(m_hWnd);
					break;
				case ID_EXIT:
					SendMessage(m_hWnd,WM_CLOSE,0,0);
					break;
				case ID_ABOUT:
					if(IsWindowEnabled(m_hWnd))
						SendMessage(m_hWnd,WM_COMMAND,IDC_ABOUT,0);
					break;
				case ID_CALL:
					if(IsWindowEnabled(m_hWnd))
						SendMessage(m_hWnd,WM_COMMAND,IDC_CALL,0);
					break;
				case ID_H:
					SendMessage(m_hWnd,WM_COMMAND,IDC_HP,0);
					break;
				}
			}

		}

		
	}
}
/*------------------------------------------------------------------------------*/
//implementation of about dialog
CAboutDlg::CAboutDlg()
{
	
}
/*------------------------------------------------------------------------------*/
CAboutDlg::~CAboutDlg()
{

}
/*------------------------------------------------------------------------------*/
LRESULT CAboutDlg::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_COMMAND:
		{
			CGraphDlg::OnCommand(wParam,lParam);
			switch(LOWORD(wParam))
			{
			case IDC_LOGO:
				KillTimer(m_hWnd,1);
				ShowWindow(m_cd1,SW_HIDE);
				ShowWindow(m_cd2,SW_HIDE);
				ShowWindow(m_rw,SW_SHOW);
				break;
			case IDC_CREDIT:
				if(!IsWindowVisible(m_cd1))
					SetTimer(m_hWnd,1,30,0);
				SetTimer(m_hWnd,1,30,0);
				ShowWindow(m_cd1,SW_SHOW);
				ShowWindow(m_cd2,SW_SHOW);
				ShowWindow(m_rw,SW_HIDE);
				break;
			}
		
		}
		break;
	case WM_INITDIALOG:
		{
			CGraphDlg::OnInitDialog();
			SetWindowText(m_hWnd,"关于NetTalk");
			MoveWindow(GetDlgItem(m_hWnd,IDC_CONTAINER),7,50,286,182,FALSE);
			m_rw.Create((CRectX&)CRectX(0,0,286,182),GetDlgItem(m_hWnd,IDC_CONTAINER),IDB_LOGO1,286,182);
			m_cd1.Create(GetDlgItem(m_hWnd,IDC_CONTAINER));
			m_cd2.Create(GetDlgItem(m_hWnd,IDC_CONTAINER));
			SetWindowPos(m_cd1,0,0,0,0,0,SWP_NOSIZE);
			CRectX rc;
			GetWindowRect(m_cd1,&rc);
			SetWindowPos(m_cd2,0,0,rc.Height(),0,0,SWP_NOSIZE);
			SendDlgItemMessage(m_hWnd,IDC_LOGO,BM_SETCHECK,BST_CHECKED,0);
			return FALSE;
		}
		break;
	case WM_TIMER:
		{
			CGraphDlg::OnTimer(wParam);
			CRectX rc1,rc2,rc3;
			GetWindowRect(m_cd1,&rc1);
			GetWindowRect(m_cd2,&rc2);
			GetWindowRect(GetDlgItem(m_hWnd,IDC_CONTAINER),&rc3);
			OffsetRect(&rc1,-rc3.left,-rc3.top);
			OffsetRect(&rc2,-rc3.left,-rc3.top);
			
			SetWindowPos(m_cd1,0,0,rc1.top-1,0,0,SWP_NOSIZE);
			SetWindowPos(m_cd2,0,0,rc2.top-1,0,0,SWP_NOSIZE);
			if(rc1.bottom<0)
			{
				SetWindowPos(m_cd1,0,0,rc2.bottom-1,0,0,SWP_NOSIZE);
			}
			if(rc2.bottom<0)
			{
				SetWindowPos(m_cd2,0,0,rc1.bottom-1,0,0,SWP_NOSIZE);
			}
			
		}break;
	

	default:
		return CGraphDlg::WndProc(uMsg,wParam,lParam);
	}
	return TRUE;
}
/*------------------------------------------------------------------------------*/
//implementation of IP input dialog
CIPInput::CIPInput()
{
	m_szIP[0]=0;
	m_uPort=0;
}
/*------------------------------------------------------------------------------*/
CIPInput::~CIPInput()
{

}
/*------------------------------------------------------------------------------*/
LRESULT CIPInput::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_COMMAND:
		{
			
			switch(LOWORD(wParam))
			{
			case IDC_OK:
				{
					GetDlgItemText(m_hWnd,IDC_IP,m_szIP,29);
					if(strlen(m_szIP)>0)
					{
						//set the result to variables
						char sz[20];
						GetDlgItemText(m_hWnd,IDC_PORT,sz,19);
						m_uPort=(unsigned short)strtoul(sz,0,10);
						
						//update the recent call address
						HWND hcb=GetDlgItem(m_hWnd,IDC_IP);
						int iItem=SendMessage(hcb,CB_FINDSTRING,-1,(LPARAM)m_szIP);
						if(iItem<0)
							SendMessage(hcb,CB_INSERTSTRING,0,(LPARAM)m_szIP);
						else
						{
							SendMessage(hcb,CB_DELETESTRING,iItem,0);
							SendMessage(hcb,CB_INSERTSTRING,0,(LPARAM)m_szIP);
						}
						
						int iCount=SendMessage(hcb,CB_GETCOUNT,0,0);
						if(iCount>20)
							iCount=20;
						char szI[4];
						
						for(int i=0;i<iCount;i++)
						{
							sprintf(szI,"%d",i);
							SendMessage(hcb,CB_SETCURSEL,iCount-i-1,0);
							GetWindowText(hcb,m_szIP,256);
							WritePrivateProfileString("recent",szI,m_szIP,"NetTalk.ini");
						}						
						sprintf(szI,"%d",iCount);
						WritePrivateProfileString("recent","count",szI,"NetTalk.ini");
						//
						EndDialog(m_hWnd,TRUE);
					}

				}
				break;
			case IDC_CANCEL:
				EndDialog(m_hWnd,FALSE);
				break;
			case IDC_ADDR:
				{
					HWND h=GetParent(m_hWnd);
					EndDialog(m_hWnd,FALSE);
					CAddrBook ab;
					ab.DoModal(LPCTSTR(IDD_ADDR),h);
				}
				break;
			}
			CGraphDlg::OnCommand(wParam,lParam);
		}
		break;
	case WM_INITDIALOG:
		{
			SetWindowText(m_hWnd,"请输入对方IP或计算机名");
			CGraphDlg::OnInitDialog();
			char sz[10];
			sprintf(sz,"%d",PORT);
			SetDlgItemText(m_hWnd,IDC_PORT,sz);
			//载入最近呼叫
			int c=GetPrivateProfileInt("recent","count",0,"NetTalk.ini");
			if(c>=20)
			{
				c=20;
			}
			char szStr[256];
			for(int i=0;i<c;i++)
			{
				char szI[4];
				sprintf(szI,"%d",i);
				
				if(GetPrivateProfileString("recent",szI,"",szStr,256,"NetTalk.ini"))
				{
					SendMessage(GetDlgItem(m_hWnd,IDC_IP),CB_INSERTSTRING,0,(LPARAM)szStr);
					
				}				
				
			}
			SendMessage(GetDlgItem(m_hWnd,IDC_IP),CB_SETCURSEL,0,0);
			
		}
		break;
	case WM_ERASEBKGND:
		{
			CGraphDlg::OnEraseBkgnd((HDC)wParam);
			DrawIcon((HDC)wParam,10,28,LoadIcon(hInstX,LPCTSTR(IDI_PHONE)));
		}
		break;
	case WM_CLOSE:
		{
			EndDialog(m_hWnd,FALSE);
		}
		break;	
	default:
		return CGraphDlg::WndProc(uMsg,wParam,lParam);
	}
	return TRUE;
}
/*------------------------------------------------------------------------------*/
//implementation of setup dlg
CSetupDlg::CSetupDlg()
{
}
/*------------------------------------------------------------------------------*/
CSetupDlg::~CSetupDlg()
{
}
/*------------------------------------------------------------------------------*/
LRESULT CSetupDlg::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{	
	case WM_DESTROY:
		CGraphDlg::OnDestroy();
		PlaySound(0,0,0);
		break;
	case WM_INITDIALOG:
		
		return OnInitDialog();
		break;
	case WM_COMMAND:
		return OnCommand(wParam,lParam);
		
		break;
		
	default:
		return CGraphDlg::WndProc(uMsg,wParam,lParam);
	}
	return TRUE;	
	
}
/*------------------------------------------------------------------------------*/

void CSetupDlg::LoadSetup()
{

	Setup.bAutoRun=(BOOL)GetPrivateProfileInt("setup","auto",0,"NetTalk.ini");
	Setup.bInitShow=(BOOL)GetPrivateProfileInt("setup","initshow",0,"NetTalk.ini");
	Setup.bMiniHide=(BOOL)GetPrivateProfileInt("setup","minihide",1,"NetTalk.ini");
	Setup.bRing=(BOOL)GetPrivateProfileInt("setup","playring",1,"NetTalk.ini");
	Setup.bRingUser=(BOOL)GetPrivateProfileInt("setup","ringuser",0,"NetTalk.ini");
	Setup.bAutoMsg=(BOOL)GetPrivateProfileInt("setup","automsg",1,"NetTalk.ini");
	Setup.bRefuseCall=(BOOL)GetPrivateProfileInt("setup","refusecall",0,"NetTalk.ini");
	Setup.bBandAdjust=(BOOL)GetPrivateProfileInt("setup","bandadjust",1,"NetTalk.ini");
	Setup.wHotKey=0xffff&GetPrivateProfileInt("setup","hotkey",MAKEWORD('A',HOTKEYF_ALT|HOTKEYF_CONTROL),"NetTalk.ini");
	
	GetPrivateProfileString("setup","ringpath","",Setup.szRingPath,sizeof(Setup.szRingPath),"NetTalk.ini");

}
/*------------------------------------------------------------------------------*/
void CSetupDlg::SaveSetup()
{
	char sz[20];
	sz[1]=0;
	WritePrivateProfileString("setup","auto",sz,"NetTalk.ini");
	if(Setup.bInitShow)
		sz[0]='1';
	else
		sz[0]='0';
	WritePrivateProfileString("setup","initshow",sz,"NetTalk.ini");
	if(Setup.bMiniHide)
		sz[0]='1';
	else
		sz[0]='0';
	WritePrivateProfileString("setup","minihide",sz,"NetTalk.ini");
	if(Setup.bRing)
		sz[0]='1';
	else
		sz[0]='0';
	WritePrivateProfileString("setup","playring",sz,"NetTalk.ini");
	if(Setup.bRingUser)
		sz[0]='1';
	else
		sz[0]='0';
	WritePrivateProfileString("setup","ringuser",sz,"NetTalk.ini");
	if(Setup.bAutoMsg)
		sz[0]='1';
	else
		sz[0]='0';
	WritePrivateProfileString("setup","automsg",sz,"NetTalk.ini");
	if(Setup.bRefuseCall)
		sz[0]='1';
	else
		sz[0]='0';
	WritePrivateProfileString("setup","refusecall",sz,"NetTalk.ini");
	if(Setup.bBandAdjust)
		sz[0]='1';
	else
		sz[0]='0';
	WritePrivateProfileString("setup","bandadjust",sz,"NetTalk.ini");

	sprintf(sz,"%d",Setup.wHotKey);	
	WritePrivateProfileString("setup","hotkey",sz,"NetTalk.ini");
	
	WritePrivateProfileString("setup","ringpath",Setup.szRingPath,"NetTalk.ini");
	
}
/*------------------------------------------------------------------------------*/
BOOL CSetupDlg::OnInitDialog()
{
	CGraphDlg::OnInitDialog();
	SetWindowText(m_hWnd,"NetTalk设置");
	if(Setup.bAutoRun)
		SendMessage(GetDlgItem(m_hWnd,IDC_AUTORUN),BM_SETCHECK,BST_CHECKED,0);
	if(Setup.bInitShow)
		SendMessage(GetDlgItem(m_hWnd,IDC_INITSHOW),BM_SETCHECK,BST_CHECKED,0);
	if(Setup.bMiniHide)
		SendMessage(GetDlgItem(m_hWnd,IDC_MINIHIDE),BM_SETCHECK,BST_CHECKED,0);
	if(Setup.bRing)
		SendMessage(GetDlgItem(m_hWnd,IDC_PLAYRING),BM_SETCHECK,BST_CHECKED,0);
	if(Setup.bRingUser)
		SendMessage(GetDlgItem(m_hWnd,IDC_USERRING),BM_SETCHECK,BST_CHECKED,0);
	
	if(Setup.bAutoMsg)
		SendMessage(GetDlgItem(m_hWnd,IDC_AUTOMSG),BM_SETCHECK,BST_CHECKED,0);
	if(Setup.bRefuseCall)
		SendMessage(GetDlgItem(m_hWnd,IDC_REFUSECALL),BM_SETCHECK,BST_CHECKED,0);
	if(Setup.bBandAdjust)
		SendMessage(GetDlgItem(m_hWnd,IDC_BANDADJUST),BM_SETCHECK,BST_CHECKED,0);
	EnableWindow(GetDlgItem(m_hWnd,IDC_PLAY),Setup.bRingUser);
	EnableWindow(GetDlgItem(m_hWnd,IDC_BROWSE),Setup.bRingUser);
	SendDlgItemMessage(m_hWnd,IDC_HOTKEY,HKM_SETHOTKEY,Setup.wHotKey,0);
	return FALSE;
}
/*------------------------------------------------------------------------------*/
BOOL CSetupDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
	CGraphDlg::OnCommand(wParam,lParam);
	switch(LOWORD(wParam))
	{
	case IDC_OK:
		{	

			Setup.wHotKey=(WORD)SendDlgItemMessage(m_hWnd,IDC_HOTKEY,HKM_GETHOTKEY,0,0);
			SaveSetup();
			OnOK();
			SendMessage(GetParent(m_hWnd),WM_USER_SETUP,0,(LPARAM)&Setup);
		}
		break;
	case IDC_AUTORUN:		
		Setup.bAutoRun^=1;		
		break;
	case IDC_INITSHOW:
		Setup.bInitShow^=1;
		break;
	case IDC_MINIHIDE:
		Setup.bMiniHide^=1;
		break;
	case IDC_PLAYRING:
		Setup.bRing^=1;
		break;
	case IDC_USERRING:
		Setup.bRingUser^=1;
		EnableWindow(GetDlgItem(m_hWnd,IDC_PLAY),Setup.bRingUser);
		EnableWindow(GetDlgItem(m_hWnd,IDC_BROWSE),Setup.bRingUser);
		break;
	case IDC_AUTOMSG:
		Setup.bAutoMsg^=1;
		break;
	case IDC_REFUSECALL:
		Setup.bRefuseCall^=1;
		break;
	case IDC_BANDADJUST:
		Setup.bBandAdjust^=1;
		break;
	case IDC_CANCEL:
		OnCancel();
		break;
	case IDC_BROWSE:
		{
			OPENFILENAME ofn;
			ZeroMemory(&ofn,sizeof(ofn));
			ofn.lStructSize=sizeof(ofn);
			ofn.hInstance=GetModuleHandle(0);
			ofn.hwndOwner=m_hWnd;
			char szFilter[100];
			char* p=szFilter;
			strcpy(p,"波形文件(*.wav)");
			p+=strlen(p)+1;
			strcpy(p,"*.wav");
			p+=strlen(p)+1;
			*p=0;
			ofn.lpstrFilter=szFilter;
			char szFile[256]="";
			ofn.lpstrFile=szFile;
			ofn.nMaxFile=256;
			ofn.lpstrTitle="请选择";
			ofn.Flags=OFN_FILEMUSTEXIST;
			
			if(GetOpenFileName(&ofn))
			{
				strcpy(Setup.szRingPath,szFile);
			}
		}
		break;
	case IDC_PLAY:
		PlaySound(Setup.szRingPath,0,SND_FILENAME|SND_ASYNC);
		break;
	}
	return TRUE;
}


/*------------------------------------------------------------------------------*/
//implementation of ring dlg
CRingDlg::CRingDlg()
{

}
/*------------------------------------------------------------------------------*/
CRingDlg::~CRingDlg()
{

}
/*------------------------------------------------------------------------------*/
LRESULT CRingDlg::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_INITDIALOG:
		return OnInitDialog();
		break;
	case WM_DESTROY:
		CGraphDlg::OnDestroy();
		KillTimer(m_hWnd,1);
		PlaySound(0,0,0);
		break;
	case WM_COMMAND:
		return OnCommand(wParam,lParam);
	case WM_ERASEBKGND:
		OnEraseBkgnd((HDC)wParam);
		return TRUE;
	case WM_TIMER:
		CGraphDlg::OnTimer(wParam);
		if(wParam==1&&CSetupDlg::Setup.bRing)
		{
			if(CSetupDlg::Setup.bRingUser)
				PlaySound(CSetupDlg::Setup.szRingPath,0,SND_FILENAME|SND_ASYNC);
			else
				PlaySound(LPCTSTR(IDR_CALL),hInstX,SND_RESOURCE|SND_ASYNC);
		}
		break;
	default:
		return CGraphDlg::WndProc(uMsg,wParam,lParam);
	}
	return TRUE;
}
/*------------------------------------------------------------------------------*/
BOOL CRingDlg::OnInitDialog()
{
	CGraphDlg::OnInitDialog();
	SetWindowText(m_hWnd,m_szCaller);
	char szTxt[256];
	sprintf(szTxt,"%s发来呼叫请求\r\r\n要接受请求吗?",m_szCaller);
	SetDlgItemText(m_hWnd,IDC_TXT,szTxt);
	SetDlgItemText(m_hWnd,IDC_OK,"是(&Y)");
	SetDlgItemText(m_hWnd,IDC_CANCEL,"否(&N)");
	SetTimer(m_hWnd,1,3000,0);
	if(CSetupDlg::Setup.bRing)
	{
		if(CSetupDlg::Setup.bRingUser)
			PlaySound(CSetupDlg::Setup.szRingPath,0,SND_FILENAME|SND_ASYNC);
		else
			PlaySound(LPCTSTR(IDR_CALL),hInstX,SND_RESOURCE|SND_ASYNC);
	}
	SetWindowPos(m_hWnd,HWND_TOPMOST,0,0,0,0,SWP_NOSIZE|SWP_NOMOVE);
	return FALSE;
}
/*------------------------------------------------------------------------------*/
BOOL CRingDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
	CGraphDlg::OnCommand(wParam,lParam);
	switch(LOWORD(wParam))
	{
	case IDC_OK:
		EndDialog(m_hWnd,TRUE);
		break;
	case IDC_CANCEL:
		EndDialog(m_hWnd,FALSE);
		break;
	
	}
	return TRUE;
}

/*------------------------------------------------------------------------------*/

BOOL CRingDlg::DoModal(HWND hParent, char *szCaller)
{
	m_szCaller=szCaller;
	return CGraphDlg::DoModal(LPCTSTR(IDD_MSGBOX),hParent);
}
/*------------------------------------------------------------------------------*/
void CRingDlg::OnEraseBkgnd(HDC hdc)
{
	CGraphDlg::OnEraseBkgnd(hdc);
	DrawIcon(hdc,25,45,LoadIcon(hInstX,LPCTSTR(IDI_GLOBAL)));
}
/*------------------------------------------------------------------------------*/
//implementation of call dlg
CCallDlg::CCallDlg()
{
}
/*------------------------------------------------------------------------------*/
CCallDlg::~CCallDlg()
{

}
/*------------------------------------------------------------------------------*/
LRESULT CCallDlg::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_INITDIALOG:
		return OnInitDialog();
		break;
	case WM_COMMAND:
		return OnCommand(wParam,lParam);
	case WM_ERASEBKGND:
		OnEraseBkgnd((HDC)wParam);
		return TRUE;
	case WM_CLOSE:
		break;
	default:
		return CGraphDlg::WndProc(uMsg,wParam,lParam);
	}
	return TRUE;
}
/*------------------------------------------------------------------------------*/
BOOL CCallDlg::OnCommand(WPARAM wParam, LPARAM lParam)
{
	CGraphDlg::OnCommand(wParam,lParam);
	switch(LOWORD(wParam))
	{
	case IDC_CANCEL:
		EndDialog(m_hWnd,FALSE);
		break;
	case IDC_OK:
		EndDialog(m_hWnd,TRUE);
		break;
	}
	return TRUE;
}
/*------------------------------------------------------------------------------*/
void CCallDlg::OnEraseBkgnd(HDC hdc)
{
	CGraphDlg::OnEraseBkgnd(hdc);
	DrawIcon(hdc,25,45,LoadIcon(hInstX,LPCTSTR(IDI_GLOBAL)));
}
/*------------------------------------------------------------------------------*/
BOOL CCallDlg::OnInitDialog()
{
	CGraphDlg::OnInitDialog();
	ShowWindow(m_btnClose,SW_HIDE);
	SetWindowText(m_hWnd,"请稍候");
	char szTxt[128];
	sprintf(szTxt,"正在连接计算机  %s...",m_szDst);
	SetDlgItemText(m_hWnd,IDC_TXT,szTxt);
	ShowWindow(GetDlgItem(m_hWnd,IDC_OK),SW_HIDE);
	ShowWindow(GetDlgItem(m_hWnd,IDC_CANCEL),SW_HIDE);
	SetDlgItemText(m_hWnd,IDC_CANCEL,"取消");
	SetDlgItemText(m_hWnd,IDC_OK,"确定");
	return TRUE;

}
/*------------------------------------------------------------------------------*/
BOOL CCallDlg::DoModal(HWND hParent, char *szDst)
{
	m_szDst=szDst;
	return CGraphDlg::DoModal(LPCTSTR(IDD_MSGBOX),hParent);
}
/*------------------------------------------------------------------------------*/
//when connected,
void CCallDlg::Connected()
{
	if(IsWindow(m_hWnd))
	{
		char szTxt[]="已经连接到目标计算机\r\r\n请等待对方回应...";
		SetDlgItemText(m_hWnd,IDC_TXT,szTxt);
		
		ShowWindow(GetDlgItem(m_hWnd,IDC_CANCEL),SW_SHOW);
		EnableWindow(GetDlgItem(m_hWnd,IDC_OK),FALSE);
	}
}
/*------------------------------------------------------------------------------*/
//fail to connect
void CCallDlg::FailConnect()
{
	if(IsWindow(m_hWnd))
	{
		char szTxt[]="无法连接到目标计算机";
		SetDlgItemText(m_hWnd,IDC_TXT,szTxt);
		
		ShowWindow(GetDlgItem(m_hWnd,IDC_OK),SW_SHOW);
		
	}

}
/*------------------------------------------------------------------------------*/
//the request is refused by user
void CCallDlg::Refuse()
{
	if(IsWindow(m_hWnd))
	{
		char szTxt[]="对方拒绝了您的通话请求";
		SetDlgItemText(m_hWnd,IDC_TXT,szTxt);
		
		ShowWindow(GetDlgItem(m_hWnd,IDC_OK),SW_SHOW);
		ShowWindow(GetDlgItem(m_hWnd,IDC_CANCEL),SW_HIDE);
		
	}
}
/*------------------------------------------------------------------------------*/
//the request is refuse for NetTalk is busy
void CCallDlg::Busy()
{
	if(IsWindow(m_hWnd))
	{
		char szTxt[]="对方NetTalk繁忙，您的通话被拒绝";
		SetDlgItemText(m_hWnd,IDC_TXT,szTxt);
		
		ShowWindow(GetDlgItem(m_hWnd,IDC_OK),SW_SHOW);
		
	}
}
/*------------------------------------------------------------------------------*/
//the implementation of credit dlg
LRESULT CCreditDlg::WndProc(UINT uMsg, WPARAM wParam, LPARAM lParam)
{
	switch(uMsg)
	{
	case WM_CTLCOLORDLG :
		return (LRESULT)GetStockObject(BLACK_BRUSH);
		break;
		//set the color the static ctrl
	case WM_CTLCOLORSTATIC:

		SetTextColor((HDC)wParam,0x00ffb093);
		SetBkMode((HDC)wParam,TRANSPARENT);
		return (LRESULT)GetStockObject(BLACK_BRUSH);
		break;
	

	default:
		return CDialogX::WndProc(uMsg,wParam,lParam);
	}
	return TRUE;
}
/*------------------------------------------------------------------------------*/
BOOL CCreditDlg::Create(HWND hParent)
{
	return CDialogX::Create((LPCTSTR)IDD_CREDITDLG,hParent);

}
