www.pudn.com > DmyNP_source.rar > Phone.c, change:2004-12-17,size:90056b


/*--> 
Damayi Net-Phone, 2004/11 (damayi.org) 
<--*/ 
 
#include "src\winmain.h" 
 
#define TB_ENDTAK  (8) 
#define TB_GETPOS  (WM_USER+0) 
#define TB_SETPOS  (WM_USER+5) 
#define TB_SETRAN  (WM_USER+6) 
#define SB_SETPAS  (WM_USER+4) 
#define SB_SETTXT  (WM_USER+1) 
#define WM_KPHONE  (WM_USER+210) 
#define WM_TSICON  (WM_USER+213) 
#define WM_LEAPED  (WM_USER+215) 
#define HANG_NULL  0x00 
#define HANG_AUTO  0x11 
 
#define KW_IDLE  0x00 
#define KW_CALL  0x01 
#define KW_ASK   0x02 
#define KW_TALK  0x03 
 
#define TL_EDIT  1001 
#define TL_USER  1002 
#define TL_CALL  IDOK 
#define TL_ANSW  1004 
#define TL_REFU  1005 
#define TL_HAND  1006 
#define TL_POFF  1007 
#define TL_ROFF  1008 
#define TL_OPTI  1009 
#define TL_QUIE  1010 
#define TL_REST  1011 
 
#define PNWIN_STYLE  WS_CAPTION|WS_POPUP|WS_SYSMENU|WS_BORDER|WS_MINIMIZEBOX 
#define FCWIN_STYEX  WS_EX_STATICEDGE 
#define FCWIN_STYLE  WS_VISIBLE|WS_CHILD 
#define TEDIT_STYLE  WS_VISIBLE|WS_CHILD|WS_BORDER|WS_TABSTOP 
#define UEDIT_STYLE  ES_LOWERCASE|ES_OEMCONVERT|ES_AUTOHSCROLL 
#define BUTON_STYLE  WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_FLAT 
#define GRBOX_STYLE  WS_VISIBLE|WS_CHILD|BS_GROUPBOX 
#define CHECK_STYLE  WS_VISIBLE|WS_CHILD|WS_TABSTOP|BS_FLAT|BS_AUTOCHECKBOX 
#define TIMER_COUNT  111 
#define TTRGB_BLACK  RGB(104,113,101) 
#define TTRGB_WHITE  RGB(195,208,193) 
#define PSound(n,b)  PlayWave(g_IV.bRing?(n):0,(b),TRUE) 
#define PSoundNs(n)  PlayWave((n),FALSE,FALSE) 
#define StopSound()  PlayWave(NULL,FALSE,TRUE) 
#define _MKINT(a,b)  ((DWORD)(((WORD)(a))|(((DWORD)((WORD)(b)))<<16))) 
 
#define STIME  SYSTEMTIME 
#define LINFO  kpLOGONINFO 
 
typedef struct 
{ 
   ATOM  atomMain;     //主窗口类标识符 
   ATOM  atomFace;     //子窗口类标识符 
   HWND  hWndMain;     //主窗口句柄 
   HWND  hWndAbout;    //关于对话框句柄 
   HWND  hWndWarn;     //警告对话框句柄 
   HWND  hWndLog;      //记录对话框句柄 
   HWND  hWndSnd;      //音频项窗口句柄 
   HWND  hWndLogon;    //登录提示框句柄 
   HWND  hWndSetup;    //设置对话框句柄 
   HWND  hWndMyInfo;   //我的信息框句柄 
   HWND  hWndOnLine;   //在线列表框句柄 
   char  sTmp[512];    //临时文本缓冲区 
   DWORD dwArevTick;   //修复速率计时器 
   LINFO stKLInfo;     //K-Phone登录信息 
   kpOPT stKOpt;       //K-Phone音频控制 
   int   iPhoneWork;   //K-Phone任务状态 
   int   iOnLine;      //K-Phone联机状态 
   int   iSndEquil;    //声音平衡(-1:左,0:双声道,+1:右) 
   int   iAutoMark;    //自动处理(0:正常,1:拒绝,2:接听) 
   int   iTaskIcon;    //任务栏图标是否已添加(0:未添加) 
   int   iReturnVar;   //过程返回值(0:重新登录,-1:退出) 
   char* pErrText;     //错误提示指针(0:无错误提示信息) 
}MAINVAR; 
 
typedef struct 
{ 
   HWND  hWndFace;     //电话面板窗口句柄 
   BOOL  bPasi;        //当前通讯主叫标志 
   BYTE  byMult;       //当前通讯MULT标志 
   DWORD dwTick;       //当前任务开始时间(TICK或计数) 
   STIME stTime;       //当前任务开始时间(SYSTEMTIME) 
   DWORD dwIP;         //当前通讯方IP地址(network order) 
   WORD  wPort;        //当前通讯方端口号(network order) 
   BOOL  bOutWOpen;    //输出设备是否打开 
   BOOL  bInWOpen;     //输入设备是否打开 
   BYTE  byPFren;      //输出FREN数值记录 
   BYTE  byRFren;      //输入FREN数值记录 
   BOOL  bSend;        //数据发送状态记录 
   DWORD dwIdleSt;     //空闲画面显示状态 
   char* pcIdleT1;     //空闲提示标题指针 
   char* pcIdleT2;     //空闲提示内容指针 
   char* pcIdleT3;     //空闲提示内容指针 
   DWORD dwIdleCoun;   //空闲提示计数变量 
   HBITMAP hIdleBmpST; //空闲提示位图句柄 
}FCWVAR; 
 
typedef struct 
{ 
   HWND  hWndUDSet;    //设置用户资料窗口句柄 
   HWND  hWndUDRed;    //查看用户资料窗口句柄 
   BOOL  bStart;       //获取任务是否正在工作 
   HWND  hWndBeMain;   //主窗口相关控件句柄 
   DWORD dwGetPID;     //获取用户帐号传值变量 
}UDCVAR; 
 
typedef struct 
{ 
   HBITMAP bmpIdle;    //空闲状态位图句柄 
   HBITMAP bmpAsk;     //询问状态位图句柄 
   HBITMAP bmpAskX;    //询问失败位图句柄 
   HBITMAP bmpCall;    //呼叫状态位图句柄 
   HBITMAP bmpCallX;   //呼叫失败位图句柄 
   HBITMAP bmpError;   //错误提示位图句柄 
   HBITMAP bmpHang;    //挂断提示位图句柄 
   HBITMAP bmpTalk;    //通话状态位图句柄 
   HBITMAP bmpTks;     //发送指示位图句柄 
   HBITMAP bmpTkv;     //音量指示位图句柄 
}RCSVAR; 
 
static MAINVAR gstMV;  //过程全局结构变量 
static FCWVAR  gstFV;  //面板窗口结构变量 
static UDCVAR  gstUD;  //用户资料模块变量 
static RCSVAR  gstRV;  //资源句柄结构变量 
 
static char const * const gcpMainClass = "Phone@Main"; 
static char const * const gcpFaceClass = "Phone@Face"; 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: CommLog模块(log) 
说明: 历史记录对话框处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//打开历史记录对话框 
static void logOpenLog(void) 
{ 
   if(gstMV.hWndLog==NULL) return; 
   if(IsWindowVisible(gstMV.hWndLog)) 
      FlashWindow(gstMV.hWndLog, TRUE); 
   else 
      ShowWindow(gstMV.hWndLog, SW_SHOW); 
   SetFocus(gstMV.hWndLog); 
   return; 
} 
 
//添加通讯记录 
//参数: ps  记录内容 
//      bl  是否添加空行(TRUE:是) 
static void logOutCommlog(char const * const ps, BOOL bl) 
{ 
   HWND hWnd; 
   int iVar; 
   if(gstMV.hWndLog==NULL) return; 
   hWnd = GetDlgItem(gstMV.hWndLog, CMLOG_LTMM); 
   if(hWnd==NULL) return; 
   SendMessage(hWnd, LB_ADDSTRING, 0, (LPARAM)(ps)); 
   if(bl) SendMessage(hWnd, LB_ADDSTRING, 0, (LPARAM)""); 
   iVar = SendMessage(hWnd, LB_GETCOUNT, 0,0); 
   SendMessage(hWnd, LB_SETCURSEL, iVar-1, 0); 
   return; 
} 
 
//添加事件记录 
//参数: ps  记录内容 
//      bl  是否添加空行(TRUE:是) 
static void logOutEventlog(char const * const ps, BOOL bl) 
{ 
   HWND hWnd; 
   int iVar; 
   if(gstMV.hWndLog==NULL) return; 
   hWnd = GetDlgItem(gstMV.hWndLog, CMLOG_LTDD); 
   if(hWnd==NULL) return; 
   SendMessage(hWnd, LB_ADDSTRING, 0, (LPARAM)(ps)); 
   if(bl) SendMessage(hWnd, LB_ADDSTRING, 0, (LPARAM)""); 
   iVar = SendMessage(hWnd, LB_GETCOUNT, 0,0); 
   SendMessage(hWnd, LB_SETCURSEL, iVar-1, 0); 
   return; 
} 
 
//历史记录对话框回调函数 
static BOOL CALLBACK logCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_INITDIALOG: 
         ShowWindow(GetDlgItem(h,CMLOG_LTMM), SW_SHOW); 
         ShowWindow(GetDlgItem(h,CMLOG_LTDD), SW_HIDE); 
         SendDlgItemMessage(h, CMLOG_CKMM, BM_SETCHECK, 1, 0); 
         PostMessage(h, WM_LEAPED, w,l); 
         return FALSE; 
      case WM_LEAPED: 
         logOutCommlog("通讯记录", FALSE); 
         logOutCommlog("~~~~~~~~", TRUE); 
         break; 
      case WM_CLOSE: 
         ShowWindow(h, SW_HIDE); 
         break; 
      case WM_DESTROY: 
         gstMV.hWndLog = NULL; 
         break; 
      case WM_COMMAND: 
         switch(LOWORD(w)) 
         { 
         case CMLOG_CKMM: 
            ShowWindow(GetDlgItem(h,CMLOG_LTMM), SW_SHOW); 
            ShowWindow(GetDlgItem(h,CMLOG_LTDD), SW_HIDE); 
            break; 
         case CMLOG_CKDD: 
            ShowWindow(GetDlgItem(h,CMLOG_LTMM), SW_HIDE); 
            ShowWindow(GetDlgItem(h,CMLOG_LTDD), SW_SHOW); 
            break; 
         case CMLOG_DELE: 
            if(IsWindowVisible(GetDlgItem(h,CMLOG_LTMM))) 
               SendDlgItemMessage(h,CMLOG_LTMM, LB_RESETCONTENT,0,0); 
            if(IsWindowVisible(GetDlgItem(h,CMLOG_LTDD))) 
               SendDlgItemMessage(h,CMLOG_LTDD, LB_RESETCONTENT,0,0); 
            break; 
         case IDOK: 
         case IDCANCEL: 
            ShowWindow(h, SW_HIDE); 
            break; 
         } 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: WarnDlg模块(war) 
说明: 警告对话框处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//警告对话框回调函数 
#pragma option -w- 
static BOOL CALLBACK _warCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_CLOSE: 
         DestroyWindow(h); 
         break; 
      case WM_DESTROY: 
         gstMV.hWndWarn = NULL; 
         break; 
      case WM_COMMAND: 
         if(LOWORD(w)==IDCANCEL) DestroyWindow(h); 
         if(LOWORD(w)==IDOK) DestroyWindow(h); 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
#pragma option -w 
 
//弹出警告对话框 
//参数: 警告文本 
static void warOpen(char const * const pcs) 
{ 
   if(gstMV.hWndWarn!=NULL) 
      FlashWindow(gstMV.hWndWarn, TRUE); 
   else 
   { 
      if(gstMV.hWndMain==NULL) return; 
      gstMV.hWndWarn = CreateDialog(g_hInst, 
         "PromptText", gstMV.hWndMain, _warCallback); 
      if(gstMV.hWndWarn==NULL) return; 
   } 
   SetWindowText(GetDlgItem(gstMV.hWndWarn,999), pcs); 
   SetFocus(GetDlgItem(gstMV.hWndWarn, IDOK)); 
   PSoundNs(g_GJ.pSWarn); 
   return; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: Other模块(otr) 
说明: 其他类别函数和处理过程模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//号码地址字符串处理函数 
//参数: dwID  帐号或地址(network order) 
//      wPort 零或端口号(network order) 
//返回: 字符串中的字符个数。 
//说明: 该函数将结果写入gstMV.sTmp缓冲区中。如果参数wPort值为零, 
//      则dwID为用户帐号, 否则, dwID值为IP地址, wPort值为端口号。 
static int otrPrintPID(DWORD dwID, WORD wPort) 
{ 
   struct in_addr addr; 
   char *pcs; 
   char sPID[8]={0}; 
   if(wPort==0) 
   { 
      ItoC(dwID, sPID); 
      return wsprintf(gstMV.sTmp, "号码:%s", sPID); 
   } 
   else 
   { 
      addr.s_addr = dwID; 
      pcs = inet_ntoa(addr); 
      if(pcs==NULL) pcs="0.0.0.0"; 
      return wsprintf(gstMV.sTmp, "地址:%s[%d]", pcs, ntohs(wPort)); 
   } 
} 
 
//禁用电话功能按钮 
static void otrDPhoneBut(void) 
{ 
   EnableWindow(GetDlgItem(gstMV.hWndMain,TL_CALL), FALSE); 
   EnableWindow(GetDlgItem(gstMV.hWndMain,TL_ANSW), FALSE); 
   EnableWindow(GetDlgItem(gstMV.hWndMain,TL_REFU), FALSE); 
   EnableWindow(GetDlgItem(gstMV.hWndMain,TL_HAND), FALSE); 
   EnableWindow(GetDlgItem(gstMV.hWndMain,TL_USER), FALSE); 
   EnableWindow(GetDlgItem(gstMV.hWndMain,TL_REST), FALSE); 
   if(GetForegroundWindow()!=gstMV.hWndMain) return; 
   SetFocus(GetDlgItem(gstMV.hWndMain, TL_EDIT)); 
   return; 
} 
 
//修改程序菜单 
static void otrModiMenu(void) 
{ 
   HMENU hMenu; 
   UINT  uEnable = (gstMV.iOnLine?MF_ENABLED:MF_GRAYED); 
   if(gstMV.hWndMain==NULL) return; 
   hMenu = GetMenu(gstMV.hWndMain); 
   if(hMenu==NULL) return; 
   CheckMenuItem(hMenu, M_HIDE, g_IV.bLieup?MF_CHECKED:MF_UNCHECKED); 
   CheckMenuItem(hMenu, M_TURNDOWN, MF_UNCHECKED); 
   CheckMenuItem(hMenu, M_AUTOMATA, MF_UNCHECKED); 
   EnableMenuItem(hMenu, M_USERDATA, uEnable); 
   EnableMenuItem(hMenu, M_ONLIST, uEnable); 
   EnableMenuItem(hMenu, M_HIDE, uEnable); 
   EnableMenuItem(hMenu, M_SAVE, g_SO.bAvaiINI?MF_GRAYED:MF_ENABLED); 
   if(gstMV.iAutoMark==1) CheckMenuItem(hMenu,M_TURNDOWN,MF_CHECKED); 
   if(gstMV.iAutoMark==2) CheckMenuItem(hMenu,M_AUTOMATA,MF_CHECKED); 
   return; 
} 
 
//设置K-Phone通讯参数 
//参数: kpOPT结构指针 
//返回: 成功返回0, 失败返回错误码。 
static int otrKpSetup(kpOPT const *pst) 
{ 
   int iErr; 
   iErr = kpSetup(pst); 
   if(iErr==0) return 0; 
   wsprintf(g_pTmp, "kpSetup()函数调用失败, 错误码:%d。", iErr); 
   logOutEventlog(g_pTmp, TRUE); 
   return iErr; 
} 
 
//登录提示框回调函数 
#pragma option -w- 
static BOOL CALLBACK otrLogonCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   RECT rect; 
   switch(u) 
   { 
      case WM_INITDIALOG: 
         SetWindowText(h, "DmyNP - 正在登录,请稍后..."); 
         GetClientRect(h, &rect); 
         CreateCaret(h, (HBITMAP)1, rect.right, rect.bottom); 
         SetCaretPos(0, 0); 
         ShowCaret(h); 
         break; 
      case WM_CLOSE: 
         gstMV.iReturnVar = 0; 
         DestroyWindow(GetParent(h)); 
         break; 
      case WM_DESTROY: 
         DestroyCaret(); 
         gstMV.hWndLogon = NULL; 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
#pragma option -w 
 
//关于对话框回调函数 
#pragma option -w- 
static BOOL CALLBACK otrAboutCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_CLOSE: 
         DestroyWindow(h); 
         break; 
      case WM_COMMAND: 
         if(LOWORD(w)==IDCANCEL) DestroyWindow(h); 
         break; 
      case WM_DESTROY: 
         gstMV.hWndAbout = NULL; 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
#pragma option -w 
 
//我的信息对话框回调函数 
#pragma option -w- 
static BOOL CALLBACK otrMyInfoCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_CLOSE: 
         DestroyWindow(h); 
         break; 
      case WM_DESTROY: 
         gstMV.hWndMyInfo = NULL; 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
#pragma option -w 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: Setup模块(set) 
说明: 参数设置对话框处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//初始化参数设置对话框 
//参数: 对话框窗口句柄 
static void _setInitializeDlg(HWND h) 
{ 
   DWORD dwI; 
   UINT uNum; 
   WAVEOUTCAPS woc; 
   WAVEINCAPS  wic; 
 
   //获取音频输出设备信息 
   uNum = waveOutGetNumDevs(); 
   if(uNum==0) 
      SendDlgItemMessage(h,SETUP_WOUT, CB_ADDSTRING,0,(LPARAM)"无音频设备"); 
   else 
   { 
      for(dwI=0; dwI<uNum; dwI++) 
      { 
      waveOutGetDevCaps(dwI, &woc, sizeof(woc)); 
      SendDlgItemMessage(h,SETUP_WOUT, CB_ADDSTRING,0,(LPARAM)woc.szPname); 
      } 
   } 
   SendDlgItemMessage(h,SETUP_WOUT, CB_SETCURSEL, 0,0); 
   SendDlgItemMessage(h,SETUP_WOUT, CB_SETCURSEL, g_IV.uWavePID,0); 
 
   //获取音频输入设备信息 
   uNum = waveInGetNumDevs(); 
   if(uNum==0) 
      SendDlgItemMessage(h,SETUP_WIN, CB_ADDSTRING,0,(LPARAM)"无音频设备"); 
   else 
   { 
      for(dwI=0; dwI<uNum; dwI++) 
      { 
      waveInGetDevCaps(dwI, &wic, sizeof(wic)); 
      SendDlgItemMessage(h,SETUP_WIN, CB_ADDSTRING,0,(LPARAM)wic.szPname); 
      } 
   } 
   SendDlgItemMessage(h,SETUP_WIN, CB_SETCURSEL, 0,0); 
   SendDlgItemMessage(h,SETUP_WIN, CB_SETCURSEL, g_IV.uWaveRID,0); 
 
   SendDlgItemMessage(h,SETUP_LPRI, BM_SETCHECK, g_IV.bLowPRI,0); 
   SendDlgItemMessage(h,SETUP_LSAW, BM_SETCHECK, g_IV.bLostAW,0); 
   SendDlgItemMessage(h,SETUP_XPIC, BM_SETCHECK, g_IV.bTrayIco,0); 
   SendDlgItemMessage(h,SETUP_AREV, BM_SETCHECK, (g_IV.wAutoREV?1:0), 0); 
 
   if(g_IV.wAutoREV==0) 
   { 
      EnableWindow(GetDlgItem(h,SETUP_TEXT), FALSE); 
      EnableWindow(GetDlgItem(h,SETUP_EDIT), FALSE); 
      wsprintf(g_pTmp, "%d", AUTOREV); 
      SetWindowText(GetDlgItem(h,SETUP_EDIT), g_pTmp); 
   } 
   else 
   { 
      wsprintf(g_pTmp, "%d", g_IV.wAutoREV); 
      SetWindowText(GetDlgItem(h,SETUP_EDIT), g_pTmp); 
   } 
 
   EnableWindow(GetDlgItem(h,SETUP_SAVE), FALSE); 
   return; 
} 
 
//获取参数设置对话框控制内容 
//参数: 对话框窗口句柄 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL _setGetCtvar(HWND h) 
{ 
   int iVar; 
   g_IV.uWavePID = SendDlgItemMessage(h,SETUP_WOUT,CB_GETCURSEL,0,0); 
   g_IV.uWaveRID = SendDlgItemMessage(h,SETUP_WIN, CB_GETCURSEL,0,0); 
   g_IV.bLowPRI  = SendDlgItemMessage(h,SETUP_LPRI,BM_GETCHECK, 0,0); 
   g_IV.bLostAW  = SendDlgItemMessage(h,SETUP_LSAW,BM_GETCHECK, 0,0); 
   g_IV.bTrayIco = SendDlgItemMessage(h,SETUP_XPIC,BM_GETCHECK, 0,0); 
   iVar = SendDlgItemMessage(h,SETUP_AREV, BM_GETCHECK,0,0); 
   if(iVar==0) 
      g_IV.wAutoREV = 0; 
   else 
   { 
      GetWindowText(GetDlgItem(h,SETUP_EDIT), g_pTmp, 6); 
      g_IV.wAutoREV = (WORD)atoi(g_pTmp); 
   } 
   return TRUE; 
} 
 
//参数设置对话框回调函数 
static BOOL CALLBACK _setCallBack(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_INITDIALOG: 
         _setInitializeDlg(h); 
         return FALSE; 
      case WM_CLOSE: 
         DestroyWindow(h); 
         break; 
      case WM_DESTROY: 
         gstMV.hWndSetup = NULL; 
         break; 
      case WM_COMMAND: 
         switch(LOWORD(w)) 
         { 
         case SETUP_WOUT: 
         case SETUP_WIN: 
            if(HIWORD(w)==CBN_SELCHANGE) 
               EnableWindow(GetDlgItem(h,SETUP_SAVE), TRUE); 
            break; 
         case SETUP_LPRI: 
         case SETUP_LSAW: 
         case SETUP_XPIC: 
            EnableWindow(GetDlgItem(h,SETUP_SAVE), TRUE); 
            break; 
         case SETUP_AREV: 
            if(!SendMessage((HWND)l,BM_GETCHECK,0,0)) 
            { 
               EnableWindow(GetDlgItem(h,SETUP_TEXT), FALSE); 
               EnableWindow(GetDlgItem(h,SETUP_EDIT), FALSE); 
            } 
            else 
            { 
               EnableWindow(GetDlgItem(h,SETUP_TEXT), TRUE); 
               EnableWindow(GetDlgItem(h,SETUP_EDIT), TRUE); 
            } 
            EnableWindow(GetDlgItem(h,SETUP_SAVE), TRUE); 
            break; 
         case SETUP_EDIT: 
            if(HIWORD(w)==EN_CHANGE) 
               EnableWindow(GetDlgItem(h,SETUP_SAVE), TRUE); 
            break; 
         case SETUP_OK: 
            if(_setGetCtvar(h)) DestroyWindow(h); 
            break; 
         case SETUP_NO: 
            DestroyWindow(h); 
            break; 
         case SETUP_SAVE: 
            SetFocus(GetDlgItem(h,SETUP_HELP)); 
            if(_setGetCtvar(h)) EnableWindow((HWND)l, FALSE); 
            break; 
         case SETUP_HELP: 
            ShellExecute(0,0, HLP_SETUP, 0,0, SW_SHOW); 
            break; 
         } 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
 
//打开参数设置对话框 
//参数: 父窗口句柄 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL setOpen(HWND hWnd) 
{ 
   if(gstMV.hWndSetup!=NULL) 
      FlashWindow(gstMV.hWndSetup, TRUE); 
   else 
   { 
      gstMV.hWndSetup = CreateDialog(g_hInst, "Setup", hWnd, _setCallBack); 
      if(gstMV.hWndSetup==NULL) return FALSE; 
   } 
   SetFocus(gstMV.hWndSetup); 
   return TRUE; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: SndoptDlg模块(spd) 
说明: 音频控制面板对话框处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//获取音频控制面板对话框控制内容 
//参数: 音频控制面板对话框句柄 
static void _spdGetCtvar(HWND h) 
{ 
   int iv; 
   inOPT *pst = (g_IV.dwDefMT==0 ? &g_IV.stOptM : &g_IV.stOptT); 
   iv = SendDlgItemMessage(h,SNDPT_TRAC, TB_GETPOS, 0,0); 
   gstMV.iSndEquil = iv - 1; 
   if(iv==0){ gstMV.stKOpt.TrackOut=1; gstMV.stKOpt.TrackIn=2; } 
   if(iv==1){ gstMV.stKOpt.TrackOut=0; gstMV.stKOpt.TrackIn=0; } 
   if(iv==2){ gstMV.stKOpt.TrackOut=2; gstMV.stKOpt.TrackIn=1; } 
   iv = SendDlgItemMessage(h,SNDPT_AGC, BM_GETCHECK,0,0); 
   g_IV.optAgc = (BYTE)(iv?1:0); 
   gstMV.stKOpt.AgcOut = g_IV.optAgc; 
   iv = SendDlgItemMessage(h,SNDPT_DELY, BM_GETCHECK,0,0); 
   g_IV.optDelay = (BYTE)(iv?1:0); 
   gstMV.stKOpt.SndDelay = g_IV.optDelay; 
   iv = SendDlgItemMessage(h,SNDPT_VINV, TB_GETPOS, 0,0); 
   if(!SendDlgItemMessage(h,SNDPT_VIN,BM_GETCHECK,0,0)) iv=0; 
   pst->VIn = (BYTE)iv; 
   gstMV.stKOpt.VIn = pst->VIn; 
   iv = SendDlgItemMessage(h,SNDPT_COMP, TB_GETPOS, 0,0); 
   pst->CompMode = (BYTE)iv; 
   gstMV.stKOpt.CompMode = pst->CompMode; 
   iv = SendDlgItemMessage(h,SNDPT_NOR, BM_GETCHECK,0,0); 
   pst->NorIn = (BYTE)(iv?1:0); 
   gstMV.stKOpt.NorIn = pst->NorIn; 
   otrKpSetup(&gstMV.stKOpt); 
   return; 
} 
 
//初始化音频控制面板对话框 
//参数: 对话框窗口句柄 
static void _spdInitializeCortrol(HWND h) 
{ 
   inOPT *pst; 
 
   if(g_IV.dwDefMT==0) 
   { 
      pst = &g_IV.stOptM; 
      SendDlgItemMessage(h,SNDPT_HSET, BM_SETCHECK, 1,0); 
      SendDlgItemMessage(h,SNDPT_LSET, BM_SETCHECK, 0,0); 
   } 
   else 
   { 
      pst = &g_IV.stOptT; 
      SendDlgItemMessage(h,SNDPT_HSET, BM_SETCHECK, 0,0); 
      SendDlgItemMessage(h,SNDPT_LSET, BM_SETCHECK, 1,0); 
   } 
 
   SendDlgItemMessage(h,SNDPT_NOR, BM_SETCHECK, pst->NorIn,0); 
   SendDlgItemMessage(h,SNDPT_DELY, BM_SETCHECK, g_IV.optDelay,0); 
   SendDlgItemMessage(h,SNDPT_AGC, BM_SETCHECK, g_IV.optAgc,0); 
   SendDlgItemMessage(h,SNDPT_COMP, TB_SETRAN, TRUE, _MKINT(0,2)); 
   SendDlgItemMessage(h,SNDPT_VINV, TB_SETRAN, TRUE, _MKINT(1,7)); 
   SendDlgItemMessage(h,SNDPT_TRAC, TB_SETRAN, TRUE, _MKINT(0,2)); 
   SendDlgItemMessage(h,SNDPT_TRAC, TB_SETPOS, TRUE, gstMV.iSndEquil+1); 
   SendDlgItemMessage(h,SNDPT_COMP, TB_SETPOS, TRUE, pst->CompMode); 
   if(pst->CompMode==0) SetWindowText(GetDlgItem(h,SNDPT_TEXT),"低压缩"); 
   else if(pst->CompMode==1) SetWindowText(GetDlgItem(h,SNDPT_TEXT),"轻压缩"); 
   else SetWindowText(GetDlgItem(h,SNDPT_TEXT),"高压缩"); 
 
   if(pst->VIn==0) 
   { 
      SendDlgItemMessage(h,SNDPT_VIN, BM_SETCHECK, 0,0); 
      EnableWindow(GetDlgItem(h,SNDPT_VINV), FALSE); 
      SendDlgItemMessage(h,SNDPT_VINV, TB_SETRAN, TRUE, _MKINT(1,200)); 
      SendDlgItemMessage(h,SNDPT_VINV, TB_SETPOS, TRUE, 1); 
   } 
   else 
   { 
      SendDlgItemMessage(h,SNDPT_VIN, BM_SETCHECK, 1,0); 
      EnableWindow(GetDlgItem(h,SNDPT_VINV), TRUE); 
      if(pst->VIn>7) pst->VIn=7; 
      SendDlgItemMessage(h,SNDPT_VINV, TB_SETPOS, TRUE, pst->VIn); 
   } 
   return; 
} 
 
//音频控制面板对话框回调函数 
static BOOL CALLBACK _spdCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_INITDIALOG: 
         _spdInitializeCortrol(h); 
         return FALSE; 
      case WM_CLOSE: 
         DestroyWindow(h); 
         SendDlgItemMessage(gstMV.hWndMain, TL_OPTI, BM_SETCHECK, 0,0); 
         break; 
      case WM_DESTROY: 
         gstMV.hWndSnd = NULL; 
         break; 
      case WM_COMMAND: 
         switch(LOWORD(w)) 
         { 
         case SNDPT_HELP: 
            ShellExecute(0,0, HLP_SNDOPT, 0,0, SW_SHOW); 
            break; 
         case SNDPT_VOL: 
            ShellExecute(0,0, "sndvol32.exe", 0,0, SW_SHOW); 
            break; 
         case SNDPT_HSET: 
            g_IV.dwDefMT = 0; 
            _spdInitializeCortrol(h); 
            _spdGetCtvar(h); 
            break; 
         case SNDPT_LSET: 
            g_IV.dwDefMT = 1; 
            _spdInitializeCortrol(h); 
            _spdGetCtvar(h); 
            break; 
         case SNDPT_NOR: 
         case SNDPT_DELY: 
         case SNDPT_AGC: 
            _spdGetCtvar(h); 
            break; 
         case SNDPT_VIN: 
            if(SendMessage((HWND)l,BM_GETCHECK,0,0)) 
            { 
               if(g_IV.dwDefMT==0) 
                  SendDlgItemMessage(h,SNDPT_VINV, TB_SETPOS, TRUE,1); 
               else 
                  SendDlgItemMessage(h,SNDPT_VINV, TB_SETPOS, TRUE,3); 
            } 
            _spdGetCtvar(h); 
            _spdInitializeCortrol(h); 
            break; 
         } 
         break; 
      case WM_HSCROLL: 
         if(LOWORD(w)!=TB_ENDTAK) break; 
         _spdGetCtvar(h); 
         if((HWND)l==GetDlgItem(h,SNDPT_COMP)) _spdInitializeCortrol(h); 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
 
//打开音频控制面板 
//参数: 父窗口句柄 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL spdOpenSndoptDlg(HWND hWnd) 
{ 
   if(gstMV.hWndSnd!=NULL) 
      FlashWindow(gstMV.hWndSnd, TRUE); 
   else 
   { 
      gstMV.hWndSnd = CreateDialog(g_hInst, "SndOpt", hWnd, _spdCallback); 
      if(gstMV.hWndSnd==NULL) return FALSE; 
   } 
   return TRUE; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: UserData模块(ud) 
说明: 用户资料对话框处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//修正用户资料数据块内容 
//参数: 用户资料结构地址 
static void udUserdataDisp(USERDATA *pst) 
{ 
   pst->in.name[sizeof(pst->in.name)-1] = 0; 
   pst->in.prov[sizeof(pst->in.prov)-1] = 0; 
   pst->in.city[sizeof(pst->in.city)-1] = 0; 
   pst->in.tel[sizeof(pst->in.tel)-1] = 0; 
   pst->in.web[sizeof(pst->in.web)-1] = 0; 
   pst->in.email[sizeof(pst->in.email)-1] = 0; 
   pst->note[sizeof(pst->note)-1] = 0; 
   return; 
} 
 
//初始化用户资料对话框控制内容 
//参数: h   用户资料对话框句柄 
//      pst 用户资料结构地址 
static void _udInitCortrol(HWND h, USERDATA const * const pst) 
{ 
   SetWindowText(GetDlgItem(h,U_NAME), pst->in.name); 
   SetWindowText(GetDlgItem(h,U_GENDER),""); 
   if(pst->in.sex>0) SetWindowText(GetDlgItem(h,U_GENDER),"男"); 
   if(pst->in.sex<0) SetWindowText(GetDlgItem(h,U_GENDER),"女"); 
   SetWindowText(GetDlgItem(h,U_YEAR),""); 
   if(pst->in.age>0) 
   { 
      wsprintf(g_pTmp, "%d", pst->in.age); 
      SetWindowText(GetDlgItem(h,U_YEAR),g_pTmp); 
   } 
   SetWindowText(GetDlgItem(h,U_PROVINCE), pst->in.prov); 
   SetWindowText(GetDlgItem(h,U_CITY), pst->in.city); 
   SetWindowText(GetDlgItem(h,U_TEL), pst->in.tel); 
   SetWindowText(GetDlgItem(h,U_WEB), pst->in.web); 
   SetWindowText(GetDlgItem(h,U_EMAIL), pst->in.email); 
   SetWindowText(GetDlgItem(h,U_EDIT), pst->note); 
   SetWindowText(GetDlgItem(h,U_NONE), pst->note); 
   return; 
} 
 
//修正GUi任务相关按钮状态 
//参数: TRUE=激活, FALSE=禁用 
static void _udEnbeWin(BOOL bl) 
{ 
   if(gstUD.hWndBeMain!=NULL) 
      EnableWindow(gstUD.hWndBeMain, bl); 
   if(gstUD.hWndUDRed==NULL) return; 
   EnableWindow(GetDlgItem(gstUD.hWndUDRed,U_OK), bl); 
   EnableWindow(GetDlgItem(gstUD.hWndUDRed,U_BUTTON), bl); 
   return; 
} 
 
//启动GUi任务 
//参数: h 窗口句柄 
//      d 用户帐号 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL _udStartGUi(HWND h, DWORD d) 
{ 
   DWORD dwi; 
   char sPID[8]={0}; 
   if(d==0) return FALSE; 
   if(gstUD.bStart) return FALSE; 
   if(kpGetUserinfo(d)!=0) return FALSE; 
   for(dwi=UID_START; dwi<=UID_END; dwi++) 
      EnableWindow(GetDlgItem(h,dwi), FALSE); 
   EnableWindow(GetDlgItem(h,U_PID), FALSE); 
   EnableWindow(GetDlgItem(h,U_NONE), FALSE); 
   ItoC(d, sPID); 
   wsprintf(g_pTmp, "\r\n  正在获取 %s 的用户资料, 请稍后...", sPID); 
   ShowWindow(GetDlgItem(h,U_TEXT), SW_HIDE); 
   SetWindowText(GetDlgItem(h,U_TEXT), g_pTmp); 
   ShowWindow(GetDlgItem(h,U_TEXT), SW_SHOW); 
   gstUD.bStart = TRUE; 
   gstUD.dwGetPID = d; 
   _udEnbeWin(FALSE); 
   return TRUE; 
} 
 
//查看用户资料对话框回调函数 
#pragma option -w- 
static BOOL CALLBACK _udRedCallBack(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_INITDIALOG: 
         SetWindowText(GetDlgItem(h,U_BUTTON), "更新"); 
         return FALSE; 
      case WM_CLOSE: 
         DestroyWindow(h); 
         break; 
      case WM_DESTROY: 
         _udEnbeWin(TRUE); 
         kpGetUserinfo(0); 
         gstUD.hWndUDRed = NULL; 
         gstUD.bStart = FALSE; 
         break; 
      case WM_COMMAND: 
         switch(LOWORD(w)) 
         { 
         case U_BUTTON: 
            SetFocus(GetDlgItem(h,U_CLOSE)); 
            _udStartGUi(h, gstUD.dwGetPID); 
            break; 
         case U_OK: 
         case U_CLOSE: 
            DestroyWindow(h); 
            break; 
         } 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
#pragma option -w 
 
//显示用户资料 
//参数: kpGUINFO结构地址 
static void udOutUserData(kpGUINFO const * const pst) 
{ 
   DWORD dwi; 
   char sPID[8]={0}; 
   if(gstUD.hWndUDRed==NULL) return; 
   gstUD.bStart = FALSE; 
   _udEnbeWin(TRUE); 
   if(pst==NULL) 
   { 
      PSoundNs(g_GJ.pSWarn); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_TEXT), 
         "\r\n获取用户资料失败,内部错误。(无效的数据)"); 
      return; 
   } 
   ShowWindow(GetDlgItem(gstUD.hWndUDRed,U_TEXT), SW_HIDE); 
   SetWindowText(gstUD.hWndUDRed, "用户资料 - 查看"); 
   if(pst->byUState==0 || pst->byMult!=0) 
   { 
      wsprintf(g_pTmp, "用户资料 - 查看 -%s%s", 
         pst->byMult?" (Mult)":"", pst->byUState?"":" (隐身)"); 
      SetWindowText(gstUD.hWndUDRed, g_pTmp); 
   } 
   udUserdataDisp((void*)pst->data); 
   _udInitCortrol(gstUD.hWndUDRed, (void*)pst->data); 
   ItoC(pst->dwPID, sPID); 
   SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_PID), sPID); 
   for(dwi=UID_START; dwi<=UID_END; dwi++) 
      EnableWindow(GetDlgItem(gstUD.hWndUDRed,dwi), TRUE); 
   EnableWindow(GetDlgItem(gstUD.hWndUDRed,U_PID), TRUE); 
   EnableWindow(GetDlgItem(gstUD.hWndUDRed,U_NONE), TRUE); 
   return; 
} 
 
//GUi任务失败处理过程 
//参数: 失败原因代码 
static void udGUiFail(WORD wErr) 
{ 
   char *ps = "未知的错误。"; 
   if(gstUD.hWndUDRed==NULL) return; 
   gstUD.bStart = FALSE; 
   PSoundNs(g_GJ.pSWarn); 
   _udEnbeWin(TRUE); 
   EnableWindow(GetDlgItem(gstUD.hWndUDRed,U_OK), FALSE); 
   if(wErr==1)  ps = "服务器响应超时。"; 
   if(wErr==2)  ps = "客户端响应超时。"; 
   if(wErr==53) ps = "未找到该用户。"; 
   wsprintf(g_pTmp, "\r\n错误!获取用户资料失败:%s", ps); 
   SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_TEXT), g_pTmp); 
   return; 
} 
 
//获取用户资料 
//参数: 用户号码 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL udGetUserData(DWORD dwPID) 
{ 
   if(dwPID==0) return FALSE; 
   if(gstUD.bStart) return FALSE; 
   if(gstUD.hWndUDRed!=NULL) 
   { 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_PID), ""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_NAME), ""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_GENDER),""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_YEAR),""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_PROVINCE), ""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_CITY), ""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_TEL), ""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_WEB), ""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_EMAIL), ""); 
      SetWindowText(GetDlgItem(gstUD.hWndUDRed,U_NONE), ""); 
   } 
   else 
   { 
      if(gstMV.hWndMain==NULL) return FALSE; 
      gstUD.hWndUDRed = CreateDialog(g_hInst, 
         "UserData", gstMV.hWndMain, _udRedCallBack); 
      if(gstUD.hWndUDRed==NULL) return FALSE; 
   } 
   if(!_udStartGUi(gstUD.hWndUDRed,dwPID)) 
   { 
      DestroyWindow(gstUD.hWndUDRed); 
      return FALSE; 
   } 
   SetFocus(GetDlgItem(gstUD.hWndUDRed,U_CLOSE)); 
   return TRUE; 
} 
 
//初始化设置用户资料对话框 
//参数: 用户资料对话框句柄 
static void _udSetuserdataInit(HWND h) 
{ 
   DWORD dwi; 
   LONG lStyle; 
 
   SetWindowText(h, "设置用户资料"); 
   SendDlgItemMessage(h,U_PID, EM_SETREADONLY, FALSE, 0); 
   lStyle = GetWindowLong(GetDlgItem(h,U_PID), GWL_STYLE); 
   lStyle = lStyle|WS_DISABLED; 
   SetWindowLong(GetDlgItem(h,U_PID), GWL_STYLE, lStyle); 
   ShowWindow(GetDlgItem(h,U_NONE), SW_HIDE); 
   ShowWindow(GetDlgItem(h,U_EDIT), SW_SHOW); 
 
   for(dwi=UID_START; dwi<=UID_END; dwi++) 
      SendDlgItemMessage(h,dwi, EM_SETREADONLY, FALSE, 0); 
 
   #define _SetLen(id,le) SendDlgItemMessage(h,id,EM_SETLIMITTEXT,le,0); 
   #define _l(n) (sizeof(((inUSERDATA*)0)->n)-1) 
   _SetLen(U_NAME, _l(name)); 
   _SetLen(U_GENDER, 2); 
   _SetLen(U_YEAR, 2); 
   _SetLen(U_PROVINCE, _l(prov)); 
   _SetLen(U_CITY, _l(city)); 
   _SetLen(U_TEL, _l(tel)); 
   _SetLen(U_WEB, _l(web)); 
   _SetLen(U_EMAIL, _l(email)); 
   _SetLen(U_EDIT, sizeof(((USERDATA*)0)->note) - 1); 
   #undef _l 
   #undef _SetLen 
 
   g_pTmp[7] = 0; 
   ItoC(g_IV.dwPID, g_pTmp); 
   SetWindowText(GetDlgItem(h,U_PID), g_pTmp); 
   _udInitCortrol(h, &g_IV.stUD); 
   EnableWindow(GetDlgItem(h,U_BUTTON), FALSE); 
   return; 
} 
 
//获取用户资料对话框控制内容 
//参数: h   用户资料对话框句柄 
//      pst 用户资料结构地址 
static void _udGetCtlvar(HWND h, USERDATA *pst) 
{ 
   GetWindowText(GetDlgItem(h,U_EDIT), pst->note, sizeof(pst->note)); 
   GetWindowText(GetDlgItem(h,U_NAME), pst->in.name, sizeof(pst->in.name)); 
   GetWindowText(GetDlgItem(h,U_PROVINCE), pst->in.prov, sizeof(pst->in.prov)); 
   GetWindowText(GetDlgItem(h,U_CITY), pst->in.city, sizeof(pst->in.city)); 
   GetWindowText(GetDlgItem(h,U_TEL), pst->in.tel, sizeof(pst->in.tel)); 
   GetWindowText(GetDlgItem(h,U_WEB), pst->in.web, sizeof(pst->in.web)); 
   GetWindowText(GetDlgItem(h,U_EMAIL), pst->in.email, sizeof(pst->in.email)); 
   GetWindowText(GetDlgItem(h,U_YEAR), g_pTmp, 3); 
   pst->in.age = (char)atoi(g_pTmp); 
   GetWindowText(GetDlgItem(h,U_GENDER), g_pTmp, 3); 
   pst->in.sex = 0; 
   if(lstrcmp(g_pTmp,"男")==0) pst->in.sex=1; 
   if(lstrcmp(g_pTmp,"女")==0) pst->in.sex=-1; 
   return; 
} 
 
//设置用户资料对话框回调函数 
static BOOL CALLBACK _udSetCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_INITDIALOG: 
         _udSetuserdataInit(h); 
         return FALSE; 
      case WM_CLOSE: 
         DestroyWindow(h); 
         break; 
      case WM_DESTROY: 
         gstUD.hWndUDSet = NULL; 
         break; 
      case WM_COMMAND: 
         if(HIWORD(w)==EN_CHANGE) 
         { 
            if(LOWORD(w)==U_EDIT) 
               EnableWindow(GetDlgItem(h,U_BUTTON), TRUE); 
            if(LOWORD(w)>=UID_START && LOWORD(w)<=UID_END) 
               EnableWindow(GetDlgItem(h,U_BUTTON), TRUE); 
         } 
         switch(LOWORD(w)) 
         { 
         case U_OK: 
            _udGetCtlvar(h, &g_IV.stUD); 
            kpSetUserinfo(&g_IV.stUD); 
            DestroyWindow(h); 
            break; 
         case U_BUTTON: 
            _udGetCtlvar(h, &g_IV.stUD); 
            kpSetUserinfo(&g_IV.stUD); 
            EnableWindow((HWND)l, FALSE); 
            break; 
         case U_CLOSE: 
            DestroyWindow(h); 
            break; 
         } 
         break; 
      default: 
         return FALSE; 
   } 
   return TRUE; 
} 
 
//打开设置用户资料对话框 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL udOpenSetupUserData(void) 
{ 
   if(gstUD.hWndUDSet!=NULL) 
      FlashWindow(gstUD.hWndUDSet, TRUE); 
   else 
   { 
      if(gstMV.hWndMain==NULL) return FALSE; 
      gstUD.hWndUDSet = CreateDialog(g_hInst, 
         "UserData", gstMV.hWndMain, _udSetCallback); 
      if(gstUD.hWndUDSet==NULL) return FALSE; 
   } 
   SetFocus(gstUD.hWndUDSet); 
   return TRUE; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: OnLine模块(onl) 
说明: 在线列表对话框处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//显示在线用户列表数据 
//参数: kpGOUS结构指针 
static void onlUserList(kpGOUS const * const pst) 
{ 
   int i; 
   char *cp, cpid[7+1]={0}; 
   HWND hWnd; 
 
   if(gstMV.hWndOnLine==NULL) return; 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_GO), TRUE); 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_UP), TRUE); 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_DOWN), TRUE); 
   if(pst==NULL) 
   { 
      SendDlgItemMessage(gstMV.hWndOnLine, 
         ONLIE_STAT, SB_SETTXT, 0,(LPARAM)"错误!"); 
      return; 
   } 
   hWnd = GetDlgItem(gstMV.hWndOnLine, ONVAR_PCUR); 
   if(hWnd==NULL) return; 
   SetWindowLong(hWnd, GWL_USERDATA, pst->he.dwPage); 
   hWnd = GetDlgItem(gstMV.hWndOnLine, ONLIE_STAT); 
   if(hWnd==NULL) return; 
   wsprintf(g_pTmp, "第%d页", pst->he.dwPage+1); 
   SendMessage(hWnd, SB_SETTXT, 1,(LPARAM)g_pTmp); 
   SendMessage(hWnd, SB_SETTXT, 0,(LPARAM)"双击显示用户资料。"); 
   wsprintf(g_pTmp, "%d", pst->he.dwPage+1); 
   SetWindowText(GetDlgItem(gstMV.hWndOnLine,ONLIE_EDIT), g_pTmp); 
 
   hWnd = GetDlgItem(gstMV.hWndOnLine, ONLIE_LIST); 
   if(hWnd==NULL) return; 
   SendMessage(hWnd, LB_RESETCONTENT, 0,0); 
 
   for(i=0; i<pst->he.byNum; i++) 
   { 
      if(pst->st[i].byError!=0) 
         SendMessage(hWnd,LB_ADDSTRING,0,(LPARAM)"error data."); 
      else 
      { 
         if(pst->st[i].byMult==0) cp=""; else cp="(M)"; 
         if(pst->st[i].byUState==0) 
         { 
         wsprintf(g_pTmp, "%%≒≒≒ %s", cp); 
         SendMessage(hWnd, LB_ADDSTRING, 0,(LPARAM)g_pTmp); 
         } 
         else 
         { 
         ItoC(pst->st[i].dwPID, cpid); 
         wsprintf(g_pTmp, "%s %s", cpid, cp); 
         SendMessage(hWnd, LB_ADDSTRING, 0,(LPARAM)g_pTmp); 
         } 
      } 
   } 
   return; 
} 
 
//获取在线用户列表失败处理过程 
//参数: 失败原因代码 
static void onlGOuFail(WORD wErr) 
{ 
   char *p; 
   if(gstMV.hWndOnLine==NULL) return; 
   if(wErr==1) p="服务器响应超时!"; else p = "页码超出范围。"; 
   SendDlgItemMessage(gstMV.hWndOnLine,ONLIE_STAT,SB_SETTXT,0,(LPARAM)p); 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_UP), TRUE); 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_GO), TRUE); 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_DOWN), TRUE); 
   return; 
} 
 
//刷新在线用户列表 
//参数: h  对话框句柄 
//      dw 列表页码 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL _onlFurbishUserList(HWND h, DWORD dw) 
{ 
   int iErr; 
   iErr = kpGetOnlineUsers(dw); 
   if(iErr!=0) 
      SendDlgItemMessage(h,ONLIE_STAT,SB_SETTXT,0,(LPARAM)"错误,刷新失败!"); 
   else 
   { 
      EnableWindow(GetDlgItem(h,ONLIE_GO), FALSE); 
      EnableWindow(GetDlgItem(h,ONLIE_UP), FALSE); 
      EnableWindow(GetDlgItem(h,ONLIE_DOWN), FALSE); 
      SendDlgItemMessage(h,ONLIE_STAT,SB_SETTXT,0,(LPARAM)"请稍后..."); 
   } 
   return !iErr; 
} 
 
//显示服务器联机信息 
//参数: kpONLINEINFO结构变量地址 
static void onlOnlineInfo(kpONLINEINFO const * const p) 
{ 
   DWORD dwn; 
   if(gstMV.hWndOnLine==NULL) return; 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_NEW), TRUE); 
   if(p==NULL) 
   { 
      SendDlgItemMessage(gstMV.hWndOnLine, 
         ONLIE_STAT, SB_SETTXT, 3,(LPARAM)"错误!"); 
      return; 
   } 
   wsprintf(g_pTmp, "   " strONLSERINFO, p->dwMaxNum, p->bySerVer/10, 
      p->bySerVer%10, p->byNewVer/10, p->byNewVer%10, 
      p->byNewVer>VER_NUM?"建议升级电话软件":"电话软件无需更新"); 
   SetWindowText(GetDlgItem(gstMV.hWndOnLine,ONLIE_TEXT), g_pTmp); 
   wsprintf(g_pTmp, "%d人在线", p->dwOnlNum); 
   SendDlgItemMessage(gstMV.hWndOnLine,ONLIE_STAT, SB_SETTXT,3,(LPARAM)g_pTmp); 
   dwn = p->dwOnlNum/KP_INLPAGE_UNUM+((p->dwOnlNum%KP_INLPAGE_UNUM)?1:0); 
   wsprintf(g_pTmp, "共%d页", dwn); 
   SendDlgItemMessage(gstMV.hWndOnLine,ONLIE_STAT, SB_SETTXT,2,(LPARAM)g_pTmp); 
   SetWindowLong(GetDlgItem(gstMV.hWndOnLine,ONVAR_PSUM), GWL_USERDATA, dwn); 
   return; 
} 
 
//获取服务器联机信息失败处理过程 
static void onlGOiFail(void) 
{ 
   if(gstMV.hWndOnLine==NULL) return; 
   EnableWindow(GetDlgItem(gstMV.hWndOnLine,ONLIE_NEW), TRUE); 
   SendDlgItemMessage(gstMV.hWndOnLine, 
      ONLIE_STAT, SB_SETTXT, 3,(LPARAM)"服务器无响应!"); 
   return; 
} 
 
//刷新服务器联机信息 
//参数: 在线列表对话框窗口句柄 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL _onlFurbishOnlineInfo(HWND h) 
{ 
   int iErr; 
   char *ps; 
   iErr = kpGetOnlineInfo(TRUE); 
   if(iErr==0) ps = "请稍后..."; 
   else ps = "错误,刷新失败!"; 
   if(iErr==0) EnableWindow(GetDlgItem(h,ONLIE_NEW), FALSE); 
   SendDlgItemMessage(h,ONLIE_STAT, SB_SETTXT,3,(LPARAM)ps); 
   return !iErr; 
} 
 
//初始化在线列表对话框 
//参数: 对话框窗口句柄 
static void _onlInitializeOnLineDialog(HWND h) 
{ 
   int isPart[4]; 
   isPart[0] = 125; 
   isPart[1] = isPart[0] + 52; 
   isPart[2] = isPart[1] + 52; 
   isPart[3] = -1; 
   SendDlgItemMessage(h,ONLIE_STAT, SB_SETPAS, 4,(LPARAM)isPart); 
   SetWindowText(GetDlgItem(h,ONLIE_EDIT), "1"); 
   SendDlgItemMessage(h,ONLIE_EDIT, WM_SETFONT,(WPARAM)g_GJ.hDevFont,0); 
   SendDlgItemMessage(h,ONLIE_LIST, LB_SETCOLUMNWIDTH,80,0); 
   SetWindowLong(GetDlgItem(h,ONVAR_PCUR), GWL_USERDATA, 0); 
   SetWindowLong(GetDlgItem(h,ONVAR_PSUM), GWL_USERDATA, 1); 
   _onlFurbishOnlineInfo(h); 
   _onlFurbishUserList(h,0); 
   return; 
} 
 
//在线列表对话框回调函数 
static BOOL CALLBACK _onlCallBack(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   LONG lvr, lnm; 
   #define _BST BS_PUSHBUTTON|BS_CENTER|BS_FLAT|WS_CHILD|WS_VISIBLE|WS_TABSTOP 
   #define _setBST(w) SendMessage((HWND)(w),BM_SETSTYLE,_BST,_MKINT(1,0)) 
   #define _setTXT(s) SendDlgItemMessage(h,ONLIE_STAT,SB_SETTXT,0,(LPARAM)(s)) 
   switch(u) 
   { 
      case WM_INITDIALOG: 
         _onlInitializeOnLineDialog(h); 
         return FALSE; 
      case WM_CLOSE: 
         DestroyWindow(h); 
         break; 
      case WM_DESTROY: 
         gstMV.hWndOnLine = NULL; 
         kpGetOnlineInfo(FALSE); 
         kpGetOnlineUsers(KP_GOUSTOP); 
         break; 
      case WM_COMMAND: 
         switch(LOWORD(w)) 
         { 
         case IDCANCEL: 
            DestroyWindow(h); 
            break; 
         case ONLIE_LIST: 
         case ONLIE_CALL: 
            if(LOWORD(w)==ONLIE_CALL) _setBST(l); 
            if(LOWORD(w)==ONLIE_LIST && HIWORD(w)!=LBN_DBLCLK) break; 
            lvr = SendDlgItemMessage(h,ONLIE_LIST,LB_GETCURSEL,0,0); 
            if(lvr==LB_ERR) break; 
            lnm = SendDlgItemMessage(h,ONLIE_LIST,LB_GETTEXTLEN,lvr,0); 
            if(lnm==LB_ERR) break; 
            if((DWORD)(lnm+1)>=sizeof(g_pTmp)) break; 
            lnm = SendDlgItemMessage(h,ONLIE_LIST,LB_GETTEXT,lvr,(LPARAM)g_pTmp); 
            if(lnm==LB_ERR) break; 
            lnm = CtoI(g_pTmp); 
            if(lnm==0) break; 
            if(LOWORD(w)==ONLIE_CALL) 
            { 
               g_pTmp[7]=0; ItoC(lnm,g_pTmp); 
               SetWindowText(GetDlgItem(gstMV.hWndMain,TL_EDIT), g_pTmp); 
               break; 
            } 
            if(LOWORD(w)==ONLIE_LIST) udGetUserData(lnm); 
            break; 
         case ONLIE_NEW: 
            _setBST(l); 
            SetFocus(GetDlgItem(h,ONLIE_EDIT)); 
            _onlFurbishOnlineInfo(h); 
            break; 
         case ONLIE_UP: 
            _setBST(l); 
            SetFocus(GetDlgItem(h,ONLIE_EDIT)); 
            lvr = GetWindowLong(GetDlgItem(h,ONVAR_PCUR), GWL_USERDATA); 
            if(lvr<=0) _setTXT("已到第一页。"); 
            else _onlFurbishUserList(h, (DWORD)lvr-1); 
            break; 
         case ONLIE_DOWN: 
            _setBST(l); 
            SetFocus(GetDlgItem(h,ONLIE_EDIT)); 
            lvr = GetWindowLong(GetDlgItem(h,ONVAR_PCUR), GWL_USERDATA); 
            if(lvr+1 >= GetWindowLong(GetDlgItem(h,ONVAR_PSUM),GWL_USERDATA)) 
               _setTXT("已到最后一页。"); 
            else 
               _onlFurbishUserList(h, (DWORD)lvr+1); 
            break; 
         case ONLIE_GO: 
            _setBST(l); 
            SetFocus(GetDlgItem(h,ONLIE_EDIT)); 
            GetWindowText(GetDlgItem(h,ONLIE_EDIT), g_pTmp, sizeof(g_pTmp)); 
            lvr = atoi(g_pTmp); 
            _setTXT("请输入正确的页码。"); 
            if(lvr<=0) break; 
            if(lvr>GetWindowLong(GetDlgItem(h,ONVAR_PSUM),GWL_USERDATA)) break; 
            _onlFurbishUserList(h, (DWORD)lvr-1); 
            break; 
         } 
         break; 
      default: 
         return FALSE; 
   } 
   #undef _BST 
   #undef _setBST 
   #undef _setTXT 
   return TRUE; 
} 
 
//打开在线列表对话框 
//参数: 父窗口句柄 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL onlOpen(HWND h) 
{ 
   if(gstMV.hWndOnLine!=NULL) 
      FlashWindow(gstMV.hWndOnLine, TRUE); 
   else 
   { 
      gstMV.hWndOnLine = CreateDialog(g_hInst,"OnLine",h,_onlCallBack); 
      if(gstMV.hWndOnLine==NULL) return FALSE; 
   } 
   SetFocus(gstMV.hWndOnLine); 
   return TRUE; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: FaceWin模块(fcw) 
说明: 电话面板Face子窗口处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//设置空闲提示画面变量 
//参数: pct  提示标题 
//      pca  提示内容A 
//      pcb  提示内容B 
//      bmp  位图句柄 
//备注: 该函数刷新Face窗口客户区。 
static void fcwSv(char *pct, char *pca, char *pcb, HBITMAP bmp) 
{ 
   gstFV.dwIdleSt = 1; 
   gstFV.pcIdleT1 = pct; 
   gstFV.pcIdleT2 = pca; 
   gstFV.pcIdleT3 = pcb; 
   gstFV.dwIdleCoun = 0; 
   gstFV.hIdleBmpST = bmp; 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   return; 
} 
 
//绘制谈话状态Face窗口内容 
//参数: hDC 设备描述表句柄 
//      iTy 绘制内容(1:输出FREN, 2:输入FREN, 3:时间, 4:指示器) 
static void _fcwDrawTalkfc(HDC hDC, int iTy) 
{ 
   DITIME  stm; 
   HGDIOBJ hObj; 
   int     it; 
   switch(iTy) 
   { 
      case 1: 
         if(gstFV.byPFren>16) gstFV.byPFren=16; 
         it = gstFV.byPFren<<2; 
         hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTalk); 
         BitBlt(hDC, 23+it, 41, 64-it, 8, g_GJ.hMemDC, 23+it, 41, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
         hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTkv); 
         BitBlt(hDC, 23, 41, it, 8, g_GJ.hMemDC, 0, 0, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
         break; 
      case 2: 
         if(gstFV.byRFren>16) gstFV.byRFren=16; 
         it = gstFV.byRFren<<2; 
         hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTalk); 
         BitBlt(hDC, 23+it, 55, 64-it, 8, g_GJ.hMemDC, 23+it, 55, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
         hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTkv); 
         BitBlt(hDC, 23, 55, it, 8, g_GJ.hMemDC, 0, 0, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
         break; 
      case 3: 
         hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTalk); 
         BitBlt(hDC, 111, 74, 54, 13, g_GJ.hMemDC, 111, 74, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
         DiffTime(&stm, gstFV.dwTick); 
         if(stm.dwHour>99) stm.dwHour=99; 
         it = wsprintf(g_pTmp,"%02d:%02d:%02d",stm.dwHour,stm.dwMin,stm.dwSec); 
         TextOut(hDC, 114, 74, g_pTmp, it); 
         break; 
      case 4: 
         if(gstFV.bSend) 
         { 
            hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTks); 
            BitBlt(hDC, 99, 55, 11, 8, g_GJ.hMemDC, 0, 0, SRCCOPY); 
            SelectObject(g_GJ.hMemDC, hObj); 
         } 
         else 
         { 
            hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTalk); 
            BitBlt(hDC, 99, 55, 11, 8, g_GJ.hMemDC, 99, 55, SRCCOPY); 
            SelectObject(g_GJ.hMemDC, hObj); 
         } 
         break; 
   } 
   return; 
} 
 
//更新谈话状态Face窗口内容 
//参数: 更新内容(1:输出FREN, 2:输入FREN, 3:时间, 4:指示器) 
static void fcwUpdateTalkFace(int iTy) 
{ 
   HGDIOBJ hFont = NULL; 
   HDC hDC; 
   if(gstMV.iPhoneWork!=KW_TALK) return; 
   hDC = GetDC(gstFV.hWndFace); 
   if(hDC==NULL) return; 
   if(iTy==3) 
   { 
      SetBkMode(hDC, TRANSPARENT); 
      SetTextColor(hDC, TTRGB_BLACK); 
      hFont = SelectObject(hDC, g_GJ.hGuiFont); 
   } 
   _fcwDrawTalkfc(hDC, iTy); 
   if(hFont!=NULL) SelectObject(hDC, hFont); 
   ReleaseDC(gstFV.hWndFace, hDC); 
   return; 
} 
 
//WM_PAINT消息处理函数 
//参数: Face子窗口句柄 
static void _fcwPaintMes(HWND h) 
{ 
   HDC hDC; 
   PAINTSTRUCT ps; 
   HGDIOBJ hObj; 
   HGDIOBJ hFont; 
   char* pcs; 
   int iRst; 
   struct in_addr addr; 
 
   hDC = BeginPaint(h, &ps); 
   if(hDC==NULL) return; 
   SetBkMode(hDC, TRANSPARENT); 
   hFont = SelectObject(hDC, g_GJ.hGuiFont); 
 
   switch(gstMV.iPhoneWork) 
   { 
   case KW_IDLE: 
      if(gstFV.dwIdleSt==0) 
      { 
         hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpIdle); 
         BitBlt(hDC, 0, 0, 171, 90, g_GJ.hMemDC, 0, 0, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
      } 
      else if(gstFV.dwIdleSt==1) 
      { 
         hObj = SelectObject(g_GJ.hMemDC, gstFV.hIdleBmpST); 
         BitBlt(hDC, 0, 0, 171, 90, g_GJ.hMemDC, 0, 0, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
         SetTextColor(hDC, TTRGB_WHITE); 
         TextOut(hDC, 7,29, gstFV.pcIdleT2, lstrlen(gstFV.pcIdleT2)); 
         TextOut(hDC, 7,48, gstFV.pcIdleT3, lstrlen(gstFV.pcIdleT3)); 
         SetTextColor(hDC, TTRGB_BLACK); 
         TextOut(hDC, 6,4, gstFV.pcIdleT1, lstrlen(gstFV.pcIdleT1)); 
      } 
      else 
      { 
         hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpAskX); 
         BitBlt(hDC, 0, 0, 171, 90, g_GJ.hMemDC, 0, 0, SRCCOPY); 
         SelectObject(g_GJ.hMemDC, hObj); 
         SetTextColor(hDC, TTRGB_WHITE); 
         if(gstFV.wPort==0) 
         { 
            iRst = gstFV.stTime.wHour; 
            if(iRst==0) iRst=12; if(iRst>12) iRst=iRst-12; 
            iRst = wsprintf(g_pTmp, "时间: %02d:%02d%s", iRst, 
               gstFV.stTime.wMinute, gstFV.stTime.wHour>=12?"PM":"AM"); 
            TextOut(hDC, 7, 29, g_pTmp, iRst); 
            g_pTmp[7] = 0; 
            ItoC(gstFV.dwIP, g_pTmp); 
            iRst = wsprintf(&g_pTmp[8],"号码: %s", g_pTmp); 
            TextOut(hDC, 7, 48, &g_pTmp[8], iRst); 
         } 
         else 
         { 
            iRst = gstFV.stTime.wHour; 
            if(iRst==0) iRst=12; if(iRst>12) iRst=iRst-12; 
            iRst = wsprintf(g_pTmp, "时间:%02d:%02d%s", iRst, 
               gstFV.stTime.wMinute, gstFV.stTime.wHour>=12?"PM":"AM"); 
            TextOut(hDC, 6, 25, g_pTmp, iRst); 
            addr.s_addr = gstFV.dwIP; 
            pcs = inet_ntoa(addr); 
            if(pcs==NULL) pcs="0.0.0.0"; 
            iRst = wsprintf(g_pTmp, "地址:%s", pcs); 
            TextOut(hDC, 6, 39, g_pTmp, iRst); 
            iRst = wsprintf(g_pTmp, "端口:%d(UDP)", ntohs(gstFV.wPort)); 
            TextOut(hDC, 6, 53, g_pTmp, iRst); 
         } 
         SetTextColor(hDC, TTRGB_BLACK); 
         TextOut(hDC, 6, 4, "未接来电∵", 10); 
      } 
      SetTextColor(hDC, TTRGB_BLACK); 
      TextOut(hDC, 4, 74, "[空闲]", 6); 
      TextOut(hDC, 111, 74, "VER:" VER_STR, 7); 
      break; 
   case KW_CALL: 
      hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpCall); 
      BitBlt(hDC, 0, 0, 171, 90, g_GJ.hMemDC, 0, 0, SRCCOPY); 
      SelectObject(g_GJ.hMemDC, hObj); 
      SetTextColor(hDC, TTRGB_WHITE); 
      if(gstFV.wPort==0) 
      { 
         TextOut(hDC, 7, 29, "被叫方号码 ∵", 13); 
         g_pTmp[7] = 0; 
         ItoC(gstFV.dwIP, g_pTmp); 
         iRst = wsprintf(&g_pTmp[8], "PID:%s", g_pTmp); 
         TextOut(hDC, 41, 48, &g_pTmp[8], iRst); 
      } 
      else 
      { 
         TextOut(hDC, 6, 25, "被叫方地址 ⊕", 13); 
         addr.s_addr = gstFV.dwIP; 
         pcs = inet_ntoa(addr); 
         if(pcs==NULL) pcs="0.0.0.0"; 
         iRst = wsprintf(g_pTmp, "IP:%s", pcs); 
         TextOut(hDC, 6, 39, g_pTmp, iRst); 
         iRst = wsprintf(g_pTmp, "PORT:%d(UDP)", ntohs(gstFV.wPort)); 
         TextOut(hDC, 6, 53, g_pTmp, iRst); 
      } 
      SetTextColor(hDC, TTRGB_BLACK); 
      TextOut(hDC, 6, 4, "正在呼叫,请稍后...", 18); 
      TextOut(hDC, 4, 74, "[呼叫]", 6); 
      iRst = wsprintf(g_pTmp, "时间:%02d秒", gstFV.dwTick); 
      TextOut(hDC, 108, 74, g_pTmp, iRst); 
      break; 
   case KW_ASK: 
      hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpAsk); 
      BitBlt(hDC, 0, 0, 171, 90, g_GJ.hMemDC, 0, 0, SRCCOPY); 
      SelectObject(g_GJ.hMemDC, hObj); 
      SetTextColor(hDC, TTRGB_WHITE); 
      if(gstFV.wPort==0) 
      { 
         TextOut(hDC, 7, 29, "主叫方号码 ∵", 13); 
         g_pTmp[7] = 0; 
         ItoC(gstFV.dwIP, g_pTmp); 
         iRst = wsprintf(&g_pTmp[8], "PID:%s", g_pTmp); 
         TextOut(hDC, 41, 48, &g_pTmp[8], iRst); 
      } 
      else 
      { 
         TextOut(hDC, 6, 25, "主叫方地址 ⊕", 13); 
         addr.s_addr = gstFV.dwIP; 
         pcs = inet_ntoa(addr); 
         if(pcs==NULL) pcs="0.0.0.0"; 
         iRst = wsprintf(g_pTmp, "IP:%s", pcs); 
         TextOut(hDC, 6, 39, g_pTmp, iRst); 
         iRst = wsprintf(g_pTmp, "PORT:%d(UDP)", ntohs(gstFV.wPort)); 
         TextOut(hDC, 6, 53, g_pTmp, iRst); 
      } 
      SetTextColor(hDC, TTRGB_BLACK); 
      TextOut(hDC, 6, 4, "来电话啦,是否接听?", 19); 
      TextOut(hDC, 4, 74, "[询问]", 6); 
      iRst = wsprintf(g_pTmp, "时间:%02d秒", gstFV.dwTick); 
      TextOut(hDC, 108, 74, g_pTmp, iRst); 
      break; 
   case KW_TALK: 
      hObj = SelectObject(g_GJ.hMemDC, gstRV.bmpTalk); 
      BitBlt(hDC, 0, 0, 171, 90, g_GJ.hMemDC, 0, 0, SRCCOPY); 
      SelectObject(g_GJ.hMemDC, hObj); 
      SetTextColor(hDC, TTRGB_WHITE); 
      if(gstFV.wPort==0) 
      { 
         g_pTmp[7] = 0; 
         ItoC(gstFV.dwIP, g_pTmp); 
         iRst = wsprintf(&g_pTmp[8], "PID:%s", g_pTmp); 
         TextOut(hDC, 7, 25, &g_pTmp[8], iRst); 
      } 
      else 
      { 
         addr.s_addr = gstFV.dwIP; 
         pcs = inet_ntoa(addr); 
         if(pcs==NULL) pcs="0.0.0.0"; 
         iRst = wsprintf(g_pTmp, "IP:%s", pcs); 
         TextOut(hDC, 7, 25, g_pTmp, iRst); 
      } 
      TextOut(hDC, 7, 39, "PW:ERROR", gstFV.bOutWOpen?3:8); 
      if(gstFV.bOutWOpen) 
      { 
         TextOut(hDC, 87, 39, ":", 1); 
         _fcwDrawTalkfc(hDC, 1); 
      } 
      TextOut(hDC, 7, 53, "RW:ERROR", gstFV.bInWOpen?3:8); 
      if(gstFV.bInWOpen) 
      { 
         TextOut(hDC, 87, 53, ":", 1); 
         TextOut(hDC, 99, 39, "ST",2); 
         _fcwDrawTalkfc(hDC, 2); 
         _fcwDrawTalkfc(hDC, 4); 
      } 
      SetTextColor(hDC, TTRGB_BLACK); 
      TextOut(hDC, 6, 4, "正在通话...", 11); 
      if(gstFV.byMult==0) TextOut(hDC,81,4,gstFV.bPasi?"[被叫]":"[主叫]",6); 
      else TextOut(hDC, 81, 4, "[多方]", 6); 
      TextOut(hDC, 4, 74, "[通话]", 6); 
      _fcwDrawTalkfc(hDC, 3); 
      break; 
   } 
 
   SetTextColor(hDC, TTRGB_BLACK); 
   if(g_IV.bStartMd) TextOut(hDC, 46, 74, "[IP模式]", 8); 
   else TextOut(hDC, 46, 74, gstMV.iOnLine?"[联机]":"[离线]", 6); 
   SelectObject(hDC, hFont); 
   EndPaint(h, &ps); 
   return; 
} 
 
//WM_TIMER消息处理函数 
//参数: hWnd  Face窗口句柄 
//      wmID  计时器ID代码 
static void _fcwTimerMes(HWND hWnd, WPARAM wmID) 
{ 
   RECT rt; 
   if(wmID!=TIMER_COUNT) return; 
   if(gstMV.iPhoneWork==KW_TALK) 
   { 
      fcwUpdateTalkFace(3); 
      return; 
   } 
   if(gstMV.iPhoneWork==KW_CALL || gstMV.iPhoneWork==KW_ASK) 
   { 
      if(gstFV.dwTick>90) return; 
      gstFV.dwTick++; 
      rt.left=130;  rt.top=71; 
      rt.right=154; rt.bottom=87; 
      InvalidateRect(hWnd, &rt, FALSE); 
   } 
   else 
   { 
      if(gstFV.dwIdleSt!=1) 
      { 
         KillTimer(hWnd, TIMER_COUNT); 
         return; 
      } 
      gstFV.dwIdleCoun++; 
      if(gstFV.dwIdleCoun>7) 
      { 
         KillTimer(hWnd, TIMER_COUNT); 
         gstFV.dwIdleSt = 0; 
         InvalidateRect(hWnd, NULL, FALSE); 
      } 
   } 
   return; 
} 
 
//Face子窗口回调函数 
static LRESULT CALLBACK fcwCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_PAINT: 
         _fcwPaintMes(h); 
         break; 
      case WM_LBUTTONDOWN: 
         SendDlgItemMessage(gstMV.hWndMain, TL_CALL, 
            BM_SETSTYLE, BUTON_STYLE, _MKINT(1,0)); 
         if(gstMV.iPhoneWork!=KW_IDLE) break; 
         if(gstFV.dwIdleSt==0) break; 
         gstFV.dwIdleSt = 0; 
         InvalidateRect(h, NULL, FALSE); 
         StopSound(); 
         break; 
      case WM_TIMER: 
         _fcwTimerMes(h, w); 
         break; 
      case WM_DESTROY: 
         KillTimer(h, TIMER_COUNT); 
         break; 
      default: 
         return(DefWindowProc(h,u,w,l)); 
   } 
   return 0; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: PnWin模块(pnw) 
说明: 主窗口及窗口控制处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//启动K-Phone 
//参数: 主窗口句柄 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL _pnwStartKPhone(HWND hWnd) 
{ 
   int iErr; 
   kpSERVER stSer; 
   kpINIT stInit; 
 
   stInit.wVer = KP_VERSION; 
   stInit.hWnd = hWnd; 
   stInit.uMes = WM_KPHONE; 
   stInit.wInPort   = htons(g_IV.wPort); 
   stInit.iPriority = THREAD_PRIORITY_TIME_CRITICAL; 
 
   stSer.dwSerIP  = g_SO.dwSerIP; 
   stSer.wSerPort = htons(SERPORT); 
   stSer.dwInIP   = g_SO.dwLocIP; 
   stSer.dwPID    = g_IV.dwPID; 
   stSer.byUState = (BYTE)(g_IV.bLieup?0:255); 
   stSer.dwKeepTime = g_IV.dwKeTime; 
   CopyMemory(stSer.pass, g_SO.pass, sizeof(stSer.pass)); 
 
   if(g_IV.bStartMd) iErr = kpInit(&stInit, NULL); 
   else iErr = kpInit(&stInit, &stSer); 
   if(iErr==0) return TRUE; 
 
   switch(iErr) 
   { 
      case 1: 
         gstMV.pErrText = "内部错误: K-Phone重复初始化! "; 
         break; 
      case 5: 
         gstMV.iReturnVar = 0; 
         gstMV.pErrText = "内部错误: 不正确的启动参数! "; 
         break; 
      case 7: 
         g_IV.bPro = TRUE; 
         g_SO.bPortErr = TRUE; 
         gstMV.iReturnVar = 0; 
         gstMV.pErrText = "指定的UDP端口被占用, 请更改“端口”参数。"; 
         break; 
      default: 
         gstMV.pErrText = "未知错误: K-Phone初始化失败! "; 
   } 
   return FALSE; 
} 
 
//创建窗口控制 
//参数: 主窗口句柄 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL _pnwCreateCortrol(HWND hWnd) 
{ 
   HWND hw; 
 
   //创建窗口控制 
   #define _cTL(id,cs,tt,sy,x,y,w,h) CreateWindow((cs),(tt),\ 
          (sy),(x),(y),(w),(h),hWnd,(HMENU)(id),g_hInst,NULL) 
   hw = _cTL(255, "BUTTON","", GRBOX_STYLE, 7,152,173,59); 
   if(hw==NULL) return FALSE; 
   hw = _cTL(TL_EDIT, "EDIT","", TEDIT_STYLE|UEDIT_STYLE, 7,102,149,20); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hDevFont,0); 
   SendMessage(hw, EM_SETLIMITTEXT, 27,0); 
   hw = _cTL(TL_USER, "BUTTON","⊿", BUTON_STYLE|WS_DISABLED, 164,104,16,16); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_CALL, "BUTTON","呼叫", BUTON_STYLE, 7,129,41,23); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_ANSW, "BUTTON","接听", BUTON_STYLE|WS_DISABLED, 51,129,41,23); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_REFU, "BUTTON","拒绝", BUTON_STYLE|WS_DISABLED, 95,129,41,23); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_HAND, "BUTTON","挂断", BUTON_STYLE|WS_DISABLED, 139,129,41,23); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_POFF, "BUTTON","输出静音", CHECK_STYLE, 17,168,66,16); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_ROFF, "BUTTON","话筒静音", CHECK_STYLE, 17,188,66,16); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_OPTI, "BUTTON","音频项面板", CHECK_STYLE, 93,168,82,16); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   hw = _cTL(TL_QUIE, "BUTTON","哑铃", CHECK_STYLE, 93,188,44,16); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hGuiFont,0); 
   SendMessage(hw, BM_SETCHECK, !g_IV.bRing,0); 
   hw = _cTL(TL_REST, "BUTTON","-", BUTON_STYLE|WS_DISABLED, 143,188,26,14); 
   if(hw==NULL) return FALSE; 
   SendMessage(hw, WM_SETFONT, (WPARAM)g_GJ.hDevFont,0); 
   #undef _cTL 
 
   //创建Face窗口 
   gstFV.hWndFace = CreateWindowEx(FCWIN_STYEX, gcpFaceClass, 
      "fw", FCWIN_STYLE, 7, 2, 173, 92, hWnd, 0, g_hInst, 0); 
   if(gstFV.hWndFace==NULL) return FALSE; 
 
   //创建历史记录对话框 
   gstMV.hWndLog = CreateDialog(g_hInst, "CommLog", hWnd, logCallback); 
   if(gstMV.hWndLog==NULL) return FALSE; 
 
   //创建登录提示框 
   if(!g_IV.bStartMd) 
   { 
      gstMV.hWndLogon = CreateDialog(g_hInst,"Prompt",hWnd,otrLogonCallback); 
      if(gstMV.hWndLogon==NULL) return FALSE; 
   } 
   return TRUE; 
} 
 
//KPNM_START消息处理过程 
//参数: hWnd  主窗口句柄 
//      Par32 32bit消息参数 
static void _pnwKStartKpnm(HWND hWnd, DWORD Par32) 
{ 
   RECT rtSpi, rtPmt; 
   RECT rtWin, rtCli; 
   LONG lx,ly, lw,lh; 
   SYSTEMTIME stTime; 
 
   PSound(g_GJ.pPWelc, FALSE); 
   StopSound(); 
 
   SystemParametersInfo(SPI_GETWORKAREA, 0, &rtSpi, 0); 
   GetWindowRect(hWnd, &rtWin); 
   GetClientRect(hWnd, &rtCli); 
   lw = (rtWin.right - rtWin.left) + (187 - rtCli.right); 
   lh = (rtWin.bottom - rtWin.top) + (218 - rtCli.bottom); 
   lx = rtSpi.right - lw - 10; 
   ly = rtSpi.bottom - lh - 12; 
   MoveWindow(hWnd, lx, ly, lw, lh, 0); 
   GetWindowRect(hWnd, &rtWin); 
 
   if(gstMV.hWndLogon==NULL) 
      DrawAnimatedRects(hWnd, 3, &g_SO.rtEnter, &rtWin); 
   else 
   { 
      GetWindowRect(gstMV.hWndLogon, &rtPmt); 
      DestroyWindow(gstMV.hWndLogon); 
      DrawAnimatedRects(hWnd, 3, &rtPmt, &rtWin); 
   } 
 
   gstMV.iOnLine = Par32; 
   otrKpSetup(&gstMV.stKOpt); 
   ShowWindow(hWnd, SW_SHOW); 
   SetFocus(GetDlgItem(hWnd, TL_EDIT)); 
   udUserdataDisp(&g_IV.stUD); 
   kpSetUserinfo(&g_IV.stUD); 
   otrModiMenu(); 
   PSound(g_GJ.pPWelc, FALSE); 
 
   GetLocalTime(&stTime); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 电话启动。登录状态:%s。", 
      stTime.wYear, stTime.wMonth, stTime.wDay, stTime.wHour, 
      stTime.wMinute, Par32?"成功登录到服务器":"未登录"); 
   logOutEventlog(g_pTmp, TRUE); 
   return; 
} 
 
//KPNM_LOGONERROR消息处理过程 
//参数: hWnd  主窗口句柄 
//      Par16 16bit消息参数 
static void _pnwLogonErrorKpnm(HWND hWnd, WORD Par16) 
{ 
   char *ps = "登录失败!\r\n未知的错误, 请尝试重新登录。"; 
   if(Par16==0)  ps = "服务器故障或系统维护中, 请稍候再登录。"; 
   if(Par16==1)  ps = "服务器繁忙! 请稍候再登录。"; 
   if(Par16==13) ps = "服务器拒绝登录请求, 原因: 联机用户满员。"; 
   if(Par16==14) ps = "服务器拒绝登录请求, 原因: 帐号或密码错误。"; 
   if(Par16==15) ps = "登录失败!\r\n该用户已在别处登录, 请更换用户号码。"; 
   if(Par16==16) ps = "服务器拒绝登录请求, 原因: 该帐号欠费冻结。"; 
   if(Par16==17) ps = "服务器拒绝登录请求, 原因: 该帐号暂停使用。"; 
   gstMV.pErrText = ps; 
   gstMV.iReturnVar = 0; 
   DestroyWindow(hWnd); 
   return; 
} 
 
//KPNM_IDLE消息处理过程 
//参数: hWnd 主窗口句柄 
static void _pnwIdleKpnm(HWND hWnd) 
{ 
   DWORD dwpc = g_IV.bLowPRI?IDLE_PRIORITY_CLASS:NORMAL_PRIORITY_CLASS; 
   gstMV.iPhoneWork = KW_IDLE; 
   gstUD.hWndBeMain = NULL; 
   otrDPhoneBut(); 
   EnableWindow(GetDlgItem(hWnd,TL_CALL), TRUE); 
   SetPriorityClass(GetCurrentProcess(), dwpc); 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   return; 
} 
 
//KPNM_HANGUP消息处理过程 
static void _pnwHangupKpnm(DWORD Par32) 
{ 
   char *ps = "您挂断了电话,"; 
   char *pc = "本次通话结束。"; 
 
   //设置空闲画面 
   if(gstMV.iPhoneWork==KW_CALL) 
   { 
      ps = TEXT("您取消了本次呼叫"); 
      pc = TEXT("操作。"); 
   } 
   if(gstMV.iPhoneWork==KW_ASK) 
   { 
      ps = TEXT("您拒绝了主叫方的"); 
      pc = TEXT("呼叫请求。"); 
      if(Par32==HANG_AUTO) pc="呼叫请求(自动)。"; 
   } 
   fcwSv("挂断电话。", ps, pc, gstRV.bmpHang); 
 
   //播放提示声音 
   if(gstMV.iPhoneWork==KW_ASK && Par32==HANG_AUTO) StopSound(); 
   else PSound(g_GJ.pSHang, FALSE); 
 
   //输出通话记录 
   if(gstMV.iPhoneWork==KW_TALK) 
   { 
      otrPrintPID(gstFV.dwIP, gstFV.wPort); 
      wsprintf(g_pTmp, "[通话记录]  %s  时间:%d点%d分%d秒。", gstMV.sTmp, 
         gstFV.stTime.wHour, gstFV.stTime.wMinute, gstFV.stTime.wSecond); 
      logOutCommlog(g_pTmp, FALSE); 
      wsprintf(g_pTmp, "            主叫标志:%s叫  通话时长:%d秒。", 
         gstFV.bPasi?"被":"主", (DWORD)(GetTickCount()-gstFV.dwTick)/1000); 
      logOutCommlog(g_pTmp, TRUE); 
   } 
 
   //输出事件记录 
   GetLocalTime(&gstFV.stTime); 
   if(gstMV.iPhoneWork!=KW_ASK) ps=TEXT("用户挂机"); 
   else ps=(Par32==HANG_AUTO?"自动拒绝":"拒绝接听"); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 挂断电话。说明:%s。", 
      gstFV.stTime.wYear, gstFV.stTime.wMonth, gstFV.stTime.wDay, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, ps); 
   logOutEventlog(g_pTmp, TRUE); 
   return; 
} 
 
//KPNM_CALL消息处理过程 
//参数: hWnd   主窗口句柄 
//      Par16  16bit消息参数 
//      Par32  32bit消息参数 
static void _pnwCallKpnm(HWND hWnd, WORD Par16, DWORD Par32) 
{ 
   gstMV.iPhoneWork = KW_CALL; 
   GetLocalTime(&gstFV.stTime); 
   gstFV.dwTick = 0; 
   gstFV.dwIP = Par32; 
   gstFV.wPort = Par16; 
   otrDPhoneBut(); 
   EnableWindow(GetDlgItem(hWnd,TL_HAND), TRUE); 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   SetTimer(gstFV.hWndFace, TIMER_COUNT, 1000, NULL); 
   PSound(g_GJ.pSBack, TRUE); 
   otrPrintPID(gstFV.dwIP, gstFV.wPort); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 拨叫电话。被叫方%s。", 
      gstFV.stTime.wYear, gstFV.stTime.wMonth, gstFV.stTime.wDay, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, gstMV.sTmp); 
   logOutEventlog(g_pTmp, TRUE); 
   return; 
} 
 
//KPNM_CALLFAIL消息处理过程 
//参数: Par16 16bit消息参数 
//      Par32 32bit消息参数 
static void _pnwCallFailKpnm(WORD Par16, DWORD Par32) 
{ 
   char *ps; 
   char *pc; 
 
   if(Par16==0) 
   { 
      //设置空闲画面 
      ps = TEXT("呼叫失败!"); 
      pc = TEXT("原因说明:"); 
      fcwSv(ps, "未知的错误。","请检查软件版本更新。", gstRV.bmpCallX); 
      if(Par32==2) fcwSv(ps, pc,"被叫方无应答(超时)。",gstRV.bmpCallX); 
      if(Par32==53) fcwSv(ps,pc,"您拨叫的号码不存在。",gstRV.bmpCallX); 
      ps = TEXT("通讯错误!"); 
      if(Par32==0) fcwSv(ps, pc,"服务器响应超时。", gstRV.bmpError); 
      if(Par32==1) fcwSv(ps, pc,"被叫端响应超时。", gstRV.bmpError); 
 
      //播放提示声音 
      if(Par32==2) PSound(g_GJ.pPOver, FALSE); 
      else if(Par32==53) PSound(g_GJ.pPNull, FALSE); 
      else PSound(g_GJ.pSErr, FALSE); 
   } 
   else 
   { 
      //设置空闲画面 
      pc = TEXT("对方拒绝接听电话。"); 
      if(Par32<=199 && Par32!=HANG_AUTO) pc="对方不方便接听电话。"; 
      if(Par32==252) pc="不符合呼叫要求。"; 
      if(Par32==253) pc="软件版本不兼容。"; 
      if(Par32==254) pc="被叫方电话关机。"; 
      if(Par32==255) pc="被叫方电话正忙。"; 
      fcwSv("呼叫失败!","原因说明:", pc, gstRV.bmpCallX); 
 
      //播放提示声音 
      if(Par32==255) PSound(g_GJ.pPBusy, FALSE); 
      else if(Par32<=199) PSound(g_GJ.pPRefu, FALSE); 
      else PSound(g_GJ.pSErr, FALSE); 
   } 
 
   //输出通讯记录 
   otrPrintPID(gstFV.dwIP, gstFV.wPort); 
   wsprintf(g_pTmp, "[呼叫失败]  %s  时间:%d点%d分%d秒。", gstMV.sTmp, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, gstFV.stTime.wSecond); 
   logOutCommlog(g_pTmp, TRUE); 
 
   //输出事件记录 
   GetLocalTime(&gstFV.stTime); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 拨叫失败。失败代码:%d/%d。", 
      gstFV.stTime.wYear, gstFV.stTime.wMonth, gstFV.stTime.wDay, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, Par16, Par32); 
   logOutEventlog(g_pTmp, TRUE); 
   return; 
} 
 
//KPNM_TALK消息处理过程 
//参数: hWnd   主窗口句柄 
//      Par16  16bit消息参数 
//      Par32  32bit消息参数 
static void _pnwTalkKpnm(HWND hWnd, WORD Par16, DWORD Par32) 
{ 
   gstMV.iPhoneWork = KW_TALK; 
   gstMV.dwArevTick = GetTickCount(); 
   GetLocalTime(&gstFV.stTime); 
   gstFV.dwTick = GetTickCount(); 
   gstFV.bPasi = Par32; 
   gstFV.byMult = (BYTE)Par16; 
   gstFV.bOutWOpen = TRUE; 
   gstFV.bInWOpen = TRUE; 
   gstFV.byPFren = 0; 
   gstFV.byRFren = 0; 
   gstFV.bSend = FALSE; 
   otrDPhoneBut(); 
   EnableWindow(GetDlgItem(hWnd,TL_HAND), TRUE); 
   EnableWindow(GetDlgItem(hWnd,TL_REST), TRUE); 
   if(gstFV.wPort==0) 
   { 
      gstUD.hWndBeMain = GetDlgItem(hWnd,TL_USER); 
      if(!gstUD.bStart) EnableWindow(gstUD.hWndBeMain, TRUE); 
   } 
   PSound(g_GJ.pSTck, FALSE); 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 开始通话。主叫:%s, MULT:%d。", 
      gstFV.stTime.wYear, gstFV.stTime.wMonth, gstFV.stTime.wDay, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, Par32?"N":"Y", Par16); 
   logOutEventlog(g_pTmp, TRUE); 
   return; 
} 
 
//KPNM_BUZZOFF消息处理过程 
static void _pnwBuzzoffKpnm(WORD Par16, DWORD Par32) 
{ 
   char *ps = "通讯错误!"; 
   char *pc = "原因说明:"; 
 
   //设置空闲画面 
   fcwSv("电话挂断。","对方挂断了电话!","本次通话结束。",gstRV.bmpHang); 
   if(Par16==0) fcwSv(ps,pc,"通讯异常中断。", gstRV.bmpError); 
   else if(Par32==254) fcwSv(ps,pc, "对方电话关机。", gstRV.bmpError); 
 
   //播放提示声音 
   if(Par16==0) PSound(g_GJ.pSErr, FALSE); 
   else if(Par32==254) PSound(g_GJ.pSErr, FALSE); 
   else PSound(g_GJ.pSTck, FALSE); 
 
   //输出通话记录 
   otrPrintPID(gstFV.dwIP, gstFV.wPort); 
   wsprintf(g_pTmp, "[通话记录]  %s  时间:%d点%d分%d秒。", gstMV.sTmp, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, gstFV.stTime.wSecond); 
   logOutCommlog(g_pTmp, FALSE); 
   wsprintf(g_pTmp, "            主叫标志:%s叫  通话时长:%d秒。", 
      gstFV.bPasi?"被":"主", (DWORD)(GetTickCount()-gstFV.dwTick)/1000); 
   logOutCommlog(g_pTmp, TRUE); 
 
   //输出事件记录 
   GetLocalTime(&gstFV.stTime); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 通话结束。结束代码:%d/%d。", 
      gstFV.stTime.wYear, gstFV.stTime.wMonth, gstFV.stTime.wDay, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, Par16, Par32); 
   logOutEventlog(g_pTmp, TRUE); 
   return; 
} 
 
//KPNM_ASK消息处理过程 
//参数: hWnd   主窗口句柄 
//      Par16  16bit消息参数 
//      Par32  32bit消息参数 
static void _pnwAskKpnm(HWND hWnd, WORD Par16, DWORD Par32) 
{ 
   NOTIFYICONDATA nd; 
   struct in_addr addr; 
   char *pcs; 
   char sPID[8]={0}; 
 
   gstMV.iPhoneWork = KW_ASK; 
   GetLocalTime(&gstFV.stTime); 
   gstFV.dwTick = 0; 
   gstFV.dwIP = Par32; 
   gstFV.wPort = Par16; 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   SetTimer(gstFV.hWndFace, TIMER_COUNT, 1000, NULL); 
 
   //设置按钮状态 
   otrDPhoneBut(); 
   EnableWindow(GetDlgItem(hWnd,TL_ANSW), TRUE); 
   EnableWindow(GetDlgItem(hWnd,TL_REFU), TRUE); 
   if(Par16==0) 
   { 
      gstUD.hWndBeMain = GetDlgItem(hWnd,TL_USER); 
      if(!gstUD.bStart) EnableWindow(gstUD.hWndBeMain, TRUE); 
   } 
 
   //输出事件记录 
   otrPrintPID(gstFV.dwIP, gstFV.wPort); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 来电询问。主叫方%s。", 
      gstFV.stTime.wYear, gstFV.stTime.wMonth, gstFV.stTime.wDay, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, gstMV.sTmp); 
   logOutEventlog(g_pTmp, TRUE); 
 
   //自动拒绝 
   if(gstMV.iAutoMark==1) 
   { 
      if(kpHangUp(HANG_AUTO)==0) 
      { 
         otrPrintPID(gstFV.dwIP, gstFV.wPort); 
         wsprintf(g_pTmp, "[自动拒绝]  %s  时间:%d点%d分%d秒。", gstMV.sTmp, 
            gstFV.stTime.wHour, gstFV.stTime.wMinute, gstFV.stTime.wSecond); 
         logOutCommlog(g_pTmp, TRUE); 
      } 
      return; 
   } 
 
   //自动接听 
   if(gstMV.iAutoMark==2) 
   { 
      kpAnswer(g_IV.uWavePID, g_IV.uWaveRID); 
      return; 
   } 
 
   //播放提示声音 
   PSound(g_GJ.pSRing, TRUE); 
   if(!g_IV.bLostAW) return; 
 
   //处理对方帐号 
   if(Par16==0) 
   { 
      if(ItoC(Par32, sPID)) 
         SetWindowText(GetDlgItem(hWnd,TL_EDIT), sPID); 
   } 
   else 
   { 
      addr.s_addr = Par32; 
      pcs = inet_ntoa(addr); 
      if(pcs!=NULL) 
      { 
         wsprintf(g_pTmp, "%s:%d", pcs, ntohs(Par16)); 
         SetWindowText(GetDlgItem(hWnd,TL_EDIT), g_pTmp); 
      } 
   } 
 
   //弹出窗口 
   if(gstMV.iTaskIcon!=0) 
   { 
      nd.cbSize = sizeof(nd); 
      nd.hWnd = hWnd; 
      nd.uID = 1; 
      Shell_NotifyIcon(NIM_DELETE, &nd); 
      gstMV.iTaskIcon = 0; 
   } 
   if(IsIconic(hWnd)){ ShowWindow(hWnd,SW_HIDE); OpenIcon(hWnd); } 
   #define _SWPN SWP_NOACTIVATE|SWP_NOMOVE|SWP_NOSIZE|SWP_SHOWWINDOW 
   SetWindowPos(hWnd, HWND_TOPMOST, 0,0,0,0, _SWPN); 
   SetWindowPos(hWnd, HWND_NOTOPMOST, 0,0,0,0, _SWPN); 
   #undef _SWPN 
   return; 
} 
 
//KPNM_ASKCANCEL消息处理过程 
//参数: Par16  16bit消息参数 
//      Par32  32bit消息参数 
static void _pnwAskCancelKpnm(WORD Par16, DWORD Par32) 
{ 
   SYSTEMTIME st; 
   gstFV.dwIdleSt = 2; 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   StopSound(); 
   otrPrintPID(gstFV.dwIP, gstFV.wPort); 
   wsprintf(g_pTmp, "[未接来电]  %s  时间:%d点%d分%d秒。", gstMV.sTmp, 
      gstFV.stTime.wHour, gstFV.stTime.wMinute, gstFV.stTime.wSecond); 
   logOutCommlog(g_pTmp, TRUE); 
   GetLocalTime(&st); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 询问取消。取消原因代码:%d/%d。", 
      st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute, Par16, Par32); 
   logOutEventlog(g_pTmp, TRUE); 
   return; 
} 
 
//KPNM_WAVEERR消息处理过程 
//参数: Par16  16bit消息参数 
//      Par32  32bit消息参数 
static void _pnwWaveErrKpnm(WORD Par16, DWORD Par32) 
{ 
   if(Par16==0) 
   { 
      gstFV.bOutWOpen = FALSE; 
      wsprintf(g_pTmp, "打开声音输出设备出错, 错误码:%d。", Par32); 
      logOutEventlog(g_pTmp, TRUE); 
   } 
   else 
   { 
      gstFV.bInWOpen = FALSE; 
      wsprintf(g_pTmp, "打开声音输入设备出错, 错误码:%d。", Par32); 
      logOutEventlog(g_pTmp, TRUE); 
   } 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   return; 
} 
 
//KPNM_FREN消息处理过程 
//参数: Par16  16bit消息参数 
//      Par32  32bit消息参数 
static void _pnwFrenKpnm(WORD Par16, DWORD Par32) 
{ 
   if(Par16==0) 
   { 
      gstFV.byPFren = (BYTE)Par32; 
      fcwUpdateTalkFace(1); 
      if(Par32!=0) return; 
      if(g_IV.wAutoREV==0) return; 
      if((DWORD)(GetTickCount()-gstMV.dwArevTick)<(DWORD)g_IV.wAutoREV*1000) 
         return; 
      kpRestTempi(); 
      gstMV.dwArevTick = GetTickCount(); 
   } 
   else 
   { 
      gstFV.byRFren = (BYTE)Par32; 
      fcwUpdateTalkFace(2); 
   } 
   return; 
} 
 
//KPNM_OFFLINE消息处理过程 
static void _pnwOffLineKpnm(void) 
{ 
   SYSTEMTIME st; 
   HBITMAP hBmp; 
 
   gstMV.iOnLine = 0; 
   InvalidateRect(gstFV.hWndFace, NULL, FALSE); 
   otrModiMenu(); 
   PSoundNs(g_GJ.pSWarn); 
 
   GetLocalTime(&st); 
   wsprintf(g_pTmp, "%d-%d-%d %d:%d 用户离线。*** 请重新登录。", 
      st.wYear, st.wMonth, st.wDay, st.wHour, st.wMinute); 
   logOutEventlog(g_pTmp, TRUE); 
 
   hBmp = LoadBitmap(g_hInst, "Idle2"); 
   if(hBmp==NULL) return; 
   if(gstRV.bmpIdle!=NULL) DeleteObject(gstRV.bmpIdle); 
   gstRV.bmpIdle = hBmp; 
   return; 
} 
 
//WM_KPHONE消息处理函数 
//参数: hWnd   主窗口句柄 
//      wKMsg  K-Phone消息代码 
//      Par16  16bit消息参数 
//      Par32  32bit消息参数 
//返回: 如果处理了消息返回TRUE, 否则返回FALSE。 
static BOOL _pnwKPhoneMes(HWND hWnd, WORD wKMsg, WORD Par16, DWORD Par32) 
{ 
   switch(wKMsg) 
   { 
      case KPNM_ONLINEINFO: 
         if(Par16!=0) onlOnlineInfo((void*)Par32); 
         if(Par32!=0) kpMesFree((void*)Par32); 
         break; 
      case KPNM_GUI: 
         udOutUserData((void*)Par32); 
         if(Par32!=0) kpMesFree((void*)Par32); 
         break; 
      case KPNM_GOU: 
         onlUserList((void*)Par32); 
         if(Par32!=0) kpMesFree((void*)Par32); 
         break; 
      case KPNM_LOGON: 
         if(Par32==0) break; 
         gstMV.stKLInfo = *((kpLOGONINFO*)Par32); 
         kpMesFree((void*)Par32); 
         break; 
      case KPNM_LOGONERROR: _pnwLogonErrorKpnm(hWnd,Par16); break; 
      case KPNM_START: _pnwKStartKpnm(hWnd,Par32); break; 
      case KPNM_IDLE: _pnwIdleKpnm(hWnd); break; 
      case KPNM_CALL: _pnwCallKpnm(hWnd,Par16,Par32); break; 
      case KPNM_ASK: _pnwAskKpnm(hWnd,Par16,Par32); break; 
      case KPNM_TALK: _pnwTalkKpnm(hWnd,Par16,Par32); break; 
      case KPNM_HANGUP: _pnwHangupKpnm(Par32); break; 
      case KPNM_CALLFAIL: _pnwCallFailKpnm(Par16,Par32); break; 
      case KPNM_ASKCANCEL: _pnwAskCancelKpnm(Par16,Par32); break; 
      case KPNM_BUZZOFF: _pnwBuzzoffKpnm(Par16,Par32); break; 
      case KPNM_WAVEERR: _pnwWaveErrKpnm(Par16,Par32); break; 
      case KPNM_FREN: _pnwFrenKpnm(Par16,Par32); break; 
      case KPNM_VSNS: gstFV.bSend=Par32; fcwUpdateTalkFace(4); break; 
      case KPNM_OFFLINE: _pnwOffLineKpnm(); break; 
      case KPNM_GOIFAIL: onlGOiFail(); break; 
      case KPNM_GOUFAIL: onlGOuFail(Par16); break; 
      case KPNM_GUIFAIL: udGUiFail(Par16); break; 
      default: return FALSE; 
   } 
   return TRUE; 
} 
 
//M_MYINFO菜单消息处理过程 
//参数: 主窗口句柄 
static void _pnwMyInfoMenu(HWND h) 
{ 
   HWND hd; 
   HOSTENT *pstHEnt; 
   struct in_addr addr; 
   char *pcs; 
   int i; 
 
   if(gstMV.hWndMyInfo!=NULL) 
      SendDlgItemMessage(gstMV.hWndMyInfo,999, LB_RESETCONTENT,0,0); 
   else 
   { 
      gstMV.hWndMyInfo = CreateDialog(g_hInst,"MyInfo",h,otrMyInfoCallback); 
      if(gstMV.hWndMyInfo==NULL) return; 
   } 
   hd = GetDlgItem(gstMV.hWndMyInfo, 999); 
   if(hd==NULL) return; 
   SendMessage(hd, LB_ADDSTRING, 0, (LPARAM)""); 
 
   #define _adds(s) SendMessage(hd,LB_ADDSTRING,0,(LPARAM)(s)) 
   _adds("用户状态:"); 
   if(g_IV.bStartMd) _adds(" 未登录"); 
   else _adds(gstMV.iOnLine?" 联机":" 离线"); 
   _adds(""); 
 
   if(gstMV.iOnLine) 
   { 
      _adds("用户帐号:"); 
      gstMV.sTmp[7] = 0; 
      ItoC(gstMV.stKLInfo.dwPID, gstMV.sTmp); 
      wsprintf(g_pTmp," %s", gstMV.sTmp); 
      _adds(g_pTmp); _adds(""); 
 
      _adds("呼叫验证码:"); 
      wsprintf(g_pTmp," %d", gstMV.stKLInfo.wUVID); 
      _adds(g_pTmp); _adds(""); 
 
      _adds("上次登录时间:"); _adds(" 0000-00-00 00:00 *"); _adds(""); 
      _adds("上次登录IP:"); _adds(" 0.0.0.0 *"); _adds(""); 
 
      _adds("服务器地址:"); 
      addr.s_addr = g_SO.dwSerIP; 
      pcs = inet_ntoa(addr); 
      if(pcs==NULL) pcs="0.0.0.0"; 
      wsprintf(g_pTmp," %s:%d", pcs, SERPORT); 
      _adds(g_pTmp); _adds(""); 
 
      _adds("客户端地址:"); 
      addr.s_addr = gstMV.stKLInfo.ip; 
      pcs = inet_ntoa(addr); 
      if(pcs==NULL) pcs="0.0.0.0"; 
      wsprintf(g_pTmp," %s:%d", pcs, ntohs(gstMV.stKLInfo.port)); 
      _adds(g_pTmp); _adds(""); 
   } 
 
   _adds("本机地址列表:"); 
   gethostname(g_pTmp, sizeof(g_pTmp)); 
   pstHEnt = gethostbyname(g_pTmp); 
   if(pstHEnt==0) 
      _adds(" 127.0.0.1:0 *"); 
   else 
   { 
      for(i=0; i<10; i++) 
      { 
         if(!pstHEnt->h_addr_list[i]) break; 
         addr.s_addr = *((DWORD*)(pstHEnt->h_addr_list[i])); 
         pcs = inet_ntoa(addr); 
         if(pcs==NULL) pcs="0.0.0.0"; 
         wsprintf(g_pTmp," %s:%d", pcs, g_IV.wPort); 
         _adds(g_pTmp); 
      } 
   } 
   _adds(""); 
   #undef _adds 
   return; 
} 
 
//WM_COMMAND消息处理过程 
//参数: hWnd  主窗口句柄 
//      hChw  控制句柄 
//      wBID  控制ID代码 
//      wNCd  控制通报码 
static void _pnwCommandMes(HWND hWnd, HWND hChw, WORD wBID, WORD wNCd) 
{ 
   int iRst; 
   STCALL stc; 
   #define ERRTXT "错误原因: 未知!请报告该错误。***" 
   switch(wBID) 
   { 
   case IDCANCEL: 
      SetWindowText(GetDlgItem(hWnd,TL_EDIT), ""); 
      break; 
   case TL_EDIT: 
      if(wNCd!=EN_SETFOCUS) break; 
      SendDlgItemMessage(hWnd,TL_CALL, BM_SETSTYLE,BUTON_STYLE,_MKINT(1,0)); 
      break; 
   case TL_USER: 
      SendMessage(hChw, BM_SETSTYLE, BUTON_STYLE, _MKINT(1,0)); 
      SetFocus(GetDlgItem(hWnd, TL_EDIT)); 
      udGetUserData(gstFV.dwIP); 
      break; 
   case TL_ANSW: 
      SendMessage(hChw, BM_SETSTYLE, BUTON_STYLE, _MKINT(1,0)); 
      SetFocus(GetDlgItem(hWnd, TL_EDIT)); 
      iRst = kpAnswer(g_IV.uWavePID, g_IV.uWaveRID); 
      if(iRst==0) break; 
      wsprintf(g_pTmp, "kpAnswer()函数调用失败, 错误码:%d。", iRst); 
      logOutEventlog(g_pTmp, FALSE); 
      logOutEventlog(ERRTXT, TRUE); 
      break; 
   case TL_REFU: 
   case TL_HAND: 
      SendMessage(hChw, BM_SETSTYLE, BUTON_STYLE, _MKINT(1,0)); 
      SetFocus(GetDlgItem(hWnd, TL_EDIT)); 
      iRst = kpHangUp(HANG_NULL); 
      if(iRst==0) break; 
      wsprintf(g_pTmp, "kpHangUp()函数调用失败, 错误码:%d。", iRst); 
      logOutEventlog(g_pTmp, FALSE); 
      logOutEventlog(ERRTXT, TRUE); 
      break; 
   case TL_POFF: 
      SendDlgItemMessage(hWnd,TL_CALL, BM_SETSTYLE,BUTON_STYLE,_MKINT(1,0)); 
      if(SendMessage(hChw,BM_GETCHECK,0,0)) gstMV.stKOpt.MOut=1; 
      else gstMV.stKOpt.MOut=0; 
      otrKpSetup(&gstMV.stKOpt); 
      break; 
   case TL_ROFF: 
      SendDlgItemMessage(hWnd,TL_CALL, BM_SETSTYLE,BUTON_STYLE,_MKINT(1,0)); 
      if(SendMessage(hChw,BM_GETCHECK,0,0)) gstMV.stKOpt.MIn=1; 
      else gstMV.stKOpt.MIn=0; 
      otrKpSetup(&gstMV.stKOpt); 
      break; 
   case TL_OPTI: 
      SendDlgItemMessage(hWnd,TL_CALL, BM_SETSTYLE,BUTON_STYLE,_MKINT(1,0)); 
      if(SendMessage(hChw,BM_GETCHECK,0,0)) spdOpenSndoptDlg(hWnd); 
      else if(gstMV.hWndSnd!=NULL) DestroyWindow(gstMV.hWndSnd); 
      break; 
   case TL_QUIE: 
      SendDlgItemMessage(hWnd,TL_CALL, BM_SETSTYLE,BUTON_STYLE,_MKINT(1,0)); 
      g_IV.bRing = !SendMessage(hChw,BM_GETCHECK,0,0); 
      break; 
   case TL_REST: 
      SendMessage(hChw, BM_SETSTYLE, BUTON_STYLE, _MKINT(1,0)); 
      SetFocus(GetDlgItem(hWnd, TL_EDIT)); 
      kpRestTempi(); 
      gstMV.dwArevTick = GetTickCount(); 
      break; 
   case TL_CALL: 
      SendMessage(hChw, BM_SETSTYLE, BUTON_STYLE, _MKINT(1,0)); 
      GetWindowText(GetDlgItem(hWnd,TL_EDIT), g_pTmp, 28); 
      if(g_pTmp[0]==0){ warOpen(strCALLPIDERR); break; } 
      iRst = CtoST(&stc, g_pTmp); 
      if(iRst==2) stc.Port=htons(5002); 
      if(iRst==0){ warOpen(strCALLERRPID); break; } 
      iRst = kpCall(stc.IP,stc.Port,stc.UVD, 0, g_IV.uWavePID,g_IV.uWaveRID); 
      if(iRst==0) break; 
      wsprintf(g_pTmp, "kpCall()函数调用失败, 错误码:%d。", iRst); 
      logOutEventlog(g_pTmp, FALSE); 
      if(iRst==10) 
      { 
         if(g_IV.bStartMd) warOpen(strCALLIPT); else warOpen(strCALLONL); 
         logOutEventlog("错误原因: IP模式或离线状态时不支持用户号码呼叫。",1); 
      } 
      else{ warOpen(strCALLERROR); logOutEventlog(ERRTXT,TRUE); } 
      break; 
   case M_MYINFO: 
      _pnwMyInfoMenu(hWnd); 
      break; 
   case M_USERDATA: 
      udOpenSetupUserData(); 
      break; 
   case M_ONLIST: 
      onlOpen(hWnd); 
      break; 
   case M_TURNDOWN: 
      gstMV.iAutoMark = (gstMV.iAutoMark==1?0:1); 
      otrModiMenu(); 
      break; 
   case M_AUTOMATA: 
      gstMV.iAutoMark = (gstMV.iAutoMark==2?0:2); 
      otrModiMenu(); 
      break; 
   case M_HIDE: 
      g_IV.bLieup = !g_IV.bLieup; 
      kpLstate((BYTE)(g_IV.bLieup?0:255)); 
      otrModiMenu(); 
      break; 
   case M_RELOGON: 
      DestroyWindow(hWnd); 
      gstMV.iReturnVar = 0; 
      break; 
   case M_EXIT: 
      DestroyWindow(hWnd); 
      break; 
   case M_BOOK: 
      wsprintf(g_pTmp, strBOOKTEXT, URLNAME); 
      warOpen(g_pTmp); 
      break; 
   case M_LOG: 
      logOpenLog(); 
      break; 
   case M_SNDVOL: 
      ShellExecute(0,0, "sndvol32.exe", 0,0, SW_SHOW); 
      break; 
   case M_SAVE: 
      g_SO.bAvaiINI = WriteIniFile(&g_IV); 
      if(g_SO.bAvaiINI) warOpen(strSAVESUCCED); 
      else warOpen(strSAVEERROR); 
      otrModiMenu(); 
      break; 
   case M_OPTIONS: 
      setOpen(hWnd); 
      break; 
   case M_MAINHELP: 
      ShellExecute(0,0, HLP_INDEX, 0,0, SW_SHOW); 
      break; 
   case M_WEB: 
      ShellExecute(0,0, HLP_MYHOME, 0,0, SW_SHOW); 
      break; 
   case M_EMAIL: 
      ShellExecute(0,0, HLP_EMAIL, 0,0, SW_SHOW); 
      break; 
   case M_ABOUT: 
      if(gstMV.hWndAbout!=NULL) break; 
      gstMV.hWndAbout = CreateDialog(g_hInst,"About",hWnd,otrAboutCallback); 
      break; 
   } 
   #undef ERRTXT 
   return; 
} 
 
//WM_DESTROY消息处理过程 
//参数: hWnd  主窗口句柄 
static void _pnwDestroyMes(HWND hWnd) 
{ 
   NOTIFYICONDATA nd = {0}; 
   if(gstMV.iTaskIcon!=0) 
   { 
      nd.cbSize = sizeof(nd); 
      nd.hWnd = hWnd; 
      nd.uID = 1; 
      Shell_NotifyIcon(NIM_DELETE, &nd); 
   } 
   if(hWnd==gstMV.hWndMain) PostQuitMessage(0); 
   return; 
} 
 
//WM_TSICON消息处理过程 
static void _pnwTsiconMes(HWND hWnd, WPARAM wParam, LPARAM lParam) 
{ 
   NOTIFYICONDATA nd; 
   RECT rtWin; 
   APPBARDATA stAPD; 
 
   if(gstMV.iTaskIcon==0) return; 
   if(wParam!=1) return; 
   if(lParam!=WM_LBUTTONUP && lParam!=WM_RBUTTONUP) return; 
 
   GetWindowRect(hWnd, &rtWin); 
   stAPD.cbSize = sizeof(APPBARDATA); 
   SHAppBarMessage(ABM_GETTASKBARPOS, &stAPD); 
   switch(stAPD.uEdge) 
   { 
      case ABE_TOP: 
      case ABE_BOTTOM: 
         stAPD.rc.right = stAPD.rc.right - 20; 
         stAPD.rc.left = stAPD.rc.right - 50; 
         break; 
      case ABE_LEFT: 
      case ABE_RIGHT: 
         stAPD.rc.top = stAPD.rc.bottom - 24; 
         break; 
   } 
   DrawAnimatedRects(hWnd, 3, &stAPD.rc, &rtWin); 
   ShowWindow(hWnd, SW_SHOW); 
 
   nd.cbSize = sizeof(NOTIFYICONDATA); 
   nd.hWnd = hWnd; 
   nd.uID = 1; 
   Shell_NotifyIcon(NIM_DELETE, &nd); 
   gstMV.iTaskIcon = 0; 
   return; 
} 
 
//WM_SYSCOMMAND消息处理函数 
//返回: 处理该消息返回TRUE, 否则返回FALSE。 
static BOOL _pnwSyscommandMes(HWND hWnd, WPARAM wParam, LPARAM lParam) 
{ 
   NOTIFYICONDATA nd; 
   RECT rtWin; 
   APPBARDATA stAPD; 
 
   if(!g_IV.bTrayIco) return FALSE; 
   if((wParam&0xFFF0)!=SC_MINIMIZE) return FALSE; 
   if(lParam==0) return FALSE; 
   if(!IsWindowVisible(hWnd)) return FALSE; 
   if(IsIconic(hWnd)) return FALSE; 
 
   GetWindowRect(hWnd, &rtWin); 
   stAPD.cbSize = sizeof(APPBARDATA); 
   SHAppBarMessage(ABM_GETTASKBARPOS, &stAPD); 
 
   switch(stAPD.uEdge) 
   { 
      case ABE_TOP: 
      case ABE_BOTTOM: 
         stAPD.rc.right = stAPD.rc.right - 20; 
         stAPD.rc.left = stAPD.rc.right - 50; 
         break; 
      case ABE_LEFT: 
      case ABE_RIGHT: 
         stAPD.rc.top = stAPD.rc.bottom - 24; 
         break; 
      default: 
         return FALSE; 
   } 
 
   DrawAnimatedRects(hWnd, 3, &rtWin, &stAPD.rc); 
   ShowWindow(hWnd, SW_HIDE); 
 
   ZeroMemory(&nd, sizeof(nd)); 
   nd.cbSize = sizeof(NOTIFYICONDATA); 
   nd.hWnd = hWnd; 
   nd.uID = 1; 
   nd.uFlags = NIF_ICON|NIF_MESSAGE|NIF_TIP; 
   nd.uCallbackMessage = WM_TSICON; 
   nd.hIcon = g_GJ.hIconS; 
   CopyMemory(nd.szTip,"大蚂蚁网络电话", 14); 
   if(Shell_NotifyIcon(NIM_ADD, &nd)) 
      gstMV.iTaskIcon = 1; 
   else 
   { 
      DrawAnimatedRects(hWnd, 3, &stAPD.rc, &rtWin); 
      ShowWindow(hWnd, SW_SHOW); 
   } 
   return TRUE; 
} 
 
//主窗口回调函数 
static LRESULT CALLBACK pnwCallback(HWND h, UINT u, WPARAM w, LPARAM l) 
{ 
   switch(u) 
   { 
      case WM_CREATE: 
         if(!_pnwStartKPhone(h)) return -1; 
         if(!_pnwCreateCortrol(h)) return -1; 
         break; 
      case WM_KPHONE: 
         if(!_pnwKPhoneMes(h,HIWORD(w),LOWORD(w),l)) kpDefmesProc(w,l); 
         break; 
      case WM_ACTIVATE: 
         SendDlgItemMessage(h,TL_CALL, BM_SETSTYLE,BUTON_STYLE,_MKINT(1,0)); 
         if(LOWORD(w)==WA_INACTIVE) break; 
         if(HIWORD(w)) break; 
         SetFocus(GetDlgItem(h, TL_EDIT)); 
         break; 
      case WM_TSICON: 
         _pnwTsiconMes(h, w, l); 
         break; 
      case WM_SYSCOMMAND: 
         if(!_pnwSyscommandMes(h,w,l)) 
            return(DefWindowProc(h,u,w,l)); 
         break; 
      case WM_COMMAND: 
         _pnwCommandMes(h, (HWND)l, LOWORD(w), HIWORD(w)); 
         break; 
      case WM_QUERYENDSESSION: 
         kpEnd(); 
         DestroyWindow(h); 
         StopSound(); 
         return 1; 
      case WM_DESTROY: 
         _pnwDestroyMes(h); 
         break; 
      default: 
         return(DefWindowProc(h,u,w,l)); 
   } 
   return 0; 
} 
 
/* =-=-=-=-=-=-=-=-=-=-=-=-=-=> 
模块: Main模块(main) 
说明: 过程初始化和清扫工作处理模块。 
<=-=-=-=-=-=-=-=-=-=-=-=-=-= */ 
 
//过程初始化 
//返回: 成功返回TRUE, 失败返回FALSE。 
static BOOL _mainInitialize(void) 
{ 
   WNDCLASS WndClass; 
 
   //注册主窗口类 
   WndClass.lpszClassName = gcpMainClass; 
   WndClass.hInstance     = g_hInst; 
   WndClass.lpfnWndProc   = pnwCallback; 
   WndClass.hCursor       = LoadCursor(NULL, IDC_ARROW); 
   WndClass.hIcon         = g_GJ.hIconB; 
   WndClass.lpszMenuName  = "MainMenu"; 
   WndClass.hbrBackground = (HBRUSH)(COLOR_BTNFACE+1); 
   WndClass.style         = CS_NOCLOSE; 
   WndClass.cbClsExtra    = 0; 
   WndClass.cbWndExtra    = 0; 
   gstMV.atomMain = RegisterClass(&WndClass); 
   if(gstMV.atomMain==0) 
   { 
      gstMV.pErrText = "注册窗口类失败! (PhoneMain) "; 
      return FALSE; 
   } 
 
   //注册子窗口类 
   WndClass.lpszClassName = gcpFaceClass; 
   WndClass.hInstance     = g_hInst; 
   WndClass.lpfnWndProc   = fcwCallback; 
   WndClass.hCursor       = LoadCursor(NULL, MAKEINTRESOURCE(32649)); 
   WndClass.hIcon         = NULL; 
   WndClass.lpszMenuName  = NULL; 
   WndClass.hbrBackground = GetStockObject(NULL_BRUSH); 
   WndClass.style         = 0; 
   WndClass.cbClsExtra    = 0; 
   WndClass.cbWndExtra    = 0; 
   gstMV.atomFace = RegisterClass(&WndClass); 
   if(gstMV.atomFace==0) 
   { 
      gstMV.pErrText = "注册窗口类失败! (PhoneFace) "; 
      return FALSE; 
   } 
 
   //初始化K-Phone音频控制结构变量 
   if(g_IV.dwDefMT==0) 
   { 
      gstMV.stKOpt.VIn      = g_IV.stOptM.VIn; 
      gstMV.stKOpt.CompMode = g_IV.stOptM.CompMode; 
      gstMV.stKOpt.NorIn    = g_IV.stOptM.NorIn; 
   } 
   else 
   { 
      gstMV.stKOpt.VIn      = g_IV.stOptT.VIn; 
      gstMV.stKOpt.CompMode = g_IV.stOptT.CompMode; 
      gstMV.stKOpt.NorIn    = g_IV.stOptT.NorIn; 
   } 
   gstMV.stKOpt.AgcOut   = g_IV.optAgc; 
   gstMV.stKOpt.SndDelay = g_IV.optDelay; 
   gstMV.stKOpt.DecpMode = 1; 
   gstMV.stKOpt.Vsns     = 1; 
   gstMV.stKOpt.Fren     = 1; 
 
   //加载位图资源 
   if(g_IV.bStartMd) gstRV.bmpIdle = LoadBitmap(g_hInst, "Idle2"); 
   else gstRV.bmpIdle = LoadBitmap(g_hInst, "Idle1"); 
   gstRV.bmpAsk   = LoadBitmap(g_hInst, "Ask"); 
   gstRV.bmpAskX  = LoadBitmap(g_hInst, "AskX"); 
   gstRV.bmpCall  = LoadBitmap(g_hInst, "Call"); 
   gstRV.bmpCallX = LoadBitmap(g_hInst, "CallX"); 
   gstRV.bmpError = LoadBitmap(g_hInst, "Error"); 
   gstRV.bmpHang  = LoadBitmap(g_hInst, "Hang"); 
   gstRV.bmpTalk  = LoadBitmap(g_hInst, "Talk"); 
   gstRV.bmpTks   = LoadBitmap(g_hInst, "Tks"); 
   gstRV.bmpTkv   = LoadBitmap(g_hInst, "Tkv"); 
 
   //创建主窗口 
   gstMV.hWndMain = CreateWindowEx(0, gcpMainClass, "DmyNP", 
       PNWIN_STYLE, 0, 0, 187, 218, NULL, 0, g_hInst, NULL); 
   if(gstMV.hWndMain==NULL) 
   { 
      if(gstMV.pErrText==NULL) 
         gstMV.pErrText = "创建窗口失败! (MainWindow) "; 
      return FALSE; 
   } 
 
   if(g_IV.bLowPRI) 
      SetPriorityClass(GetCurrentProcess(), IDLE_PRIORITY_CLASS); 
   return TRUE; 
} 
 
//过程清扫操作 
static void _mainClear(void) 
{ 
   if(gstRV.bmpIdle!=NULL) DeleteObject(gstRV.bmpIdle); 
   if(gstRV.bmpAsk!=NULL) DeleteObject(gstRV.bmpAsk); 
   if(gstRV.bmpAskX!=NULL) DeleteObject(gstRV.bmpAskX); 
   if(gstRV.bmpCall!=NULL) DeleteObject(gstRV.bmpCall); 
   if(gstRV.bmpCallX!=NULL) DeleteObject(gstRV.bmpCallX); 
   if(gstRV.bmpError!=NULL) DeleteObject(gstRV.bmpError); 
   if(gstRV.bmpHang!=NULL) DeleteObject(gstRV.bmpHang); 
   if(gstRV.bmpTalk!=NULL) DeleteObject(gstRV.bmpTalk); 
   if(gstRV.bmpTks!=NULL) DeleteObject(gstRV.bmpTks); 
   if(gstRV.bmpTkv!=NULL) DeleteObject(gstRV.bmpTkv); 
   if(gstMV.atomMain!=0) UnregisterClass(gcpMainClass, g_hInst); 
   if(gstMV.atomFace!=0) UnregisterClass(gcpFaceClass, g_hInst); 
   SetPriorityClass(GetCurrentProcess(), NORMAL_PRIORITY_CLASS); 
   StopSound(); 
   kpEnd(); 
   return; 
} 
 
//Phone处理过程入口函数 
//返回: 重新登录返回0, 退出返回-1。 
int PhoneMain(void) 
{ 
   MSG msg; 
 
   ZeroMemory(&gstMV, sizeof(gstMV)); 
   ZeroMemory(&gstFV, sizeof(gstFV)); 
   ZeroMemory(&gstUD, sizeof(gstUD)); 
   ZeroMemory(&gstRV, sizeof(gstRV)); 
   gstMV.iReturnVar = -1; 
 
   if(_mainInitialize()) 
   { 
      while(GetMessage(&msg,NULL,0,0)) 
      { 
      if(IsDialogMessage(gstMV.hWndMain,&msg)) continue; 
      if(IsDialogMessage(gstMV.hWndLog,&msg)) continue; 
      if(gstMV.hWndWarn && IsDialogMessage(gstMV.hWndWarn,&msg)) continue; 
      if(gstMV.hWndSetup && IsDialogMessage(gstMV.hWndSetup,&msg)) continue; 
      if(gstMV.hWndSnd && IsDialogMessage(gstMV.hWndSnd,&msg)) continue; 
      if(gstMV.hWndOnLine && IsDialogMessage(gstMV.hWndOnLine,&msg)) continue; 
      if(gstUD.hWndUDSet && IsDialogMessage(gstUD.hWndUDSet,&msg)) continue; 
      if(gstUD.hWndUDRed && IsDialogMessage(gstUD.hWndUDRed,&msg)) continue; 
      TranslateMessage(&msg); 
      DispatchMessage(&msg); 
      } 
   } 
 
   _mainClear(); 
 
   if(gstMV.pErrText!=NULL) 
   { 
      if(gstMV.iReturnVar!=0) PromptError(gstMV.pErrText); 
      else MessageBox(0, gstMV.pErrText, "DmyNP", MB_ICONWARNING); 
   } 
 
   return gstMV.iReturnVar; 
}