|
음 아래는 제가 잠깐 시간을 내서 했던건데요
생업에 시달려 더이상 진전을 못하고 팽게쳐 놨던 겁니다.
대충 돌아가지만 완벽하지도 않았고 제대로 한건지도
스스로 의심이 가는 그런 소스입니다.
컴포넌트는 UDP 를 쓴겁니다.
화상입력받는 방법이나 음성입출등의 개념이 맞는지는 모르지만
참고하셔서 좋은 프로그램 만들어 보세요.
이외에 폼이 몇개있는데 그냥단순한 입력폼일뿐입니다.
//---------------------------------------------------------------------------
#ifndef F1vs1H
#define F1vs1H
//---------------------------------------------------------------------------
#include <Classes.hpp>
#include <Controls.hpp>
#include <StdCtrls.hpp>
#include <Forms.hpp>
#include <Menus.hpp>
#include <ComCtrls.hpp>
#include <ExtCtrls.hpp>
#include <ImgList.hpp>
//---------------------------------------------------------------------------
#include <NMUDP.hpp>
#include <mmsystem.h>
#include <vfw.h>
#include <jpeg.hpp>
#include <ScktComp.hpp>
#define BUFFER_SIZE 2000
class TF_1vs1 : public TForm
{
__published: // IDE-managed Components
TMainMenu *MainMenu1;
TMenuItem *MAIN1;
TMenuItem *N1;
TMenuItem *N2;
TMenuItem *N3;
TMenuItem *N4;
TMenuItem *N5;
TMenuItem *N6;
TMenuItem *N7;
TMenuItem *N10;
TMenuItem *N11;
TMenuItem *N12;
TMenuItem *N13;
TMenuItem *N14;
TMenuItem *N15;
TMenuItem *N16;
TMenuItem *N17;
TMenuItem *N18;
TMenuItem *N160X1201;
TMenuItem *N320X2401;
TMenuItem *N280X2101;
TMenuItem *N320X2402;
TMenuItem *N19;
TMenuItem *N20;
TPanel *Panel1;
TStatusBar *StatusBar1;
TImageList *ImageList1;
TTimer *VideoTimer;
TNMUDP *VideoSendUdp;
TMenuItem *N200X1501;
TServerSocket *ServerSocket;
TClientSocket *ClientSocket;
TNMUDP *VideoReceiveUdp;
TPaintBox *pb;
TNMUDP *AudioSendUdp;
TNMUDP *AudioReceiveUdp;
TLabel *Label1;
TMemo *Memo1;
TMemo *Memo2;
void __fastcall N280X2101Click(TObject *Sender);
void __fastcall N160X1201Click(TObject *Sender);
void __fastcall N320X2401Click(TObject *Sender);
void __fastcall N320X2402Click(TObject *Sender);
void __fastcall N11Click(TObject *Sender);
void __fastcall FormShow(TObject *Sender);
void __fastcall VideoTimerTimer(TObject *Sender);
void __fastcall FormClose(TObject *Sender, TCloseAction &Action);
void __fastcall N200X1501Click(TObject *Sender);
void __fastcall N12Click(TObject *Sender);
void __fastcall N13Click(TObject *Sender);
void __fastcall ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall N14Click(TObject *Sender);
void __fastcall ClientSocketRead(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall ServerSocketClientConnect(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall N20Click(TObject *Sender);
void __fastcall ServerSocketClientRead(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall N4Click(TObject *Sender);
void __fastcall N6Click(TObject *Sender);
void __fastcall N3Click(TObject *Sender);
void __fastcall N5Click(TObject *Sender);
void __fastcall VideoReceiveUdpDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port);
void __fastcall AudioReceiveUdpDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port);
void __fastcall ServerSocketClientDisconnect(TObject *Sender,
TCustomWinSocket *Socket);
void __fastcall ClientSocketDisconnect(TObject *Sender,
TCustomWinSocket *Socket);
private: // User declarations
static bool pascal FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr);
bool FrameCallbackHelp(HWND hWnd, LPVIDEOHDR lpVHdr);
void __fastcall VideoInit();
void __fastcall VideoInitConnect();
void __fastcall ChangeVideoSize();
void __fastcall FreeVideoInit();
int __fastcall TF_1vs1::ConnectSever_1();
int __fastcall TF_1vs1::ConnectSever_2();
void __fastcall OnMMWimData(TMessage &Msg);
void __fastcall OnMMWomDone(TMessage &Msg);
void __fastcall TF_1vs1::InitWaveIn();
void __fastcall TF_1vs1::InitWaveOut();
public: // User declarations
void __fastcall TF_1vs1::ViewMyWindow();
//=============================================
//=============================================
__fastcall TF_1vs1(TComponent* Owner);
BEGIN_MESSAGE_MAP
MESSAGE_HANDLER(MM_WOM_DONE,TMessage,OnMMWomDone)
MESSAGE_HANDLER(MM_WIM_DATA,TMessage,OnMMWimData)
END_MESSAGE_MAP(TForm)
};
//---------------------------------------------------------------------------
extern PACKAGE TF_1vs1 *F_1vs1;
//---------------------------------------------------------------------------
#endif
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "_1vs1.h"
#include "MyWindow.h"
#include "inputbox.h"
#include "ConnectWindow.h"
#include "Chat.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TF_1vs1 *F_1vs1;
#define NO_CONNECT 0
#define I_AM_SERVER 1
#define I_AM_CLIENT 2
int ConState;
int XSize;
int YSize;
bool IsVideo;
bool IsAudio;
bool SendVideo;
bool ReceiveVideo;
bool SendAudio;
bool ReceiveAudio;
bool ViewMyVideo=false;
//audio
WAVEFORMATEX WaveFormat;
HWAVEIN WaveInHandle;
WAVEHDR WaveInHeader;
HWAVEOUT WaveOutHandle;
WAVEHDR WaveOutHeader;
unsigned char WaveInBuf[BUFFER_SIZE];
unsigned char WaveOutBuf[BUFFER_SIZE];
//video
HWND hWndC;
BITMAPINFO bmpi;
CAPDRIVERCAPS dcaps;
Graphics::TBitmap*TmSendVideoBmp;
TMemoryStream*TmSendVideoMStream;
TJPEGImage*TmpSendJpg;
Graphics::TBitmap*TmReceiveVideoBmp;
TMemoryStream*TmReceiveVideoMStream;
TJPEGImage*TmpReceiveJpg;
unsigned char VideoBuffer[2048*4];
int VideoBufferNo=0;
//tcp
AnsiString HostAddress;
//event
CRITICAL_SECTION CS;
// InitializeCriticalSection(&CS);
// EnterCriticalSection(&CS);
// LeaveCriticalSection(&CS);
HANDLE HConOkEvent; //연결성공
HANDLE HConFailEvent; //연결실패
HANDLE HCancelEvent; //유저캔슬
HANDLE HWOutEvent; //wav out;
//thread
#define QUE_SIZE 8
class CSendAudioThread : public TThread
{
private:
void __fastcall Execute();
void __fastcall ExecuteSub();
public:
__fastcall CSendAudioThread();
__fastcall ~CSendAudioThread(){};
};
class CReceiveAudioThread : public TThread
{
private:
void __fastcall Execute();
void __fastcall ExecuteSub();
public:
__fastcall CReceiveAudioThread();
__fastcall ~CReceiveAudioThread(){};
};
CSendAudioThread*SendAudioTr;
CReceiveAudioThread*ReceiveAudioTr;
unsigned char WaveInBufQue[QUE_SIZE][BUFFER_SIZE];
unsigned char WaveOutBufQue[QUE_SIZE][BUFFER_SIZE];
int InNextPos=0;
int InPrevPos=0;
int OutNextPos=0;
int OutPrevPos=0;
__fastcall CSendAudioThread::CSendAudioThread():TThread(false)
{
}
void __fastcall CSendAudioThread::ExecuteSub()
{
if(InNextPos!=InPrevPos){
unsigned char*p=WaveInBufQue[InPrevPos];
//send audio
switch(ConState)
{
case NO_CONNECT:
return;
case I_AM_SERVER:
F_1vs1->AudioSendUdp->RemoteHost=F_1vs1->ServerSocket->Socket->Connections[0]->RemoteAddress;
break;
case I_AM_CLIENT:
F_1vs1->AudioSendUdp->RemoteHost=HostAddress;
break;
}
try
{
int sum=0;
for(int i=0;i<BUFFER_SIZE;i++){
if(p[i]<100||p[i]>156){
sum += p[i];
}
}
if(sum>1000){
F_1vs1->AudioSendUdp->SendBuffer(p,BUFFER_SIZE,BUFFER_SIZE);
F_1vs1->Memo1->Lines->Add(Time().FormatString("nn:ss")+" audio send("+AnsiString(InPrevPos)+")("+AnsiString(InNextPos)+")("+AnsiString(sum)+")");
}
}
catch(...)
{
}
InPrevPos++;
InPrevPos%=QUE_SIZE;
}
}
void __fastcall CSendAudioThread::Execute()
{
while(!Terminated)
{
if(SendAudio){
Synchronize(ExecuteSub);
}
}
}
__fastcall CReceiveAudioThread::CReceiveAudioThread():TThread(false)
{
}
void __fastcall CReceiveAudioThread::ExecuteSub()
{
if(OutNextPos!=OutPrevPos){
WaitForSingleObject(HWOutEvent,1000);
WaveOutHeader.lpData=WaveOutBufQue[OutPrevPos%QUE_SIZE];
OutPrevPos++;
OutPrevPos%=QUE_SIZE;
WaveOutHeader.dwBufferLength=BUFFER_SIZE;
WaveOutHeader.dwFlags=0L;
WaveOutHeader.dwLoops=0L;
waveOutPrepareHeader(WaveOutHandle,&WaveOutHeader,sizeof(WAVEHDR));
waveOutWrite(WaveOutHandle,&WaveOutHeader,sizeof(WAVEHDR));
}
}
void __fastcall CReceiveAudioThread::Execute()
{
while(!Terminated)
{
if(ReceiveAudio){
Synchronize(ExecuteSub);
}
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::InitWaveIn()
{
WaveFormat.wFormatTag=WAVE_FORMAT_PCM;
WaveFormat.nChannels=1;
WaveFormat.nSamplesPerSec=8000L;
WaveFormat.nAvgBytesPerSec=8000L;
WaveFormat.nBlockAlign=1;
WaveFormat.wBitsPerSample=8;
WaveFormat.cbSize=0;
WaveInHeader.lpData=WaveInBuf;
WaveInHeader.dwBufferLength=BUFFER_SIZE;
WaveInHeader.dwFlags=0L;
WaveInHeader.dwLoops=0L;
if(waveInOpen(&WaveInHandle,WAVE_MAPPER,&WaveFormat,(DWORD)Handle,0,CALLBACK_WINDOW) != MMSYSERR_NOERROR){
IsAudio=false;
ShowMessage("err waveInOpen");
}
//start thread
InNextPos=0;
InPrevPos=0;
SendAudioTr = new CSendAudioThread();
}
void __fastcall TF_1vs1::InitWaveOut()
{
WaveFormat.wFormatTag=WAVE_FORMAT_PCM;
WaveFormat.nChannels=1;
WaveFormat.nSamplesPerSec=8000L;
WaveFormat.nAvgBytesPerSec=8000L;
WaveFormat.nBlockAlign=1;
WaveFormat.wBitsPerSample=8;
WaveFormat.cbSize=0;
if(waveOutOpen(&WaveOutHandle,WAVE_MAPPER,&WaveFormat,(DWORD)Handle,0,CALLBACK_WINDOW) != MMSYSERR_NOERROR){
IsAudio=false;
ShowMessage("err waveOutOpen");
}
OutNextPos=0;
OutPrevPos=0;
ReceiveAudioTr=new CReceiveAudioThread();
}
//---------------------------------------------------------------------------
__fastcall TF_1vs1::TF_1vs1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
bool pascal TF_1vs1::FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)
{
return F_1vs1->FrameCallbackHelp(hWnd,lpVHdr);
}
bool TF_1vs1::FrameCallbackHelp(HWND hWnd, LPVIDEOHDR lpVHdr)
{
if(!IsVideo) return false;
if(ViewMyVideo||SendVideo){
SetDIBitsToDevice(TmSendVideoBmp->Canvas->Handle,
0,0,bmpi.bmiHeader.biWidth,bmpi.bmiHeader.biHeight,
0,0,0,bmpi.bmiHeader.biHeight,
lpVHdr->lpData, &bmpi, DIB_RGB_COLORS);
}
if(SendVideo){
TmpSendJpg->Assign(TmSendVideoBmp);
TmpSendJpg->SaveToStream(TmSendVideoMStream);
TmSendVideoMStream->Position=0;
int c_size,size=TmSendVideoMStream->Size;
unsigned char*p=(unsigned char*)TmSendVideoMStream->Memory;
while(size>0)
{
c_size=(size>=2048?2048:size);
try
{
switch(ConState)
{
case NO_CONNECT:
break;
case I_AM_SERVER:
VideoSendUdp->RemoteHost=ServerSocket->Socket->Connections[0]->RemoteAddress;
VideoSendUdp->SendBuffer(p,c_size,c_size);
Memo2->Lines->Add(Time().FormatString("nn:ss")+" video send");
break;
case I_AM_CLIENT:
VideoSendUdp->RemoteHost=HostAddress;
VideoSendUdp->SendBuffer(p,c_size,c_size);
Memo2->Lines->Add(Time().FormatString("nn:ss")+" video send");
break;
}
}
catch(...)
{
}
size-=c_size;
if(!size){
break;
}
p+=c_size;
}
}
if(ViewMyVideo&&FMyWindow->Visible){
SetDIBitsToDevice(FMyWindow->pb->Canvas->Handle,
0,0,bmpi.bmiHeader.biWidth,bmpi.bmiHeader.biHeight,
0,0,0,bmpi.bmiHeader.biHeight,
lpVHdr->lpData, &bmpi, DIB_RGB_COLORS);
}
return true;
}
void __fastcall TF_1vs1::VideoInit()
{
hWndC=capCreateCaptureWindow("...",WS_CHILD,0,0,1,1,Handle,1);
VideoInitConnect();
}
void __fastcall TF_1vs1::VideoInitConnect()
{
bool test=capDriverConnect(hWndC,0);
if(!test){
ShowMessage("err in capDriverConnect");
IsVideo=false;
}else{
int s=capGetVideoFormatSize(hWndC);
capGetVideoFormat(hWndC,&bmpi,s);
bmpi.bmiHeader.biWidth=XSize;
bmpi.bmiHeader.biHeight=YSize;
bmpi.bmiHeader.biBitCount=16;
bmpi.bmiHeader.biSizeImage=bmpi.bmiHeader.biWidth*bmpi.bmiHeader.biHeight*bmpi.bmiHeader.biBitCount/8;
capSetVideoFormat(hWndC,&bmpi,s);
capSetCallbackOnFrame(hWndC,FrameCallbackProc);
capOverlay(hWndC,false);
capPreview(hWndC,false);
IsVideo=true;
TmSendVideoBmp=new Graphics::TBitmap();
TmSendVideoMStream=new TMemoryStream();
TmReceiveVideoMStream=new TMemoryStream();
TmReceiveVideoBmp=new Graphics::TBitmap();
TmSendVideoBmp->Width=XSize;
TmSendVideoBmp->Height=YSize;
TmReceiveVideoBmp->Width=XSize;
TmReceiveVideoBmp->Height=YSize;
TmpSendJpg=new TJPEGImage();
TmpReceiveJpg=new TJPEGImage();
TmpSendJpg->CompressionQuality=50;
TmpReceiveJpg->CompressionQuality=50;
}
}
void __fastcall TF_1vs1::FreeVideoInit()
{
IsVideo=false;
capSetCallbackOnFrame(hWndC,NULL);
capDriverDisconnect(hWndC);
delete TmSendVideoBmp;
delete TmReceiveVideoBmp;
delete TmReceiveVideoMStream;
delete TmpSendJpg;
delete TmpReceiveJpg;
}
void __fastcall TF_1vs1::ChangeVideoSize()
{
bool re_open=false;
if(FMyWindow->Visible){
re_open=true;
FMyWindow->Close();
}
FreeVideoInit();
VideoInitConnect();
if(re_open){
ViewMyWindow();
}
}
void __fastcall TF_1vs1::N280X2101Click(TObject *Sender)
{
N280X2101->Checked=true;
XSize=280;
YSize=210;
ChangeVideoSize();
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N160X1201Click(TObject *Sender)
{
N160X1201->Checked=true;
XSize=160;
YSize=120;
ChangeVideoSize();
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N320X2401Click(TObject *Sender)
{
N320X2401->Checked=true;
XSize=240;
YSize=180;
ChangeVideoSize();
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N200X1501Click(TObject *Sender)
{
N200X1501->Checked=true;
XSize=200;
YSize=150;
ChangeVideoSize();
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N320X2402Click(TObject *Sender)
{
N320X2402->Checked=true;
XSize=320;
YSize=240;
ChangeVideoSize();
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::ViewMyWindow()
{
ViewMyVideo=true;
FMyWindow->Width=XSize+10;
FMyWindow->Height=YSize+19;
FMyWindow->Show();
}
void __fastcall TF_1vs1::N11Click(TObject *Sender)
{
ViewMyWindow();
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::FormShow(TObject *Sender)
{
XSize=160;
YSize=120;
ConState=NO_CONNECT;
SendVideo=false;
ReceiveVideo=false;
SendAudio=false;
ReceiveAudio=false;
ViewMyVideo=false;
ClientSocket->Active=false;
ServerSocket->Active=true;
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::VideoTimerTimer(TObject *Sender)
{
if(IsVideo&&(ViewMyVideo||SendVideo)){
capGrabFrame(hWndC);
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::FormClose(TObject *Sender, TCloseAction &Action)
{
FreeVideoInit();
}
//---------------------------------------------------------------------------
int __fastcall TF_1vs1::ConnectSever_1()
{
//연결을 확립한다.
if(ClientSocket->Active){
ClientSocket->Active=false;
}
FConnectWindow=new TFConnectWindow(this);
int res=FConnectWindow->ShowModal();
HostAddress=FConnectWindow->Edit1->Text.Trim();
delete FConnectWindow;
if(res!=mrOk){
return 0;
}
HConOkEvent=CreateEvent(0,true,false,0);
HConFailEvent=CreateEvent(0,true,false,0);
HCancelEvent=CreateEvent(0,true,false,0);
ClientSocket->Host=HostAddress;
ClientSocket->Open();
DWORD re;
bool loop_flag=true; //event 를 기다린다
int con_state=0;
int st=GetTickCount();
while(loop_flag)
{
Application->ProcessMessages();
re=WaitForSingleObject(HConOkEvent,100);
switch(re)
{
case WAIT_FAILED:
break;
case WAIT_OBJECT_0: // connection established
loop_flag=false;
con_state=1;
break;
case WAIT_TIMEOUT:
break;
}
re=WaitForSingleObject(HConFailEvent,100);
switch(re)
{
case WAIT_FAILED:
break;
case WAIT_OBJECT_0: // fail
loop_flag=false;
con_state=2;
break;
case WAIT_TIMEOUT:
break;
}
re=WaitForSingleObject(HCancelEvent,100);
switch(re)
{
case WAIT_FAILED:
break;
case WAIT_OBJECT_0: // user click cancel
loop_flag=false;
con_state=3;
break;
case WAIT_TIMEOUT:
break;
}
if(GetTickCount()-st>20000){ //after 20 sec
loop_flag=false;
con_state=4; //time out
}
}
CloseHandle(HConOkEvent);
CloseHandle(HConFailEvent);
CloseHandle(HCancelEvent);
return con_state;
}
int __fastcall TF_1vs1::ConnectSever_2()
{
//this is connected state
HConOkEvent=CreateEvent(0,true,false,0);
HConFailEvent=CreateEvent(0,true,false,0);
HCancelEvent=CreateEvent(0,true,false,0);
DWORD re;
bool loop_flag=true; //event 를 기다린다
int con_state=0;
int st=GetTickCount();
ClientSocket->Socket->SendText("COMMAND:CONNECT");
while(loop_flag)
{
Application->ProcessMessages();
re=WaitForSingleObject(HConOkEvent,100);
switch(re)
{
case WAIT_FAILED:
break;
case WAIT_OBJECT_0: // connection established
loop_flag=false;
con_state=1;
break;
case WAIT_TIMEOUT:
break;
}
re=WaitForSingleObject(HConFailEvent,100);
switch(re)
{
case WAIT_FAILED:
break;
case WAIT_OBJECT_0: // use deny connect
loop_flag=false;
con_state=2;
break;
case WAIT_TIMEOUT:
break;
}
re=WaitForSingleObject(HCancelEvent,100);
switch(re)
{
case WAIT_FAILED:
break;
case WAIT_OBJECT_0: // user click cancel
loop_flag=false;
con_state=3;
break;
case WAIT_TIMEOUT:
break;
}
if(GetTickCount()-st>30000){ //after 30 sec
loop_flag=false;
con_state=4; //time out
}
}
CloseHandle(HConOkEvent);
CloseHandle(HConFailEvent);
CloseHandle(HCancelEvent);
return con_state;
}
void __fastcall TF_1vs1::N12Click(TObject *Sender)
{
int re;
ConState=NO_CONNECT;
re=ConnectSever_1();
switch(re)
{
case 0:
// ShowMessage("use cancel");
break;
case 1:
// ShowMessage("con ok");
break;
case 2:
// ShowMessage("con fail");
break;
case 3:
// ShowMessage("user click cancel");
break;
case 4:
ShowMessage("연결 에러 time out");
break;
default:
break;
}
if(re!=1){
return;
}
re=ConnectSever_2();
switch(re)
{
case 1:
// ShowMessage("accepte ok");
break;
case 2:
ShowMessage("수신자가 연결을 거부 하였습니다.");
break;
case 3:
// ShowMessage("con user cancel");
break;
case 4:
ShowMessage("연결 에러 time out");
break;
default:
break;
}
if(re!=1){
ClientSocket->Close();
return;
}
ConState=I_AM_CLIENT;
// connect completed
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N13Click(TObject *Sender)
{
ClientSocket->Active=false;
ServerSocket->Active=true;
SendVideo=false;
ReceiveVideo=false;
SendAudio=false;
ReceiveAudio=false;
ViewMyVideo=false;
ConState=NO_CONNECT;
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::ClientSocketConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
SetEvent(HConOkEvent);
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N14Click(TObject *Sender)
{
SetEvent(HCancelEvent);
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::ClientSocketRead(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString r;
r=Socket->ReceiveText().Trim();
if(r=="COMMAND:CONNECT"){
SetEvent(HConOkEvent);
return;
}
if(r=="COMMAND:DISCONNECT"){
SetEvent(HConFailEvent);
return;
}
if(r=="COMMAND:CHAT"){
FChat->Show();
return;
}
FChat->Memo1->Lines->Add(r);
}
//---------------------------------------------------------------------------
AnsiString __fastcall _MsgBox(AnsiString msg,AnsiString flag)
{
UINT f=0;
if(flag.Pos("ync")){
f|=MB_YESNOCANCEL;
}else if(flag.Pos("yn")){
f|=MB_YESNO;
}else if(flag.Pos("oc")){
f|=MB_OKCANCEL;
}else if(flag.Pos("o")){
f|=MB_OK;
}
if(flag.Pos("?")){
f|=MB_ICONQUESTION;
}else if(flag.Pos("!")){
f|=MB_ICONASTERISK;
}
int ret=Application->MessageBox(msg.c_str(),"",f);
switch(ret)
{
case IDCANCEL:
return "c";
case IDNO:
return "n";
case IDOK:
return "o";
case IDYES:
return "y";
default:
return "";
}
}
void __fastcall TF_1vs1::ServerSocketClientConnect(TObject *Sender,
TCustomWinSocket *Socket)
{
if(_MsgBox(Socket->RemoteHost.Trim()+"("+Socket->RemoteAddress.Trim()+") 의 연결 요청입니다.\n연결 하시겠습니까?","yn?")=="y"){
Socket->SendText("COMMAND:CONNECT");
ConState=I_AM_SERVER;
}else{
Socket->SendText("COMMAND:DISCONNECT");
ConState=NO_CONNECT;
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N20Click(TObject *Sender)
{
switch(ConState)
{
case NO_CONNECT:
break;
case I_AM_SERVER:
FChat->Show();
ServerSocket->Socket->Connections[0]->SendText("COMMAND:CHAT");
break;
case I_AM_CLIENT:
FChat->Show();
ClientSocket->Socket->SendText("COMMAND:CHAT");
break;
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::ServerSocketClientRead(TObject *Sender,
TCustomWinSocket *Socket)
{
AnsiString s=Socket->ReceiveText().Trim();
if(s=="COMMAND:CHAT"){
FChat->Show();
return;
}
FChat->Memo1->Lines->Add(s);
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N4Click(TObject *Sender)
{
N4->Checked=!N4->Checked;
SendAudio=N4->Checked;
if(SendAudio){
InitWaveIn();
waveInPrepareHeader(WaveInHandle,&WaveInHeader,sizeof(WAVEHDR));
waveInAddBuffer(WaveInHandle,&WaveInHeader,sizeof(WAVEHDR));
if(waveInStart(WaveInHandle)!=MMSYSERR_NOERROR){
ShowMessage("error");
}
}else{
waveInStop(WaveInHandle);
waveInUnprepareHeader(WaveInHandle,&WaveInHeader,sizeof(WAVEHDR));
waveInReset(WaveInHandle);
waveInClose(WaveInHandle);
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N6Click(TObject *Sender)
{
N6->Checked=!N6->Checked;
ReceiveAudio=N6->Checked;
if(ReceiveAudio){
InitWaveOut();
HWOutEvent=CreateEvent(NULL,true,true,0);
}else{
for(int i=0;i<4;i++){
SetEvent(HWOutEvent);
}
waveOutUnprepareHeader(WaveOutHandle,&WaveOutHeader,sizeof(WAVEHDR));
waveOutReset(WaveOutHandle);
waveOutClose(WaveOutHandle);
WaveOutHandle=0;
CloseHandle(HWOutEvent);
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N3Click(TObject *Sender)
{
N3->Checked=!N3->Checked;
SendVideo=N3->Checked;
if(SendVideo){
VideoInit();
}else{
FreeVideoInit();
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::N5Click(TObject *Sender)
{
N5->Checked=!N5->Checked;
ReceiveVideo=N5->Checked;
VideoBufferNo=0;
if(ReceiveVideo){
}else{
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::VideoReceiveUdpDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port)
{
if(!ReceiveVideo){
return;
}
int readen;
if(NumberBytes==2048){
VideoReceiveUdp->ReadBuffer(VideoBuffer+2048*VideoBufferNo,2048,readen);
VideoBufferNo++;
if(VideoBufferNo>7){
VideoBufferNo=7;
}
}else{
VideoReceiveUdp->ReadBuffer(VideoBuffer+2048*VideoBufferNo,NumberBytes,readen);
TmReceiveVideoMStream->Position=0;
TmReceiveVideoMStream->WriteBuffer(VideoBuffer,2048*VideoBufferNo+NumberBytes);
VideoBufferNo=0;
TmReceiveVideoMStream->Position=0;
try
{
TmpReceiveJpg->LoadFromStream(TmReceiveVideoMStream);
pb->Canvas->Draw(0,0,TmpReceiveJpg);
}
catch(...)
{
}
}
Memo2->Lines->Add(Time().FormatString("nn:ss")+" video receive");
if(Memo2->Lines->Count>200){
Memo1->Lines->Clear();
Memo2->Lines->Clear();
}
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::AudioReceiveUdpDataReceived(TComponent *Sender,
int NumberBytes, AnsiString FromIP, int Port)
{
if(!WaveOutHandle) return;
int readen;
AudioReceiveUdp->ReadBuffer(WaveOutBufQue[OutNextPos],BUFFER_SIZE,readen);
OutNextPos++;
OutNextPos%=QUE_SIZE;
Memo1->Lines->Add(Time().FormatString("nn:ss")+" audio receive");
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::OnMMWimData(TMessage &Msg)
{
if(!SendAudio){
return;
}
unsigned char p[BUFFER_SIZE];
LPWAVEHDR lphdr=(LPWAVEHDR)Msg.LParam;
waveInUnprepareHeader((HWAVEIN)Msg.WParam,lphdr,sizeof(WAVEHDR));
CopyMemory(WaveInBufQue[InNextPos],lphdr->lpData,BUFFER_SIZE);
waveInPrepareHeader(WaveInHandle,lphdr,sizeof(WAVEHDR));
waveInAddBuffer(WaveInHandle,lphdr,sizeof(WAVEHDR));
InNextPos++;
InNextPos%=QUE_SIZE;
}
void __fastcall TF_1vs1::OnMMWomDone(TMessage &Msg)
{
SetEvent(HWOutEvent);
}
void __fastcall TF_1vs1::ServerSocketClientDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
ConState=NO_CONNECT;
ShowMessage("상대방과 연결이 해제 되었습니다.");
}
//---------------------------------------------------------------------------
void __fastcall TF_1vs1::ClientSocketDisconnect(TObject *Sender,
TCustomWinSocket *Socket)
{
ConState=NO_CONNECT;
ShowMessage("상대방과 연결이 해제 되었습니다.");
}
//---------------------------------------------------------------------------
제라툴 님이 쓰신 글 :
: 화상전송을 Win32 Api를 통해서 가능할거라 생각하는데..
: 좋은 자료를 알고 계신분 계십니까.?? ㅡㅡ;
: MFC의 CSocket을 통해서 전송할수도 없고...또한 빌더 컴퍼넌트를 사용
: 해서 한다구 해두.. 힘들거 같구..
:
: 직접 전송해야될거같은데.. 우선 소켓은.. 그냥.. DataGram 소켓만들어서 한다구해두..
: 화상을 전송할려면.. JPEG등으로 압축을해야되는데.. ㅡㅡ;
: 또 화상을 입력받을수 있는 루틴도 필요할꺼구영..
: (Video for Windows 나 MCI 아님 Direct show를 사용하면 될거 같긴한데.. 해본적이 없어서...)
:
: 제 생각에는 Win32 Api루 해야 할거같은데.. 관련 자료를 가지고 계신분.. 있으면..
: 좀 정보좀 주세영.. ㅡㅡ; 헐헐 아님 컴퍼넌트라두....헐헐.. ~~
:
: ---- 아름다운 청년 제라툴 ----
|