📄 phoneui.cpp
字号:
#include "stdafx.h"
#include "Resource.h"
#include "TestPhone.h"
#include "usb.h"
#include "Skype.h"
#include "Skypephone.h"
#include "Client.h"
#include "Call.h"
#include "CallCollection.h"
#include "User.h"
#include "UserCollection.h"
#include "Conversion.h"
#include "Command.h"
#include "mmsystem.h"
#include "Volume.h"
#include "PhoneUI.h"
#include <afxpriv.h> // for AfxLoadString
#include "Registry.h"
#include "wave.h"
#define C_Key_AUTORUN "Software\\Microsoft\\Windows\\CurrentVersion\\Run"
#define C_VALUE_AUTORUN "UsbPhone"
#define C_Key_APP "Software\\UsbPhone"
#define C_Key_Volume_Ring "Usbphone Ring Volume"
#define C_Key_Volume_InCall "Usbphone InCall Volume"
#define C_Key_Volume_Normal "Usbphone Normal Volume"
#define C_Key_MIC_Normal "Usbphone MIC Normal Volume"
#define C_Volume_Ring 0xC000
#define C_Volume_InCall 0x6000
#define C_Volume_Normal 0xA000
#define C_MIC_Normal 0x8000
#define C_MIC_STEP (0x10000/12)
#define C_VOLUME_STEP (0x10000/44)
BOOL m_AutoRun;
DWORD m_Mic_Cur;
DWORD m_Volume_Ring; //震铃
DWORD m_Volume_InCall; //通话
DWORD m_Volume_Normal; //平时
DWORD m_Volume_Min=0;
DWORD m_Volume_Max=0xffff;
void GetRegKeys(void)
{
BOOL result;
CRegistry reg;
if( ! reg.Open(C_Key_APP))
reg.CreateKey(C_Key_APP);
result =reg.GetRegistryKey(C_Key_Volume_Ring, &m_Volume_Ring, C_Volume_Ring);
result&=reg.GetRegistryKey(C_Key_Volume_InCall, &m_Volume_InCall, C_Volume_InCall);
result&=reg.GetRegistryKey(C_Key_Volume_Normal, &m_Volume_Normal, C_Volume_Normal);
result&=reg.GetRegistryKey(C_Key_MIC_Normal, &m_Mic_Cur, C_MIC_Normal);
CString FilePath;
reg.Open(C_Key_AUTORUN);
reg.Read(C_VALUE_AUTORUN, &FilePath);
if(FilePath.IsEmpty())
m_AutoRun=FALSE;
else
m_AutoRun=TRUE;
}
void SetRegKeys(void)
{
BOOL result;
CRegistry reg;
if( ! reg.Open(C_Key_APP))
reg.CreateKey(C_Key_APP);
result =reg.Write(C_Key_Volume_Ring, m_Volume_Ring);
result&=reg.Write(C_Key_Volume_InCall, m_Volume_InCall);
result&=reg.Write(C_Key_Volume_Normal, m_Volume_Normal);
result&=reg.Write(C_Key_MIC_Normal, m_Mic_Cur);
TCHAR AppPath[MAX_PATH];
GetModuleFileName(NULL, AppPath, MAX_PATH);
reg.Open(C_Key_AUTORUN);
if(m_AutoRun)
reg.Write(C_VALUE_AUTORUN, AppPath);
else
reg.DeleteValue(C_VALUE_AUTORUN);
}
UINT MainThread(LPVOID pParam)
{
TRACE("MainThread\n");
CPhoneUI *pPhoneUI=(CPhoneUI *)pParam;
pPhoneUI->MainFunc();
return (0);
}
CPhoneUI::CPhoneUI()
{
m_Width=C_LCD_WIDTH;
m_Height=C_LCD_HEIGHT;
CDC hDC;
hDC.CreateDC("DISPLAY",NULL,NULL,NULL);
m_Dc.CreateCompatibleDC(&hDC);
m_Bitmap.CreateCompatibleBitmap(&hDC, m_Width, m_Height);
m_Dc.SelectObject(&m_Bitmap);
long size;
BITMAP bmp;
size=m_Width*((m_Height+7)/8);
m_LcdBuff=new UCHAR[size];
m_Bitmap.GetBitmap(&bmp);
size=bmp.bmHeight*bmp.bmWidthBytes;
m_Bitmapbuff=new UCHAR[size];
GetRegKeys(); //取保存的参数设置
EventWait=CreateEvent(NULL,TRUE,FALSE,NULL);
ResetEvent(EventWait);
TerminalThread=NULL;
pTestPhone=NULL;
pUsbTerminal=NULL;
pSkypePhone=NULL;
pSkype=NULL;
pVolumeMaster=NULL;
pVolumeMic=NULL;
pWave=new CWave;
}
CPhoneUI::~CPhoneUI()
{
StopMainThread();
delete[] m_LcdBuff;
delete[] m_Bitmapbuff;
delete pWave;
pTestPhone=NULL;
pUsbTerminal=NULL;
pSkypePhone=NULL;
pSkype=NULL;
pVolumeMaster=NULL;
pVolumeMic=NULL;
}
void CPhoneUI::SetVolume(DWORD volume)
{
if(pVolumeMaster)
pVolumeMaster->SetCurrentVolume(volume);
}
void CPhoneUI::IncVolume(void)
{
DWORD CurVolume, MaxVolume;
if(!pVolumeMaster)
return;
CurVolume=pVolumeMaster->GetCurrentVolume();
MaxVolume=pVolumeMaster->GetMaximalVolume();
DWORD step;
if(m_KeyFlag) //长按
step=C_VOLUME_STEP;
else if(CurVolume > MaxVolume /4 *3)
step= C_VOLUME_STEP * 2;
else if(CurVolume > MaxVolume /3 *2)
step=C_VOLUME_STEP*4;
else
step=C_VOLUME_STEP*5;
CurVolume +=step;
if(CurVolume > MaxVolume)
CurVolume =MaxVolume;
pVolumeMaster->SetCurrentVolume(CurVolume);
}
void CPhoneUI::DecVolume(void)
{
DWORD CurVolume, MaxVolume, MinVolume;
if(!pVolumeMaster)
return;
CurVolume=pVolumeMaster->GetCurrentVolume();
MaxVolume=pVolumeMaster->GetMaximalVolume();
MinVolume=pVolumeMaster->GetMinimalVolume();
DWORD step;
if(m_KeyFlag) //长按
step=C_VOLUME_STEP;
else if(CurVolume > MaxVolume /4 *3)
step= C_VOLUME_STEP * 2;
else if(CurVolume > MaxVolume /3 *2)
step=C_VOLUME_STEP*4;
else
step=C_VOLUME_STEP*5;
if(CurVolume < step)
CurVolume =0;
else
CurVolume -=step;
pVolumeMaster->SetCurrentVolume(CurVolume);
}
void CPhoneUI::StartMainThread(void)
{
if(TerminalThread)
StopMainThread();
pVolumeMaster=new CVolume(MIXERLINE_COMPONENTTYPE_DST_SPEAKERS);
if(pVolumeMaster->IsAvailable())
{
pVolumeMaster->Enable();
pVolumeMaster->SetCurrentVolume(m_Volume_Normal);
m_Volume_Min=pVolumeMaster->GetMinimalVolume();
m_Volume_Max=pVolumeMaster->GetMaximalVolume();
}
else
{
delete(pVolumeMaster);
pVolumeMaster=NULL;
}
pVolumeMic=new CVolume(MIXERLINE_COMPONENTTYPE_DST_WAVEIN);
if(pVolumeMic->IsAvailable())
{
pVolumeMic->Enable();
pVolumeMic->SetCurrentVolume(m_Mic_Cur);
}
else
{
delete(pVolumeMic);
pVolumeMic=NULL;
}
m_Events=0;
ResetEvent(EventWait);
TerminalThread=AfxBeginThread(MainThread, this);
TRACE("AfxBeginThread TerminalThread %x \n",TerminalThread->m_nThreadID);
}
void CPhoneUI::StopMainThread(void)
{
if(TerminalThread)
{
Cls();
Show();
LcdLight(FALSE);
TerminateThread(TerminalThread->m_hThread, 0);
ShowResult();
TRACE("TerminateThread TerminalThread\n");
CloseHandle(TerminalThread->m_hThread);
ShowResult();
TRACE("CloseHandle TerminalThread\n");
TerminalThread=NULL;
}
if(pVolumeMaster)
{
delete(pVolumeMaster);
pVolumeMaster=NULL;
}
if(pVolumeMic)
{
delete(pVolumeMic);
pVolumeMic=NULL;
}
}
int CPhoneUI::WaitEvents(DWORD timeout)
{
while(1)
{
if(WaitForSingleObject(EventWait, timeout)==WAIT_TIMEOUT)
return(0);
ResetEvent(EventWait);
if(m_Events & C_MASK_NEWCALLIN)
{
m_Events ^= C_MASK_NEWCALLIN;
NewCallIn();
return(0);
}
if(KeyEvent())
return(1);
}
}
void CPhoneUI::OnUsbPhoneMsg(long wp, long lp)
{
if(wp==C_WM_KEY_DOWN)
{
OnKeyDown(lp);
}
else if(wp==C_WM_CONNECT_TERMINAL)
{
if(lp==C_CONNECT_ON )
StartMainThread();
else if(lp==C_CONNECT_OFF )
StopMainThread();
}
return ;
}
void CPhoneUI::KeyTong(int key)
{
int WaveID;
// return;
if(key&0xff00) //后续按键 不再放按键音
return;
switch(key & 0xFF)
{
case C_KEY_0:
WaveID=IDR_WAVE_D0;
break;
case C_KEY_1:
WaveID=IDR_WAVE_D1;
break;
case C_KEY_2:
WaveID=IDR_WAVE_D2;
break;
case C_KEY_3:
WaveID=IDR_WAVE_D3;
break;
case C_KEY_4:
WaveID=IDR_WAVE_D4;
break;
case C_KEY_5:
WaveID=IDR_WAVE_D5;
break;
case C_KEY_6:
WaveID=IDR_WAVE_D6;
break;
case C_KEY_7:
WaveID=IDR_WAVE_D7;
break;
case C_KEY_8:
WaveID=IDR_WAVE_D8;
break;
case C_KEY_9:
WaveID=IDR_WAVE_D9;
break;
case C_KEY_X:
WaveID=IDR_WAVE_STAR;
break;
default:
WaveID=IDR_WAVE_HASH;
break;
}
pWave->PlayFromRes( IDR_WAVE_D0, AfxGetInstanceHandle() );
}
void CPhoneUI::OnKeyDown(int key)
{
TRACE("CPhoneUI::OnKeyDown \n");
KeyTong(key);
m_KeyFlag=(key /0x100) &0xff;
key &= 0xFF;
switch(key)
{
case C_KEY_INCVOL:
IncVolume();
return;
case C_KEY_DECVOL:
DecVolume();
return;
}
m_key=key;
m_Events |= C_MASK_EVENT_KEY;
SetEvent(EventWait);
}
/*==========================================================================
; 背光
; 引脚:PA.1 PA(12H) PAC(13H)
==========================================================================*/
void CPhoneUI::LcdLight(bool on)
{
UCHAR buff[8];
buff[0]=C_CMD_AND; //PA.1 输出
buff[1]=0x13;
buff[2]=0xFD;
if(on)
{
buff[3]=C_CMD_AND; //灯亮 低电平
buff[4]=0x12;
buff[5]=0xFD;
}
else
{
buff[3]=C_CMD_OR; //灯灭 高电平
buff[4]=0x12;
buff[5]=0x02;
}
pUsbTerminal->UsbWrite(C_CMD_REPORT, buff, 6);
}
/*==========================================================================
; 写LCD控制命令
; 格式: CMD, Len, DATA1 .... DATAn
==========================================================================*/
void CPhoneUI::SetLcdPos(UCHAR X, UCHAR Y)
{
UCHAR lcdpage[9]={0xb0,0xb1,0xb2,0xb3,0xb4,0xb5,0xb6,0xb7,0xb8};
UCHAR buff[8];
X+=4; //偏移
buff[0]=C_CMD_LCD_COMMAND;
buff[1]=5;
buff[2]=0xe0;
buff[3]=0xee;
buff[4]=lcdpage[Y];
buff[5]=0x10 | (X >> 4 );
buff[6]=X & 0x0F;
pUsbTerminal->UsbWrite(C_CMD_REPORT, buff, 7);
}
/*==========================================================================
; 把数据分解成SetReport数据包格式发送
; 格式: ReportID, Len, (用户数据DATA1 .... DATAn), 填充数据xx ...
==========================================================================*/
void CPhoneUI::UpdateLcd(UCHAR *buff)
{
if(!pUsbTerminal)
return;
SetLcdPos(0,0);
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
SetLcdPos(0,1);
buff+=C_LCD_WIDTH;
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
SetLcdPos(0,2);
buff+=C_LCD_WIDTH;
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
SetLcdPos(0,3);
buff+=C_LCD_WIDTH;
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
SetLcdPos(0,4);
buff+=C_LCD_WIDTH;
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
SetLcdPos(0,5);
buff+=C_LCD_WIDTH;
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
SetLcdPos(0,6);
buff+=C_LCD_WIDTH;
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
SetLcdPos(0,7);
buff+=C_LCD_WIDTH;
pUsbTerminal->UsbWrite(C_DATA_REPORT, buff, C_LCD_WIDTH);
}
/*==========================================================================
; 把DC中的Bitmap数据转换成LCD的显示点阵数据
==========================================================================*/
void CPhoneUI::Show(void)
{
DWORD StartTime=GetCurrentTime();
UCHAR *LcdBuff=m_LcdBuff;
UCHAR *buff=m_Bitmapbuff;
BITMAP bmp;
DWORD size, bytes;
size=m_Width*((m_Height+7)/8);
memset(LcdBuff, 0, size);
m_Bitmap.GetBitmap(&bmp);
size=bmp.bmHeight*bmp.bmWidthBytes;
bytes=m_Bitmap.GetBitmapBits(size, buff);
long dotbytes=bmp.bmWidthBytes/m_Width;
UCHAR mask;
UCHAR maskbits[]={0x01,0x02,0x04,0x08,0x10,0x20,0x40,0x80};
UCHAR *pst;
UCHAR *pLcdBuff, *pLcd;
pst=(UCHAR *)buff;
pLcdBuff=LcdBuff;
for(int i=0; i<m_Height; i++)
{
mask=maskbits[i&0x07];
pLcd=pLcdBuff;
for(int j=0; j<m_Width; j++)
{
if(!*pst)
*pLcd |= mask;
pst+=dotbytes;
pLcd++;
}
if((i&0x07)==0x07)
pLcdBuff +=m_Width;
}
UpdateLcd(LcdBuff);
if(pTestPhone)
pTestPhone->Display(&m_Dc, m_Width, m_Height);
}
void CPhoneUI::Cls(void)
{
CPen *oldPen;
CBrush *oldBrush;
oldBrush=(CBrush *)m_Dc.SelectStockObject(WHITE_BRUSH);
oldPen=(CPen *)m_Dc.SelectStockObject(WHITE_PEN);
m_Dc.Rectangle(0,0,m_Width,m_Height);
m_Dc.SelectObject(oldPen);
m_Dc.SelectObject(oldBrush);
}
//多行显示
void CPhoneUI::DisplayText(CDC *pdc, CString str, RECT &rect, UINT format)
{
long right, bottom;
right=rect.right;
bottom=rect.bottom;
pdc->DrawText(str, &rect, format|DT_WORDBREAK| DT_CALCRECT);
if(rect.right <= right)
{
rect.right = right;
rect.bottom=bottom;
pdc->DrawText(str, &rect, format|DT_WORDBREAK);
return;
}
format=DT_LEFT;
while(1)
{
for(int i=1; i<=str.GetLength(); i++)
{
CSize size;
size=pdc->GetTextExtent(str, i);
if(size.cx > right)
break;
}
i--;
CString str1;
str1=str.Left(i);
str=str.Right(str.GetLength()-i);
rect.right = right;
rect.bottom= bottom;
pdc->DrawText(str1, &rect, format|DT_CALCRECT);
if(rect.bottom>bottom)
rect.bottom=bottom;
rect.right = right;
pdc->DrawText(str1, &rect, format);
rect.top=rect.bottom;
if((rect.top>=bottom) || (str==""))
break;
}
}
void CPhoneUI::DisplayString(UINT id, RECT &rect, UINT format)
{
TCHAR buff[64];
memset(buff, 0, sizeof(buff));
AfxLoadString(id, buff);
DisplayString(buff, rect, format);
}
void CPhoneUI::DisplayString(CString str, RECT &rect, UINT format)
{
long right, bottom;
right=rect.right;
bottom=rect.bottom;
m_Dc.DrawText(str, &rect, format|DT_CALCRECT);
if((format & DT_VCENTER) &&(bottom >rect.bottom))
{
bottom=(bottom-rect.bottom)/2;
rect.top+=bottom;
rect.bottom+=bottom;
}
if(format & DT_CENTER)
{
right=(right-rect.right)/2;
rect.left+=right;
rect.right+=right;
}
else
rect.right=right;
m_Dc.DrawText(str, &rect, format);
}
int CPhoneUI::DisInformation(UINT id, DWORD timeout_ms)
{
RECT Rect1;
CFont font;
CFont *OldFont;
font.CreatePointFont(148, "Times New Roman");
OldFont=m_Dc.SelectObject(&font);
Cls();
Rect1.left=0;
Rect1.top=0;
Rect1.right=m_Width;
Rect1.bottom=m_Height;
DisplayString(id, Rect1, DT_VCENTER|DT_CENTER|DT_WORDBREAK);
Show();
m_Dc.SelectObject(OldFont);
WaitEvents(timeout_ms);
return(0);
}
void CPhoneUI::ScrollBar(long index, long max)
{
CPen *oldPen;
long x,y0,y1,y;
if((max<=1) || (index==0))
return;
if(index > max)
index =max ;
x=m_Width-3;
y0=3;
y1=m_Height-3;
y=y1-y0-(4+4+4);
y*=index-1;
y/=max-1;
y+=y0+4;
oldPen=(CPen *)m_Dc.SelectStockObject(BLACK_PEN);
m_Dc.MoveTo(x,y0);
m_Dc.LineTo(x,y1);
m_Dc.MoveTo(x,y0);
m_Dc.LineTo(x+3,y0+3);
m_Dc.MoveTo(x,y0);
m_Dc.LineTo(x-3,y0+3);
m_Dc.MoveTo(x,y1);
m_Dc.LineTo(x+3,y1-3);
m_Dc.MoveTo(x,y1);
m_Dc.LineTo(x-3,y1-3);
m_Dc.MoveTo(x-1,y);
m_Dc.LineTo(x-1,y+4);
m_Dc.MoveTo(x-2,y);
m_Dc.LineTo(x-2,y+4);
m_Dc.MoveTo(x+1,y);
m_Dc.LineTo(x+1,y+4);
m_Dc.MoveTo(x+2,y);
m_Dc.LineTo(x+2,y+4);
m_Dc.SelectObject(oldPen);
}
/*==========================================================================
; 终端初始化
;
; 命令:电压控制, 页地址, 正常显示, 行扫描方向, LCD BIAS, 起始行, 列扫描方向, 大灰度等级, 显示, 灰度(2B)
==========================================================================*/
void CPhoneUI::InitalHardware()
{
UCHAR buff1[]={ //LCD 复位
C_CMD_AND, 0x17, 0xF3, //PCC 2 3输出
C_CMD_AND, 0x16, 0xFB, //LCD 复位线PC2=0
C_CMD_OR, 0x16, 0x04, //LCD 复位线PC2=1
};
pUsbTerminal->UsbWrite(C_CMD_REPORT, buff1, sizeof(buff1));
UCHAR buff2[]={ //LCD初始化
C_CMD_LCD_COMMAND, 11,
0x2F,0xB2,0xA6,0xC0,0xA2,0x40,0xA1,0x24,0xAF, //命令
0x81, 0xE8 //灰度
};
pUsbTerminal->UsbWrite(C_CMD_REPORT, buff2, sizeof(buff2));
b_InCall=FALSE;
UCHAR buff[6];
buff[0]=C_CMD_AND; //打开左声道 34H.0
buff[1]=0x34;
buff[2]=0xFE;
buff[3]=C_CMD_OR; //关闭右声道 34H.1
buff[4]=0x34;
buff[5]=0x02;
/*
buff[0]=C_CMD_OR;
buff[1]=0x34;
buff[2]=0x01;
buff[3]=C_CMD_AND;
buff[4]=0x34;
buff[5]=0xFD;
*/
pUsbTerminal->UsbWrite(C_CMD_REPORT, buff,sizeof(buff));
}
#define C_LcdLightDelay 15
void CPhoneUI::MainFunc(void)
{
pSkypePhone->OpenSkype();
int LcdLightDelay;
CTime time;
CString str1="test";
CString strTime;
CString strDate;
bool bShow=1;
RECT rect;
CFont font1,font2;
CFont *OldFont;
font1.CreatePointFont(140, "宋体");
font2.CreatePointFont(200, "黑体");
InitalHardware();
LcdLight(TRUE);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -