C++Builder Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
C++빌더 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
메신저 프로젝트
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
볼랜드포럼 광고 모집

C++빌더 Q&A
C++Builder Programming Q&A
[6050] Re:[질문, 긴급] 화상및 음성 전송을 위한 Win32 Api에 관한 질문.
방태윤 [] 5072 읽음    2001-03-12 22:10
음 아래는 제가 잠깐 시간을 내서 했던건데요
생업에 시달려 더이상 진전을 못하고 팽게쳐 놨던 겁니다.
대충 돌아가지만 완벽하지도 않았고 제대로 한건지도
스스로 의심이 가는 그런 소스입니다.
컴포넌트는 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루 해야 할거같은데.. 관련 자료를 가지고 계신분.. 있으면..
: 좀 정보좀 주세영.. ㅡㅡ; 헐헐 아님 컴퍼넌트라두....헐헐.. ~~
:
: ---- 아름다운 청년 제라툴 ----

+ -

관련 글 리스트
6048 [질문, 긴급] 화상및 음성 전송을 위한 Win32 Api에 관한 질문. 제라툴 2791 2001/03/12
6050     Re:[질문, 긴급] 화상및 음성 전송을 위한 Win32 Api에 관한 질문. 방태윤 5072 2001/03/12
6057         Re:Re:[질문, 긴급] 화상및 음성 전송을 위한 Win32 Api에 관한 질문. 제라툴 2557 2001/03/12
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.