Q&A

  • RS 232 통신에서 data를 전송받았을때 이벤트 발생방법..?
현재 rs-232통신을 위해 commportdrv를 이용하는데 이쪽에서 전송하는것은 성공하였는데

상대쪽 모뎀에서 'connect 19200' 또는 기타 문자를 전송받았을때 이쪽에서 자동으로 어떤 문자를 자동으로 전송하고 싶은데 방법을 모르겠네요. commportdrv.readdata..등을 이용하는거 같기도 한데..초보라서 감을 잘 못잡겠네요

예제같은것이 있으면 좋겠습니다. 좋은 하루 되세요



1  COMMENTS
  • Profile
    김정선 2000.03.14 19:54
    이건 잠시 제가 테스트할려고 만든겁니다..

    조금이나마 도움이 되셨으면 합니다..

    참고로 포트는 Com5, Com6 멀티 포트를 쓰구요. 디비는 엑세스 씁니다.

    그냥 저장만 하는...



    unit uPolling;



    interface



    uses

    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,

    ComCtrls, ToolWin, Grids, StdCtrls, Buttons, ExtCtrls, CPDrv, Db,

    DBTables, Wwquery;



    type

    TfrmPolling = class(TForm)

    stabHint: TStatusBar;

    sgdDisplay: TStringGrid;

    Panel1: TPanel;

    bbtnStop_Polling: TBitBtn;

    bbtnStart_Polling: TBitBtn;

    Label1: TLabel;

    cmbComPort: TComboBox;

    chbCheckSum: TCheckBox;

    Label2: TLabel;

    Label3: TLabel;

    cmbStart_Address: TComboBox;

    cmbEnd_Address: TComboBox;

    bbtnPause_Continue: TBitBtn;

    CommPortDriver: TCommPortDriver;

    tmrPolling: TTimer;

    qryPolling: TwwQuery;

    dtbsPolling: TDatabase;

    Label4: TLabel;

    edtPolling_Interval: TEdit;

    Label5: TLabel;

    procedure FormCreate(Sender: TObject);

    procedure cmbComPortChange(Sender: TObject);

    procedure bbtnStop_PollingClick(Sender: TObject);

    procedure bbtnStart_PollingClick(Sender: TObject);

    procedure bbtnPause_ContinueClick(Sender: TObject);

    procedure FormClose(Sender: TObject; var Action: TCloseAction);

    procedure tmrPollingTimer(Sender: TObject);

    procedure cmbStart_AddressChange(Sender: TObject);

    procedure CommPortDriverReceiveData(Sender: TObject; DataPtr: Pointer;

    DataSize: Cardinal);

    private

    { Private declarations }

    // 수신된 데이터가 프로토콜 포멧에 맞는지 검사한다.

    function Check_Data( Original_Data : String ) : Boolean;

    // 올바르게 수신된 오리지날 데이터를 조작해 디스플레이하고

    // 데이터베이스에 저장한다.

    procedure Handling_Polling_Data( Original_Data : String );

    public

    { Public declarations }

    end;



    var

    frmPolling: TfrmPolling;

    xstrOriginal_Data, xstrRemained_Data, xstrCommPort : string;

    xintBoard_Addr : integer;



    const

    xstrStartbit : String = #1;

    xstrChecksumbit : String = 'CRCT';

    xstrCRbit : String = #13;

    xstrCommand : String = 'V';

    xstrSend_Data : String = 'H';

    xintCount : Integer = 1;



    implementation



    {$R *.DFM}





    // 데이터 송수신시 체크섬을 해서 체크섬 영역에 붙힌다.

    // 체크섬은 Port ID 부터 Send Area 영역까지이다.

    function Check_Sum( Data : string ) : string;

    var

    pstrHexToString, pstrCheck_Sum_Target, pstrHex_Value : string;

    i, pintAscii_Value, pintHex_Value : integer;

    begin

    // 변수를 초기화한다.

    pintAscii_Value := 0;

    pstrHexToString := '';

    pstrCheck_Sum_Target := Data;



    // 문자열을 아스키코드로 변환 후 더함.

    for i := 1 to Length( pstrCheck_Sum_Target ) do

    pintAscii_Value := pintAscii_Value + Ord( pstrCheck_Sum_Target[i] );



    // 아스키코드로 더해 나온 값을 16진수로 변환.

    pstrHex_Value := '0000' + IntToHex( pintAscii_Value, 2 );



    for i := ( Length( pstrHex_Value ) - 3 ) to Length( pstrHex_Value ) do

    begin

    pintHex_Value := StrToInt( '$' + pstrHex_Value[i] ) + $30;

    // 16진수값으로 나온 값을 문자열로 나타낸다.

    pstrHexToString := pstrHexToString + Char( pintHex_Value );

    end;



    // 반환되는 값은 시작비트와 캐리지리턴비트를 모두 붙혀 보낸다.

    Result := #1 + pstrCheck_Sum_Target + pstrHexToString + #13;

    end;





    // 컴포트로 명령을 보낸다.

    procedure Transfer_Command( Board_Addr : integer );

    var

    pstrBoard_Addr, pstrCommand, pstrCheckSum_Target : string;

    begin

    // 보드 어드레스를 두 자릿수 형식으로 만든다.

    if Board_Addr < 10 then

    pstrBoard_Addr := '0' + IntToStr( Board_Addr )

    else

    pstrBoard_Addr := IntToStr( Board_Addr );



    // 주어진 명령( xstrCommand )를 컴포트를 보낸다.

    if frmPolling.CommPortDriver.Connected then

    begin

    // CheckSum 항목 선택에 따라 데이터를 달리 보낸다.

    if frmPolling.chbCheckSum.Checked = True then

    begin

    pstrCheckSum_Target := '01' + pstrBoard_Addr + xstrCommand + xstrSend_Data;

    pstrCommand := Check_Sum( pstrCheckSum_Target );

    end

    // CheckSum을 하지 않는다.

    else

    begin

    pstrCommand := xstrStartbit + '01' + pstrBoard_Addr + xstrCommand +

    xstrSend_Data + xstrChecksumbit + xstrCRbit;

    end;



    frmPolling.CommPortDriver.ContinuePolling;

    frmPolling.CommPortDriver.SendString( pstrCommand );

    end;

    end;





    procedure MessageToStatusbar;

    begin

    // 컴포트가 이미 연결되어 있다면 아무것도 하지 않는다.

    if frmPolling.CommPortDriver.Connect = True then

    frmPolling.stabHint.Panels[0].Text := Copy( frmPolling.CommPortDriver.PortName, 5, Length( frmPolling.CommPortDriver.PortName ) ) + ' ' + 'already connected'

    // 컴포트를 연결한다.

    else if frmPolling.CommPortDriver.Connected = True then

    frmPolling.stabHint.Panels[0].Text := Copy( frmPolling.CommPortDriver.PortName, 5, Length( frmPolling.CommPortDriver.PortName ) ) + ' ' + 'connected'

    // 컴포트 연결을 다시 시도해 연결되지 않으면.

    else if not frmPolling.CommPortDriver.Connect then

    begin

    MessageDlg( 'Could not connect to ' + Copy( frmPolling.CommPortDriver.PortName, 5, Length( frmPolling.CommPortDriver.PortName ) ) + '.'#13#10 +

    'Please, check settings and try again.', mtError, [mbOK], 0 );

    Exit;

    end;

    end;





    // 폼이 생성될 때 그리드를 초기화한다.

    procedure TfrmPolling.FormCreate(Sender: TObject);

    begin

    cmbComPort.Text := CommPortDriver.PortName;

    cmbStart_Address.Text := '01';

    cmbEnd_Address.Text := '01';

    xstrCommPort := cmbComPort.Text;

    dtbsPolling.LoginPrompt := False;

    dtbsPolling.KeepConnection := True;



    sgdDisplay.Cells[ 0, 0 ] := 'Date';

    sgdDisplay.Cells[ 1, 0 ] := 'Time';

    sgdDisplay.Cells[ 2, 0 ] := 'Card Tag';

    sgdDisplay.Cells[ 3, 0 ] := 'Status';

    sgdDisplay.Cells[ 4, 0 ] := 'Controller';

    sgdDisplay.Cells[ 5, 0 ] := 'Reader';

    sgdDisplay.Cells[ 6, 0 ] := 'Original Data';

    sgdDisplay.ColWidths[0] := 70;

    sgdDisplay.ColWidths[1] := 70;

    sgdDisplay.ColWidths[2] := 70;

    sgdDisplay.ColWidths[3] := 80;

    sgdDisplay.ColWidths[4] := 70;

    sgdDisplay.ColWidths[5] := 60;

    sgdDisplay.ColWidths[6] := 550;

    end;





    // 컴포트를 바꾼다.

    procedure TfrmPolling.cmbComPortChange(Sender: TObject);

    begin

    // 포트가 열려있는 상태에서 포트를 바꾸면 에러 메세지를 출력하고

    // 루틴을 빠져나온다.

    if CommPortDriver.Connected = True then

    begin

    MessageDlg( 'You must close the current ' + Copy( CommPortDriver.PortName, 5, Length( frmPolling.CommPortDriver.PortName ) ) + ' port',

    mtInformation, [mbOK], 0 );

    Exit;

    CommPortDriver.Disconnect;

    end;



    // 포트가 닫혀있으면 포트를 바꾼다.

    CommPortDriver.PortName := Trim( cmbComPort.Text );

    end;





    // Stop 버튼을 수행한다. 컴포트를 닫고, 타이머를 멈춘다.

    procedure TfrmPolling.bbtnStop_PollingClick(Sender: TObject);

    begin

    if not CommPortDriver.Connect then

    Exit;



    CommPortDriver.Disconnect;

    tmrPolling.Enabled := False;

    end;





    // Start 버튼을 수행한다. 설정한 컴포트를 연결하고 타이머를 활성화한다.

    procedure TfrmPolling.bbtnStart_PollingClick(Sender: TObject);

    begin

    if CommPortDriver.Connected then

    Exit;

    if not CommPortDriver.Connect then

    begin

    MessageDlg( 'Could not connect to serial port.'#13#10 +

    'Please, check settings and try again.', mtError, [mbOK], 0 );

    Exit;

    end;

    tmrPolling.Interval := StrToInt( edtPolling_Interval.Text );

    tmrPolling.Enabled := True;

    end;





    procedure TfrmPolling.bbtnPause_ContinueClick(Sender: TObject);

    var

    pintI : integer;

    begin

    for pintI := ( xintCount - 1 ) downto sgdDisplay.Row do

    begin

    sgdDisplay.Cells[ 0, pintI ] := '';

    sgdDisplay.Cells[ 1, pintI ] := '';

    sgdDisplay.Cells[ 2, pintI ] := '';

    sgdDisplay.Cells[ 3, pintI ] := '';

    sgdDisplay.Cells[ 4, pintI ] := '';

    sgdDisplay.Cells[ 5, pintI ] := '';

    sgdDisplay.Cells[ 6, pintI ] := '';

    end;

    end;





    // 폼을 종료하면 컴포트를 닫고 타이머를 중지하고 쿼리를 닫는다.

    procedure TfrmPolling.FormClose(Sender: TObject; var Action: TCloseAction);

    begin

    CommPortDriver.Disconnect;

    tmrPolling.Enabled := False;

    qryPolling.Close;

    end;





    procedure TfrmPolling.tmrPollingTimer(Sender: TObject);

    var

    i : integer;

    begin

    i := 0;

    while i = 1000 do

    inc( i );



    // 보드 어드레스를 증가시킨다.

    inc( xintBoard_Addr );

    // 현재 보드 어드레스가 마지막 어드레스를 넘어갈 경우 처음 보드

    // 어드레스로 되돌린다.

    if xintBoard_Addr = ( StrToInt( cmbEnd_Address.Text ) + 1 ) then

    begin

    // 보드 어드레스를 바꾸는 동안 딜레이를 줘 데이터를 다 받는다.

    i := 0;

    while i = 1000 do

    inc( i );



    xintBoard_Addr := StrToInt( cmbStart_Address.Text );

    end;



    // 주어진 컴포트와 보드 어드레스에 따라 명령을 컴포트로 전송한다.

    Transfer_Command( xintBoard_Addr );

    end;





    procedure TfrmPolling.cmbStart_AddressChange(Sender: TObject);

    begin

    xintBoard_Addr := StrToInt( cmbStart_Address.Text );

    end;





    // 컴포트로 데이터가 수신되면 수행한다.

    procedure TfrmPolling.CommPortDriverReceiveData(Sender: TObject;

    DataPtr: Pointer; DataSize: Cardinal);

    var

    pstrBuffer, pstrEndData : String;

    begin

    // 수신된 데이터를 문자열로 변환한다.

    pstrBuffer := StringofChar( ' ', DataSize );

    move( DataPtr^, pchar( pstrBuffer )^, DataSize );





    // 컨트롤러에서 온 데이터 첫 비트와 마지막 비트가 프로토콜의 포멧에 맞으면 그대로 처리한다.

    if ( Copy( pstrBuffer, 1, 1 ) = #1 ) and ( Copy( pstrBuffer, Length( pstrBuffer ), 1 ) = #13 ) then

    xstrOriginal_Data := pstrBuffer

    // 컨트롤러에서 온 데이터 첫 비트만 맞고 마지막 비트가 맞지 않으면 버퍼의 데이터를

    // 전역변수에 저장하고 루틴을 빠져나간다.

    else if ( Pos( #1, pstrBuffer ) <> 0 ) and ( Pos( #13, pstrBuffer ) = 0 ) then

    begin

    xstrOriginal_Data := pstrBuffer;

    Exit;

    end

    // 컨트롤러에서 온 데이터 첫 비트가 없고 마지막 비트만 맞으면 전역변수에 저장된

    // 데이터에 버퍼 데이터를 더한다.

    else if ( Pos( #1, pstrBuffer ) = 0 ) and ( Pos( #13, pstrBuffer ) <> 0 ) then

    xstrOriginal_Data := xstrOriginal_Data + pstrBuffer;



    pstrEndData := xstrOriginal_Data;

    xstrOriginal_Data := '';



    // 폴링된 데이터가 맞는지 검사한다. 맞으면 폴링된 데이터를 조작한다.

    if Check_Data( pstrEndData ) then

    Handling_Polling_Data( pstrEndData );

    end;





    // 폴링된 데이터가 맞으면 True를 반환한다.

    function TfrmPolling.Check_Data;

    var

    pstrStart_ID, pstrCRbit : String;

    begin

    pstrStart_ID := copy( Original_Data, 1, 1 );

    pstrCRbit := copy( Original_Data, Length( Original_Data ), 1 );

    if ( pstrStart_ID = #1 ) and ( pstrCRbit = #13 ) then

    Check_Data := True

    else

    Check_Data := False;

    end;





    // 폴링된 데이터를 조작한다.

    procedure TfrmPolling.Handling_Polling_Data;

    var

    pstrEvent, pstrCard_Tag, pstrStatus, pstrDate, pstrTime,

    pstrDisplay_Status, pstrOri_CardData, pstrBoard_Addr, pstrReader_Addr : String;

    pintI : integer;

    begin

    // 폴링된 데이터에서 이벤트 종류를 알아낸다.

    pstrEvent := copy( Original_Data, 7, 1 );



    Case StrToInt( pstrEvent ) of

    // Normal event

    0 : begin

    // 폴링된 오리지날 데이터를 저장한다.

    pstrOri_CardData := Original_Data;

    pstrCard_Tag := '';

    pstrBoard_Addr := '';

    pstrReader_Addr := '';

    pstrStatus := '';

    pstrDate := '';

    pstrTime := '';

    pstrDisplay_Status := 'No Event'

    end;

    // Card event

    1 : begin

    // 폴링된 데이터에서 카드 번호를 읽어낸다.

    pstrCard_Tag := copy( Original_Data, 9, 8 );

    // if Card_tag's length is lower than 8, don't display and save database.

    if length( pstrCard_Tag ) < 8 then

    Exit;



    // 폴링된 오리지날 데이터를 저장한다.

    pstrOri_CardData := Original_Data;

    // 보드 어드레스를 알아낸다.

    pstrBoard_Addr := copy( Original_Data, 4, 2 );

    // 리더 어드레스를 알아낸다.

    pstrReader_Addr := copy( Original_Data, 8, 1 );

    // 카드에 대한 인가, 비인가등을 알아낸다.

    pstrStatus := copy( Original_Data, 17, 2 );

    // 연도는 시스템 날짜, 달과 날은 폴링된 데이터에서 알아낸다.

    pstrDate := copy( Original_Data, 19, 2 ) + '/' +

    copy( Original_Data, 21, 2 ) + '/' +

    formatdatetime( 'YYYY', Date );

    // 카드 읽은 시간을 알아낸다.

    pstrTime := copy( Original_Data, 23, 2 ) + ':' +

    copy( Original_Data, 25, 2 ) + ':' +

    copy( Original_Data, 27, 2 );



    // 카드에 대한 인가, 비인가 정보에 따라 그리드에 나타낸다.

    if pstrStatus = '00' then

    pstrDisplay_Status := 'Valid ID'

    else if pstrStatus = '01' then

    pstrDisplay_Status := 'Undefined ID'

    else if ( pstrStatus = '10' ) or ( pstrStatus = '20' ) then

    pstrDisplay_Status := 'Invalid ID'

    else if pstrStatus = '11' then

    pstrDisplay_Status := 'Invaiid Time'

    else

    pstrDisplay_Status := 'Unknown Data';

    end;

    // Card event

    2 : begin

    // 폴링된 데이터에서 카드 번호를 읽어낸다.

    pstrCard_Tag := copy( Original_Data, 9, 8 );

    // if Card_tag's length is lower than 8, don't display and save database.

    if length( pstrCard_Tag ) < 8 then

    Exit;



    // 폴링된 오리지날 데이터를 저장한다.

    pstrOri_CardData := Original_Data;

    // 보드 어드레스를 알아낸다.

    pstrBoard_Addr := copy( Original_Data, 4, 2 );

    // 리더 어드레스를 알아낸다.

    pstrReader_Addr := '';

    // 카드에 대한 인가, 비인가등을 알아낸다.

    pstrStatus := copy( Original_Data, 10, 2 );

    // 연도는 시스템 날짜, 달과 날은 폴링된 데이터에서 알아낸다.

    pstrDate := copy( Original_Data, 12, 2 ) + '/' +

    copy( Original_Data, 14, 2 ) + '/' +

    formatdatetime( 'YYYY', Date );

    // 카드 읽은 시간을 알아낸다.

    pstrTime := copy( Original_Data, 16, 2 ) + ':' +

    copy( Original_Data, 18, 2 ) + ':' +

    copy( Original_Data, 20, 2 );



    // 카드에 대한 인가, 비인가 정보에 따라 그리드에 나타낸다.

    if pstrStatus = '00' then

    pstrDisplay_Status := '문열려있음'

    else if pstrStatus = '01' then

    pstrDisplay_Status := '문열림'

    else if ( pstrStatus = '10' ) or ( pstrStatus = '20' ) then

    pstrDisplay_Status := '문강제열림'

    else if pstrStatus = '11' then

    pstrDisplay_Status := '문닫힘'

    else

    pstrDisplay_Status := 'Unknown Data';

    end;

    end;



    // 스트링 그리드에 정보를 디스플레이한다.

    if xintCount > 1 then

    begin

    for pintI := ( xintCount - 1 ) downto sgdDisplay.Row do

    begin

    sgdDisplay.Cells[ 0, pintI + 1 ] := sgdDisplay.Cells[ 0, pintI ];

    sgdDisplay.Cells[ 1, pintI + 1 ] := sgdDisplay.Cells[ 1, pintI ];

    sgdDisplay.Cells[ 2, pintI + 1 ] := sgdDisplay.Cells[ 2, pintI ];

    sgdDisplay.Cells[ 3, pintI + 1 ] := sgdDisplay.Cells[ 3, pintI ];

    sgdDisplay.Cells[ 4, pintI + 1 ] := sgdDisplay.Cells[ 4, pintI ];

    sgdDisplay.Cells[ 5, pintI + 1 ] := sgdDisplay.Cells[ 5, pintI ];

    sgdDisplay.Cells[ 6, pintI + 1 ] := sgdDisplay.Cells[ 6, pintI ];

    end;

    end;



    sgdDisplay.Cells[ 0, sgdDisplay.Row ] := pstrDate;

    sgdDisplay.Cells[ 1, sgdDisplay.Row ] := pstrTime;

    sgdDisplay.Cells[ 2, sgdDisplay.Row ] := pstrCard_Tag;

    sgdDisplay.Cells[ 3, sgdDisplay.Row ] := pstrDisplay_Status;

    sgdDisplay.Cells[ 4, sgdDisplay.Row ] := pstrBoard_Addr;

    sgdDisplay.Cells[ 5, sgdDisplay.Row ] := pstrReader_Addr;

    sgdDisplay.Cells[ 6, sgdDisplay.Row ] := pstrOri_CardData;

    inc( xintCount );



    // 엑세스 데이터베이스에 저장한다.



    with qryPolling do

    begin

    Close;

    SQL.Clear;

    SQL.Add( 'INSERT INTO TCS_EVENT ' );

    SQL.Add( 'VALUES ( :CARD_TAG, :WORK_DATE, :IN_TIME, :NULL, :STATUS, ' );

    SQL.Add( ':ORI_CARDDATA, :BOARD_ADDR, :READER_ADDR ) ' );

    ParamByName( 'CARD_TAG' ).AsString := pstrCard_Tag;

    ParamByName( 'WORK_DATE' ).AsString := pstrDate;

    ParamByName( 'IN_TIME' ).AsString := pstrTime;

    ParamByName( 'NULL' ).AsString := '';

    ParamByName( 'STATUS' ).AsString := pstrStatus;

    ParamByName( 'ORI_CARDDATA' ).AsString := pstrOri_CardData;

    ParamByName( 'BOARD_ADDR' ).AsString := pstrBoard_Addr;

    ParamByName( 'READER_ADDR' ).AsString := pstrReader_Addr;

    ExecSQL;

    end;

    end;



    end.







    bjjang74 wrote:

    > 현재 rs-232통신을 위해 commportdrv를 이용하는데 이쪽에서 전송하는것은 성공하였는데

    > 상대쪽 모뎀에서 'connect 19200' 또는 기타 문자를 전송받았을때 이쪽에서 자동으로 어떤 문자를 자동으로 전송하고 싶은데 방법을 모르겠네요. commportdrv.readdata..등을 이용하는거 같기도 한데..초보라서 감을 잘 못잡겠네요

    > 예제같은것이 있으면 좋겠습니다. 좋은 하루 되세요

    >

    • 쫑현이
    • 2000.03.14 23:18
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 하얀까마귀
      2000.03.14 23:41
      안녕하세요 하얀까마귀 입니다. TIMC := ImmGetContext(E_ip.Handle); ImmGetConversionStatus(TIM...
    • 기타맨
      2000.03.14 23:25
      김준연 wrote: > form2에서 form1의 이벤트 프로시져(버틀클릭이벤트)를 어떻게 호출하는지 가르쳐 주십시...
    • 김준연
      2000.03.14 23:40
      기타맨 wrote: > 김준연 wrote: > > form2에서 form1의 이벤트 프로시져(버틀클릭이벤트)를 어떻게 호출...
    • 기타맨
      2000.03.14 23:52
      김준연 wrote: > 기타맨 wrote: > > 김준연 wrote: > > > form2에서 form1의 이벤트 프로시져(버틀클릭...
    • 김준연
      2000.03.14 23:59
      기타맨 wrote: > 김준연 wrote: > > 기타맨 wrote: > > > 김준연 wrote: > > > > form2에서 form1의 이...
    • 홍세비
    • 2000.03.14 23:14
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 화랑
      2000.03.15 05:23
      ISAPI로 이미지를 띄운다면 HTML안에서도 가능하지만.. 따로 Include 하는 형식은 당연 안 되죠.. 홍...
    • 안명호
    • 2000.03.14 20:42
    • 3 COMMENTS
    • /
    • 0 LIKES
    • 이만준
      2000.03.15 02:25
      안녕하세요.. 저는 95에서 작업합니다만... 제 옆에서 작업하는 두사람은 200에서 작업하고 있지요.....
    • 하얀까마귀
      2000.03.15 00:03
      안녕하세요 하얀까마귀 입니다. 지금 말씀하신건 아마도 98에서 하시든 2000에서 하시든 마찬가지 일것 ...
    • 왕초보
      2000.03.15 19:52
      글쎄요... 저희 회사에서도 윈98에서 회계Package를 만들어서 판매중에 있습니다. 그러던 중 ...
    • 초보..
    • 2000.03.14 20:35
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2000.03.14 20:48
      소스가 없어서 어딘지는 잘 모르겠지만 소스상의 어딘가에 메모리를 할당받고 사용한 후 해제를 안해주...
    • 김혜진
    • 2000.03.14 20:21
    • 4 COMMENTS
    • /
    • 0 LIKES
    • 이주흥
      2000.03.14 21:29
      김혜진 wrote: > 안녕하세요? 저는 델파이를 거의 사용 못하는 왕 초보입니다. > 근데 회사에서 시키니 ...
    • 최용일
      2000.03.14 21:16
      질문을 반밖에 이해를 못해서... 뒷부분의 그냥 단어이면 검색결과를 출력한다는데 이부분을 잘이해를 못...
    • 김혜진
      2000.03.15 00:55
      최용일 wrote: > 질문을 반밖에 이해를 못해서... 뒷부분의 그냥 단어이면 검색결과를 > 출력한다는데 이...
    • 최용일
      2000.03.15 02:03
      히스토리기능은 값이 입력될때마다 Add나 Insert메소드를 써서 넣어주시면됩니다. 검색할때는 검색엔진마...
    • 최용일
      2000.03.14 20:54
      방법이 없는것은 아니지만 (커스텀 드로 이벤트 사용) 이런경우는 델파이의 TStringGrid컴포넌트를 사용하...
    • 최진실
    • 2000.03.14 19:33
    • 2 COMMENTS
    • /
    • 0 LIKES
    • 최진실
      2000.03.14 21:32
      최진실 wrote: > A, B, C, D, E > 다섯개의 필드중 A, B, C필드와 중복되는 필드만 골라서 그리드에 뷰할...
    • 최재원
      2000.03.14 22:26
      최진실 wrote: > 최진실 wrote: > > A, B, C, D, E > > 다섯개의 필드중 A, B, C필드와 중복되는 필드만...
    • 철이
    • 2000.03.14 18:37
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 노태협
      2000.03.14 20:19
      철이 wrote: > 디자인시에 디비연결은 먼저 알리아스를 지정하고 그리고 적절한 테이블을 선택하면되잖야...
    • 초보
    • 2000.03.14 16:07
    • 5 COMMENTS
    • /
    • 0 LIKES
    • 장은석
      2000.03.16 07:15
      초보 wrote: > 안녕하세요 늘 질문만 올립니다.. > 프로그램이 실행될때 폼자체를 보이지 않게 실행시켜...
    • 최용일
      2000.03.15 00:44
      Q&A 검색을 활용하시면 이런 질문을 안 올리고도 충분히 활용을 하셨을텐데... 안타깝군요... 구창민님...
    • 초보
      2000.03.15 15:47
      최용일님이 답변해 주신 소스 그대로 복사해서 붙여서 실행했는데도 폼이 보여지는데요... 최용일님은 되...
    • 최용일
      2000.03.15 18:49
      그럴리가요... 안돼신다길래 저도 이걸 그대로 복사해서 실행해보았는데 폼이 안보이던데요...... 아마...
    • 초보
      2000.03.16 02:11
      가만 보니까 이벤트연결이 안되었더라구요.. 아이 쪽팔려라..^^ 언제 초보신세 면할지원... 담에 또 답변...
    • 전병하
    • 2000.03.14 09:12
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2000.03.14 23:20
      제가 MMSystem유닛에서 세가지 볼륨제어 함수를 찾았습니다. function waveOutGetVolume(hwo: HWAVEOUT;...
    • random
    • 2000.03.14 08:14
    • 1 COMMENTS
    • /
    • 0 LIKES
    • 최용일
      2000.03.14 21:26
      베벨에다 판넬을 넣으셨다구요? 어떻게 넣으셨는지.... 하하하, 각설하고 먼저 Random함수를 쓰시기전에...
    • 느티나무
      2000.03.15 03:01
      답변을 해드리고 싶은데... 자유계시판의 글을 보고 내키지 않네요... 그리 어려운것도 아니지만 자세가...
    • 임형호
      2000.03.14 22:38
      코스모스 wrote: > 무지 수고가 많네요 > 프로그램으로 먹고 살기 힘드시죠 ? > 제가 좀더 힘들게 해드...
    • 조피디
      2000.03.14 21:13
      흠..드뎌 한델에 유명인사 한분이 탄생하셨군여.. 추카추카..^^ 자유게시판에 올리신글을 읽어보니 코...
    • 강인규
      2000.03.14 20:54
      자유게시판을 보고 글을 올립니다. 어쩜 그런 발언을 하구도 여기에 질문을 올리실 수 있는지 궁금하군...
    • 최용일
      2000.03.14 21:17
      질문에 대한 답을 하기전에 자유게시판에 있는 코스모스님의 글을 읽어보시고 한번생각한 뒤에 답...
    • bjjang74
    • 2000.03.14 07:17
    • 1 COMMENTS
    • /
    • 1 LIKES
    • 김정선
      2000.03.14 19:54
      이건 잠시 제가 테스트할려고 만든겁니다.. 조금이나마 도움이 되셨으면 합니다.. 참고로 포트는 Com5, C...