#include "../systeminc/version.h" #include "../systeminc/talkwindow.h" #include "../systeminc/main.h" #include "../resource.h" #include "../systeminc/loadrealbin.h" #include "../oft/work.h" #include "../systeminc/font.h" #include "../systeminc/mouse.h" #include "../systeminc/tool.h" #ifdef _TALK_WINDOW int g_iCursorCount = -1; extern HFONT hFont; #ifdef _CHANNEL_MODIFY extern char g_szChannelTitle[][13]; extern int TalkMode; #endif CTalkWindow::CTalkWindow() {}; CTalkWindow::~CTalkWindow() { Release(); }; void CTalkWindow::Init(HWND hWnd,HINSTANCE hInstance) { int i; ChatBufferLink *pCBL; m_hdcBackBuffer = 0; m_hbmpOldBackBuffer = 0; m_hbmpBackBuffer = 0; m_bScroll = FALSE; m_bUpArrowHit = FALSE; m_bDownArrowHit = FALSE; m_bInit = FALSE; m_hTalkWindow = NULL; m_hWnd = hWnd; m_hInstance = hInstance; m_iline = 0; for(i=0;inext = (ChatBufferLink*)MALLOC(sizeof(ChatBufferLink)); if(pCBL == NULL){ MessageBoxNew(hWnd,TEXT("CTalkWindow::Init()记忆体配置失败(2)!!"),TEXT("确定"),MB_OK); Release(); return; } memset(pCBL->next,0,sizeof(ChatBufferLink)); pCBL->next->prev = pCBL; pCBL = pCBL->next; } pCBL->next = NULL; m_pCBLTail = pCBL; m_bInit = TRUE; LoadSkin("data\\skin\\default"); #ifdef _STONDEBUG_ m_iSymbolCount = 0; memset(m_fsFaceSymbol,0,sizeof(m_fsFaceSymbol)); memset(m_ssStoreSymbol,0,sizeof(m_ssStoreSymbol)); ReadFaceSymbolFile(); #endif }; void CTalkWindow::Release(void) { ChatBufferLink *pCBL = m_pCBLHead,*pCBLTemp; for(int i=0;inext){ if(pCBL->next->next){ pCBLTemp = pCBL->next->next; FREE(pCBL->next); pCBL->next = pCBLTemp; } else FREE(pCBL->next); } } FREE(m_pCBLHead); #ifdef _STONDEBUG_ ReleaseFaceSymbol(); #endif }; void CTalkWindow::Create() { RECT rect; WNDCLASS wndclass; if(!m_bInit) return; if(m_hTalkWindow){ ShowWindow(m_hTalkWindow,SW_SHOW); SetFocus(hWnd); return; } wndclass.style = CS_OWNDC; wndclass.lpfnWndProc = TalkWindowProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; wndclass.hInstance = m_hInstance; wndclass.hIcon = NULL; wndclass.hCursor = LoadCursor(m_hInstance ,MAKEINTRESOURCE(SA_MOUSE1)); wndclass.hbrBackground = (HBRUSH)GetStockObject(BLACK_BRUSH); wndclass.lpszMenuName= NULL; wndclass.lpszClassName = "TALK"; RegisterClass(&wndclass); GetWindowRect(hWnd,&rect); m_hTalkWindow = CreateWindow("TALK","TalkWIndow",WS_OVERLAPPED, rect.left,rect.top + rect.bottom, SKIN_WIDTH,SKIN_HEIGHT,hWnd,NULL,m_hInstance,NULL); if(m_hTalkWindow){ DWORD dwStyle; HRGN hRegion; ShowWindow(m_hTalkWindow,SW_SHOW); UpdateWindow(m_hTalkWindow); hRegion = CreateRectRgn(0,0,SKIN_WIDTH,SKIN_HEIGHT+GetSystemMetrics(SM_CYSIZE)+GetSystemMetrics(SM_CXFIXEDFRAME)); SetWindowRgn(m_hTalkWindow,hRegion,true); DeleteObject(hRegion); dwStyle = GetWindowLong(m_hTalkWindow,GWL_STYLE); dwStyle &= ~(WS_CAPTION|WS_SIZEBOX); SetWindowLong(m_hTalkWindow,GWL_STYLE,dwStyle); InvalidateRect(m_hTalkWindow,NULL,TRUE); SetWindowPos(m_hTalkWindow,NULL,0,0,SKIN_WIDTH,SKIN_HEIGHT+GetSystemMetrics(SM_CYSIZE),SWP_NOMOVE|SWP_NOZORDER); SetTimer(m_hTalkWindow,1,500,(TIMERPROC)NULL); TalkWindow.Update(); SetFocus(hWnd); } } void CTalkWindow::Update() { if(g_bTalkWindow) SendMessage(m_hTalkWindow,WM_UPDATE_SKIN,0,0); } void CTalkWindow::LoadSkin(char *szSkinPath) { char szFileName[5][32] = { "\\base.bmp","\\up_arrow_g.bmp","\\up_arrow_r.bmp","\\down_arrow_g.bmp","\\down_arrow_r.bmp"}; char szTemp[128]; // 读入skin的图 for(int i=0;iChatBuffer.buffer); #endif color = pCBL->ChatBuffer.color; if(pCBL->bUse){ SetTextColor(m_hdcBackBuffer,0); TextOut(m_hdcBackBuffer,TALK_WINDOW_SXO + 1,TALK_WINDOW_SYO + 1 + j * 18,szBuffer,(int)strlen(szBuffer)); SetTextColor(m_hdcBackBuffer,FontPal[color]); TextOut(m_hdcBackBuffer,TALK_WINDOW_SXO,TALK_WINDOW_SYO + j * 18,szBuffer,(int)strlen(szBuffer)); j++; } } if(pCBL->next == NULL) pCBL = m_pCBLHead; else pCBL = pCBL->next; } // 显示输入的文字 strcpy(szBuffer,MyChatBuffer.buffer); color = MyChatBuffer.color; SetTextColor(m_hdcBackBuffer,0); #ifdef _CHANNEL_MODIFY TextOut(m_hdcBackBuffer,TALK_WINDOW_SXI - 25,TALK_WINDOW_SYI+1,g_szChannelTitle[TalkMode],(int)strlen(g_szChannelTitle[TalkMode])); // 显示频道 #endif TextOut(m_hdcBackBuffer,TALK_WINDOW_SXI + 1,TALK_WINDOW_SYI + 1,szBuffer,(int)strlen(szBuffer)); SetTextColor(m_hdcBackBuffer,FontPal[color]); #ifdef _CHANNEL_MODIFY TextOut(m_hdcBackBuffer,TALK_WINDOW_SXI - 26,TALK_WINDOW_SYI,g_szChannelTitle[TalkMode],(int)strlen(g_szChannelTitle[TalkMode])); // 显示频道 #endif TextOut(m_hdcBackBuffer,TALK_WINDOW_SXI,TALK_WINDOW_SYI,szBuffer,(int)strlen(szBuffer)); // 显示游标 if(bShowCursor){ int x; x = TALK_WINDOW_SXI + MyChatBuffer.cursor * (FONT_SIZE>>1); SetTextColor(m_hdcBackBuffer,0); TextOut(m_hdcBackBuffer,x + 1,TALK_WINDOW_SYI + 1,"_",1); SetTextColor(m_hdcBackBuffer,FontPal[color]); TextOut(m_hdcBackBuffer,x,TALK_WINDOW_SYI,"_",1); } SelectObject(m_hdcBackBuffer,hOldFont); #ifdef _STONDEBUG_ ShowFaceSymbol(); #endif // draw to window dc hdc = GetDC(m_hTalkWindow); BitBlt(hdc,0,0,SKIN_WIDTH,SKIN_HEIGHT,m_hdcBackBuffer,0,0,SRCCOPY); ReleaseDC(m_hTalkWindow,hdc); } void CTalkWindow::AddString(char *szString,int color) { if(m_hTalkWindow){ // 游戏一开始没字串,所以要先把 m_iline 累加到 MAX_TALK_WINDOW_LINE 才进行显示框的移动 if(m_iline <= MAX_TALK_WINDOW_LINE) m_iline++; strcpy(m_pCBLString->ChatBuffer.buffer,szString); m_pCBLString->ChatBuffer.color = color; m_pCBLString->bUse = TRUE; // 游戏一开始都没有字串,所以要当 m_iline 值大于等于 MAX_TALK_WINDOW_LINE 时才进行显示框的移动 // 正处于卷动状态时不进行显示框的移动 if(!m_bScroll && m_iline > MAX_TALK_WINDOW_LINE){ if(m_pCBLView->next != NULL) m_pCBLView = m_pCBLView->next; else m_pCBLView = m_pCBLHead; } // 不处于卷动状态时进行显示框的移动 if(!m_bScroll){ if(m_pCBLViewBottom->next != NULL) m_pCBLViewBottom = m_pCBLViewBottom->next; else m_pCBLViewBottom = m_pCBLHead; } // 当 m_pCBLString->next 时,表示已到 list 尾,指回 list 头 if(m_pCBLString->next == NULL) m_pCBLString = m_pCBLHead; else m_pCBLString = m_pCBLString->next; } } // 上卷 void CTalkWindow::UpArrowHit(BOOL bHit) { m_bUpArrowHit = bHit; if(bHit){ m_bScroll = FALSE; // 若 m_pCBLView 和 m_pCBLString 不相等,表示目前显示范围还没超过 m_pCBLString if(m_pCBLView != m_pCBLString){ // 若 m_pCBLView->prev 为 NULL,表示上卷到底了 if(m_pCBLView->prev == NULL){ // 若list尾部有在使用的话,把 m_pCBLView 指向 m_pCBLTail if(m_pCBLTail->bUse){ m_pCBLView = m_pCBLTail; m_bScroll = TRUE; m_pCBLViewBottom = m_pCBLViewBottom->prev; // 移动显示框 if(m_pCBLViewBottom == NULL) m_pCBLViewBottom = m_pCBLTail; } } // 未卷到底 else if(m_pCBLView->prev->bUse){ m_pCBLView = m_pCBLView->prev; m_bScroll = TRUE; m_pCBLViewBottom = m_pCBLViewBottom->prev; if(m_pCBLViewBottom == NULL) m_pCBLViewBottom = m_pCBLTail; } } } } // 下卷 void CTalkWindow::DownArrowHit(BOOL bHit) { m_bDownArrowHit = bHit; if(bHit){ m_bScroll = FALSE; // 若 m_pCBLViewBottom 和 m_pCBLString 不相等,表示目前显示范围还没超过 m_pCBLString if(m_pCBLViewBottom != m_pCBLString){ // 若 m_pCBLView->next 为 NULL,表示下卷到底了 if(m_pCBLView->next == NULL){ // 若list尾部有在使用的话,把 m_pCBLView 指向 m_pCBLHead if(m_pCBLTail->bUse){ m_pCBLView = m_pCBLHead; m_bScroll = TRUE; m_pCBLViewBottom = m_pCBLViewBottom->next; // 移动显示框 if(m_pCBLViewBottom == NULL) m_pCBLViewBottom = m_pCBLHead; } } // 未卷到底 else if(m_pCBLView->next->bUse){ m_pCBLView = m_pCBLView->next; m_bScroll = TRUE; m_pCBLViewBottom = m_pCBLViewBottom->next; if(m_pCBLViewBottom == NULL) m_pCBLViewBottom = m_pCBLHead; } } } } void CTalkWindow::ClearChatBuffer(void) { ChatBufferLink *pCBL = m_pCBLHead; while(pCBL != NULL){ memset(&pCBL->ChatBuffer,0,sizeof(CHAT_BUFFER)); pCBL->bUse = FALSE; pCBL = pCBL->next; } m_pCBLView = m_pCBLViewBottom = m_pCBLString = m_pCBLHead; m_iline = 0; } void CTalkWindow::Visible(BOOL flag) { ShowWindow(m_hTalkWindow,SW_HIDE); ::ClearChatBuffer(); } #ifdef _STONDEBUG_ void CTalkWindow::ReadFaceSymbolFile(void) { FILE *pfFaceSymbolFile = NULL; char szReadBuffer[32]; int iStrlen; fopen_s(&pfFaceSymbolFile,"data\\facesymbol.ini","r"); if(pfFaceSymbolFile){ for(int i=0;iChatBuffer.buffer,sizeof(szSourString)); memset(szTemp,0,sizeof(szTemp)); iStrlen = strlen(szSourString); for(int i=0;i>1)) > 610){ if(pCBL->next != NULL){ sprintf_s(szTemp,"%s%s",&szSourString[iStoreX],pCBL->next->ChatBuffer.buffer); sprintf_s(pCBL->next->ChatBuffer.buffer,"%s",szTemp); }else{ sprintf_s(szTemp,"%s%s",&szSourString[iStoreX],m_pCBLHead->ChatBuffer.buffer); sprintf_s(m_pCBLHead->ChatBuffer.buffer,"%s",szTemp); } // 把原先的字串分离成二行 memcpy(szTemp,szSourString,iStoreX); sprintf_s(szSourString,"%s",szTemp); sprintf_s(pCBL->ChatBuffer.buffer,"%s",szTemp); // 设定 i 为 STR_BUFFER_SIZE + 1 是为了直接离开 i 那层 loop i = STR_BUFFER_SIZE + 1; bBreak = TRUE; break; } szDestString[iCount++] = ' '; szDestString[iCount++] = ' '; szDestString[iCount++] = ' '; // 记录要在那个位置显示表情符号 m_ssStoreSymbol[m_iSymbolCount].bUse = TRUE; m_ssStoreSymbol[m_iSymbolCount].hDraw = m_fsFaceSymbol[j].hDraw; m_ssStoreSymbol[m_iSymbolCount].hDrawMask = m_fsFaceSymbol[j].hDrawMask; m_ssStoreSymbol[m_iSymbolCount].x = x + (iStoreX + iSymbolNum) * (FONT_SIZE>>1); m_ssStoreSymbol[m_iSymbolCount].y = y; m_iSymbolCount++; bBreak = TRUE; iSymbolNum++; break; } i++; } else{ i = iStoreX; break; } } } //if(bBreak) break; } if(j == FACE_SYMBOL_NUM){ szDestString[iCount++] = szSourString[iStoreX]; } } szDestString[iCount] = '\0'; } void CTalkWindow::ShowFaceSymbol(void) { SetTextColor(m_hdcBackBuffer,0); for(int i=0;icnt = 0; pNowStrBuffer->buffer[0] = NULL; } }else KeyboardBackSpace(); break; case VK_DELETE: TalkWindow.ClearChatBuffer(); break; case VK_CONTROL: if(di_key[DIK_V] & 0x80) GetClipboad(); break; case VK_V: if(GetKeyState(VK_CONTROL) & 0xff00) GetClipboad(); break; case VK_UP: joy_auto[0] |= JOY_UP; ChatProc(); break; case VK_DOWN: joy_auto[0] |= JOY_DOWN; ChatProc(); break; } TalkWindow.Update(); break; case WM_CHAR: StockStrBufferChar((char)wParam); break; case WM_TIMER: bShowCursor = !bShowCursor; TalkWindow.DrawSkin(bShowCursor); break; case WM_PAINT: BeginPaint(hWnd,&ps); EndPaint(hWnd,&ps); case WM_UPDATE_SKIN: TalkWindow.DrawSkin(bShowCursor); break; case WM_MOVE: RECT rect; GetWindowRect(::hWnd,&rect); SetWindowPos(hWnd,NULL,rect.left,rect.bottom,0,0,SWP_NOZORDER|SWP_NOSIZE); break; case WM_LBUTTONDOWN: if(MAKEPOINTS(lParam).x >= 620 && MAKEPOINTS(lParam).x <= 638 && MAKEPOINTS(lParam).y >= 8 && MAKEPOINTS(lParam).y <= 26){ TalkWindow.UpArrowHit(TRUE); TalkWindow.DrawSkin(bShowCursor); } if(MAKEPOINTS(lParam).x >= 620 && MAKEPOINTS(lParam).x <= 638 && MAKEPOINTS(lParam).y >= 98 && MAKEPOINTS(lParam).y <= 116){ TalkWindow.DownArrowHit(TRUE); TalkWindow.DrawSkin(bShowCursor); } break; case WM_LBUTTONUP: TalkWindow.UpArrowHit(FALSE); TalkWindow.DownArrowHit(FALSE); TalkWindow.DrawSkin(bShowCursor); break; default: return DefWindowProc( hWnd, Message, wParam, lParam ); } return 0; } #endif