FT232 가지고 놀기 Part.1

프로젝트/FTDI 2009. 2. 26. 19:08 Posted by 보노보노보노






FTDI사에서 만든 USB-serial 칩이다.

PC와 연결시 VCP로 인식이 되지만 D2XX드라이버로 제어가 가능하다.

사용법은 FTD2XX.DLL 파일을 이용하는것이다.

클래식 인터페이스나 FT-WIN32 인터페이스중에서 하나만 사용하여야 하지만 나는 클래식 인터페이스를 사용하였다.

#include <ftd2xx.h> //FTDI사에서 제공.

int board_present; // 보드의 연결상태를 확인하고 저장하기 위한 변수.
int bus_busy; // USB 버스의 사용유무 확인용 FLAG
CString m_NameNmbr; // FTDI칩과 연결시에 DESCRIPTIN(이름으로 열기)으로 OPEN할때 문자열 비교용.

HMODULE m_hmodule; // FTD2XX.dll 핸들을 얻어오기 위한 코드 내부의 핸들..
FT_HANDLE m_ftHandle; // FT_핸들 선언.


typedef FT_STATUS (WINAPI *PtrToOpen)(PVOID, FT_HANDLE *); //
PtrToOpen m_pOpen;
FT_STATUS Open(PVOID pvDevice)
{
if (!m_pOpen)
return FT_INVALID_HANDLE; // FT_INVALID_HANDLE FT_STATUS에 1로 되어 있음.

return (*m_pOpen)(pvDevice, &m_ftHandle ); //핸들 반환.
} ;

/* FTD2xx.h 안에 원래 함수
FTD2XX_API
FT_STATUS WINAPI FT_Open(
int deviceNumber,
FT_HANDLE *pHandle
); */


typedef FT_STATUS (WINAPI *PtrToOpenEx)(PVOID, DWORD, FT_HANDLE *);
PtrToOpenEx m_pOpenEx;
FT_STATUS OpenEx(PVOID pArg1, DWORD dwFlags)
{
if (!m_pOpenEx)
return FT_INVALID_HANDLE;

return (*m_pOpenEx)(pArg1, dwFlags, &m_ftHandle);
} ;


typedef FT_STATUS (WINAPI *PtrToListDevices)(PVOID, PVOID, DWORD);
PtrToListDevices m_pListDevices;
FT_STATUS ListDevices(PVOID pArg1, PVOID pArg2, DWORD dwFlags)
{
if (!m_pListDevices)
return FT_INVALID_HANDLE;

return (*m_pListDevices)(pArg1, pArg2, dwFlags);
} ;


typedef FT_STATUS (WINAPI *PtrToClose)(FT_HANDLE);
PtrToClose m_pClose;
FT_STATUS USBDrvClose()
{
if (!m_pClose)
return FT_INVALID_HANDLE;

return (*m_pClose)(m_ftHandle);
} ;


typedef FT_STATUS (WINAPI *PtrToRead)(FT_HANDLE, LPVOID, DWORD, LPDWORD);
PtrToRead m_pRead;
FT_STATUS Read(LPVOID lpvBuffer, DWORD dwBuffSize, LPDWORD lpdwBytesRead)
{
if (!m_pRead)
return FT_INVALID_HANDLE;

return (*m_pRead)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytesRead);
} ;




typedef FT_STATUS (WINAPI *PtrToWrite)(FT_HANDLE, LPVOID, DWORD, LPDWORD);
PtrToWrite m_pWrite;
FT_STATUS Write(LPVOID lpvBuffer, DWORD dwBuffSize, LPDWORD lpdwBytes)
{
if (!m_pWrite)
return FT_INVALID_HANDLE;

return (*m_pWrite)(m_ftHandle, lpvBuffer, dwBuffSize, lpdwBytes);
} ;


typedef FT_STATUS (WINAPI *PtrToSetBaudRate)(FT_HANDLE, ULONG);
PtrToSetBaudRate m_pSetBaudRate;
FT_STATUS SetBaudRate(ULONG ulBaudRate)
{
if (!m_pSetBaudRate)
return FT_INVALID_HANDLE;

return (*m_pSetBaudRate)(m_ftHandle,ulBaudRate);
} ;

typedef FT_STATUS (WINAPI *PtrToSetDataCharacteristics)(FT_HANDLE,UCHAR,UCHAR,UCHAR);
PtrToSetDataCharacteristics m_pSetDataCharacteristics;
FT_STATUS SetSetDataCharacteristics(UCHAR WordLenth, UCHAR StopBit, UCHAR Parity)
{
if (!m_pSetDataCharacteristics)
return FT_INVALID_HANDLE;

return (*m_pSetDataCharacteristics)(m_ftHandle, WordLenth, StopBit, Parity);
} ;

typedef FT_STATUS (WINAPI *PtrToSetFlowControl)(FT_HANDLE, USHORT, UCHAR, UCHAR);
PtrToSetFlowControl m_pSetFlowControl;
FT_STATUS SetFlowControl(USHORT FlowControl, UCHAR XonChar, UCHAR XoffChar)
{
if (!m_pSetFlowControl)
return FT_INVALID_HANDLE;

return (*m_pSetFlowControl)(m_ftHandle, FlowControl, XonChar, XoffChar);
} ;



typedef FT_STATUS (WINAPI *PtrToResetDevice)(FT_HANDLE);
PtrToResetDevice m_pResetDevice;
FT_STATUS ResetDevice()
{
if (!m_pResetDevice)
return FT_INVALID_HANDLE;

return (*m_pResetDevice)(m_ftHandle);
} ;


typedef FT_STATUS (WINAPI *PtrToPurge)(FT_HANDLE, ULONG);
PtrToPurge m_pPurge;
FT_STATUS Purge(ULONG dwMask)
{
if (!m_pPurge)
return FT_INVALID_HANDLE;

return (*m_pPurge)(m_ftHandle, dwMask);
} ;


typedef FT_STATUS (WINAPI *PtrToSetTimeouts)(FT_HANDLE, ULONG, ULONG);
PtrToSetTimeouts m_pSetTimeouts;
FT_STATUS SetTimeouts(ULONG dwReadTimeout, ULONG dwWriteTimeout)
{
if (!m_pSetTimeouts)
return FT_INVALID_HANDLE;

return (*m_pSetTimeouts)(m_ftHandle, dwReadTimeout, dwWriteTimeout);
} ;

typedef FT_STATUS (WINAPI *PtrToGetQueueStatus)(FT_HANDLE, LPDWORD);
PtrToGetQueueStatus m_pGetQueueStatus;
FT_STATUS GetQueueStatus(LPDWORD lpdwAmountInRxQueue)
{
if (!m_pGetQueueStatus)
return FT_INVALID_HANDLE;

return (*m_pGetQueueStatus)(m_ftHandle, lpdwAmountInRxQueue);
} ;


typedef FT_STATUS (WINAPI *PtrToGetEventStatus)(FT_HANDLE, DWORD);
PtrToGetEventStatus m_pGetEventStatus;
FT_STATUS GetEventStatus(DWORD dwEventDWord)
{
if (!m_pGetEventStatus)
return FT_INVALID_HANDLE;

return (*m_pGetEventStatus)(m_ftHandle, dwEventDWord);
} ;


int InitDrv()
{
m_hmodule = LoadLibrary("Ftd2xx.dll"); //ftd2xx.dll파일을 로드
if(m_hmodule == NULL)
{
return -1;
}
m_pWrite = (PtrToWrite)GetProcAddress(m_hmodule, "FT_Write"); //ftd2xx.dll에 있는 "FT_WRITE"함수의 주소를 가져옴.
if (m_pWrite == NULL) //만약 함수의 주소를 받아오지 못할 경우 초기화 종료.
{
return -1;
}

m_pRead = (PtrToRead)GetProcAddress(m_hmodule, "FT_Read");
if (m_pRead == NULL)
{
return -1;
}

m_pOpen = (PtrToOpen)GetProcAddress(m_hmodule, "FT_Open");
if (m_pOpen == NULL)
{
return -1;
}

m_pOpenEx = (PtrToOpenEx)GetProcAddress(m_hmodule, "FT_OpenEx");
if (m_pOpenEx == NULL)
{
return -1;
}

m_pListDevices = (PtrToListDevices)GetProcAddress(m_hmodule, "FT_ListDevices");
if(m_pListDevices == NULL)
{
return -1;
}

m_pClose = (PtrToClose)GetProcAddress(m_hmodule, "FT_Close");
if (m_pClose == NULL)
{
return -1;
}

m_pResetDevice = (PtrToResetDevice)GetProcAddress(m_hmodule, "FT_ResetDevice");
if (m_pResetDevice == NULL)
{
return -1;
}

m_pPurge = (PtrToPurge)GetProcAddress(m_hmodule, "FT_Purge");
if (m_pPurge == NULL)
{
return -1;
}

m_pSetTimeouts = (PtrToSetTimeouts)GetProcAddress(m_hmodule, "FT_SetTimeouts");
if (m_pSetTimeouts == NULL)
{
return -1;
}

m_pGetQueueStatus = (PtrToGetQueueStatus)GetProcAddress(m_hmodule, "FT_GetQueueStatus");
if (m_pGetQueueStatus == NULL)
{
return -1;
}

m_pSetBaudRate =(PtrToSetBaudRate)GetProcAddress(m_hmodule,"FT_SetBaudRate");
if (m_pSetBaudRate == NULL)
{
return -1;
}

m_pSetDataCharacteristics =(PtrToSetDataCharacteristics)GetProcAddress(m_hmodule,"FT_SetDataCharacteristics");
if (m_pSetDataCharacteristics == NULL)
{
return -1;
}

m_pSetFlowControl =(PtrToSetFlowControl)GetProcAddress(m_hmodule,"FT_SetFlowControl");
if (m_pSetFlowControl == NULL)
{
return -1;
}

m_pGetEventStatus =(PtrToGetEventStatus)GetProcAddress(m_hmodule,"FT_GetEventStatus");
if (m_pGetEventStatus == NULL)
{
return -1;
}

return 1;
};


FT_STATUS OpenBy()
{
FT_STATUS status; // 샅애확인 위한 구조체 생성.
m_NameNmbr="USB <-> Serial" ; // 이름으로 USB장치를 검색하여 열기 위한 장치이름.

status = OpenEx((PVOID)(LPCTSTR)m_NameNmbr, FT_OPEN_BY_DESCRIPTION);
//이름에 의한 호출로 Product Description이 "USB <-> Serial"으로 되어있는 장치를 엶.
return status; // 정상적으로 OPEN 되었을시 0(FT_OK)반환.
};

FT_STATUS OpenBy(char* DESCRIPTION)
{
FT_STATUS status; // 샅애확인 위한 구조체 생성.
m_NameNmbr=DESCRIPTION; // 이름으로 USB장치를 검색하여 열기 위한 장치이름.

status = OpenEx((PVOID)(LPCTSTR)m_NameNmbr, FT_OPEN_BY_DESCRIPTION);
//이름에 의한 호출로 Product Description이 "USB <-> Serial"으로 되어있는 장치를 엶.
return status; // 정상적으로 OPEN 되었을시 0(FT_OK)반환.
};

int SetFT232()
{
// 232 통신위한 설정.
SetBaudRate(FT_BAUD_115200 ); //115.2k
SetSetDataCharacteristics(FT_BITS_8, FT_STOP_BITS_1,
FT_PARITY_NONE); // 데이터길이, 스탑비트, 페리티 설정.
SetFlowControl(FT_FLOW_NONE,NULL,NULL); //흐름제어 설정부
SetTimeouts(1000,1000); // READ TIMEOUT, WRITE TIMEOUT 설정(ms단위)

return 1;
}
int SetFT232(ULONG Baud, UCHAR Bit, UCHAR StopBit, UCHAR Parity)
{
// 232 통신위한 설정.
SetBaudRate(Baud); //115.2k
SetSetDataCharacteristics(Bit, StopBit, Parity); // 데이터길이, 스탑비트, 페리티 설정.
SetFlowControl(FT_FLOW_NONE,NULL,NULL); //흐름제어 설정부
SetTimeouts(1000,1000); // READ TIMEOUT, WRITE TIMEOUT 설정(ms단위)
return 1;
}

int USBDrvInit()
{
//open the device
FT_STATUS status = OpenBy(); // USB 디바이스 OPEN위한 함수 실행.
if(!(status==FT_OK)) // USB 열기를 실패할 경우.
{
board_present=0; // 디바이스와 연결 안되었음을 저장.
return -1; // 종료.
}
else // 디바이스를 성공적으로 열었을 경우.
{
ResetDevice(); // 디바이스를 리셋시킴.
Purge(FT_PURGE_RX || FT_PURGE_TX); // 디바이스의 Rx,Tx버퍼를 초기화.


//test for presence of board
board_present=1; //디바이스와 연결되었다는 상태를 저장.
SetFT232();
}
return 1; // 초기화 성공을 알리는 상수 반환.
};

int USBDrvInit(char *DESCRIPTION)
{
//open the device
FT_STATUS status = OpenBy(DESCRIPTION); // USB 디바이스 OPEN위한 함수 실행.
if(!(status==FT_OK)) // USB 열기를 실패할 경우.
{
board_present=0; // 디바이스와 연결 안되었음을 저장.
return -1; // 종료.
}
else // 디바이스를 성공적으로 열었을 경우.
{
ResetDevice(); // 디바이스를 리셋시킴.
Purge(FT_PURGE_RX || FT_PURGE_TX); // 디바이스의 Rx,Tx버퍼를 초기화.


//test for presence of board
board_present=1; //디바이스와 연결되었다는 상태를 저장.
SetFT232();
}
return 1; // 초기화 성공을 알리는 상수 반환.
};


void TxData(char *TxD,UINT len) // 데이터 길이를 정해서 전송시
{
DWORD ret_bytes; // 이전에 전송한 데이터를 받을 주소.

if(!board_present) // 디바이스와 연결이 되지 않았을때
return ; // 함수종료

bus_busy=1; // 버스가 사용중임을 알림.

//keep the timer function from grabbing return data

Write(TxD, len, &ret_bytes); // 전송할 문자열, 길이, 이전에 전송한 데이터(반환) 

bus_busy=0; // 버스의 사용종료 알림.
};


int AsciiToInt_2Digit(char *ascii_) // 2개의 아스키 코드를 정수형변수로 변환.
{
int int_data; // 계산하여 반환될 정수형 데이터 선언.

int_data=(int)ascii_[1]-48;
int_data+=((int)ascii_[0]-48)*10;

return int_data;
}


int RxData(char **RxDD,int lenth) // 문자열의 길이를 지정해서 전손받을때.
{
static char rx[256]; // 전송받을 문자를 받을 배열 설정.

DWORD rec_bytes; // 디바이스측에서 외부장치로부터 받은 데이터의 길이를 저장

if(!board_present) // 디바이스와 연결되지 않았을때
return -1; // 함수종료.

for (int i=0;i<256;i++) // 데이터 받을 곳을 초기화.
rx[i]=NULL;

bus_busy=1; // 버스가 사용중임을 알림.

Read(rx, lenth, &rec_bytes); // 받을 문자열을 저장할 장소, 받을 데이터의 길이,
// 디바이스가 외부로부터 받은 데이터 길이.
bus_busy=0; // 버스의 사용종료 알림.

*RxDD=rx; // 받은 데이터를 입력받은 포인터에 반환.
return 0;
}


int RxData(char **RxDD) // 문자열의 길이를 지정하지 않고 데이터를 받을때.
{
static char rx[256]; // 전송받을 문자를 받을 배열 설정.

DWORD rec_bytes, Rxbyte_lenth; // 디바이스측에서 외부장치로부터 받은 데이터의 길이를 저장,
//
if(!board_present) // 디바이스와 연결되지 않았을때
return -1; // 함수종료.

for (int i=0;i<256;i++) // 데이터 받을 곳을 초기화.
rx[i]=NULL;

bus_busy=1; // 버스가 사용중임을 알림.
GetQueueStatus(&Rxbyte_lenth); // 현재 디바이스가 받은 데이터의 길이 저장

if(Rxbyte_lenth>0) // 수신한데이터가 있으면
{
Read(rx, Rxbyte_lenth, &rec_bytes); //수신한 데이터양만큼 데이터를 수신.
}
bus_busy=0; // 버스의 사용종료 알림.

*RxDD=rx; // 받은 데이터를 입력받은 포인터에 반환.
return Rxbyte_lenth; // 수신한 데이터의 길이 반환.
}


int RxData_dynamic(char **RxDD) // 받을 데이터에 데이터의 길이가 포함되어 있을경우.
{
static char rx[256]; // 전송받을 문자를 받을 배열 설정.

DWORD ret_bytes, Rxbyte_lenth; // 디바이스측에서 외부장치로부터 받은 데이터의 길이를 저장,
char lenth_data[2]; // 데이터의 길이를 받을 배열 생성.
int lenth_int; // 데이터의 길이 저장변수.

if(!board_present) // 디바이스와 연결되지 않았을때
return -1; // 함수종료.

for (int i=0;i<256;i++) // 데이터를 받을 곳을 초기화.
rx[i]=NULL;

bus_busy=1; // 버스 사용중임을 알림.
GetQueueStatus(&Rxbyte_lenth); // 현재 디바이스가 받은 데이터의 길이 저장

if(Rxbyte_lenth>0) // 수신한 데이터가있을시.
{
Read(lenth_data,2,&ret_bytes); // 길이 데이터 수신.
lenth_int=AsciiToInt_2Digit(lenth_data); //받은길이 데이터를 정수형으로 변환.
Read(rx, lenth_int, &ret_bytes); // 데이터의 길이만큼 데이터 수신.
}
bus_busy=0; // 버스의 사용종료 알림.

*RxDD=rx; // 받은 데이터를 입력받은 포인터에 반환.
return lenth_int; // 수신한 데이터의 길이 반환.
}



 

위와같이 해더파일을 만들엇다

메카트로닉스 산업기사에서 사용하는 imechatronics.h 헤더파일을 수정하였으며.

기존의 FT245 칩을 사용시에  통신속도와 패리티 비트, 스탑비트를 설정 안하여도 된다.

int InitDrv()는  FTD2XX.dll에서 각 핸들을 얻어오는 함수이고.

FT_STATUS OpenBy()는 기본 DESCRIPTION인 "USB <-> Serial"을 사용시 사용하고

int SetFT232() 는 115.2K속도, 데이터 8bit, 1스탑비트, 패리티 비트 없이, 흐름제어를 안하는 기본 설정으로 여는것이고.

int USBDrvInit()는 기본 DESCRIPTION을 이용하여 드라이버를 열고 SerFT232() 함수를 실핼 한것으로 포트를 열기 실패시 -1의 값을 리턴한다.

나머지 함수는 주석을 달았으니 그때그때 보면서 쓰면 될듯...



API 시작하기 #2 - 문자열 출력

학습/API 2009. 2. 11. 20:02 Posted by 보노보노보노


#include<windows.h>
// WINAPI : 09년 2월 11일

/* WndClass 정의 -> 클레스 등록- > 메모리상의 윈도우 생성 -> 윈도우 화면에 표시 -> 사용자로부터의 메시지 처리. */


LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hlnst;     //인스턴스 핸들형 g_hlst 선언.
LPCTSTR lpszClass=TEXT("first"); //LPCTSTR -> const char* 형태 .
     
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
      LPSTR lpszCmdLine, int nCmdshow)
{
 /*hInstance   : 프로그램의 인스턴스 핸들,  hPrevInstance : 앞에서 실행된 현재프로그램의 인스턴스 핸들*/
 /*lpszCmdLine : 명령행,입력된 프로그램의 인수. 도스의 argv, 보통 실행직후에 열 파일의 경로.  */
 /*nCmdshow    : 프로그램이 실행될 형태, 최소화,보통모양등*/

 HWND hWnd;        // 윈도으 핸들을 생성.
 MSG Message;       // MSG구조체인 Message생성.
 WNDCLASS WndClass;      // 윈도우 클래스 생성.
 g_hlnst=hInstance;      //

 WndClass.cbClsExtra  = 0;   //예약 영역, 내부적으로 사용하며 아주 특수한 목적에 사용되는 여분의 공간.
 WndClass.cbWndExtra  = 0;   //사용하지 않을시에는 0으로 지정
 WndClass.hbrBackground = (HBRUSH)GetStockObject(LTGRAY_BRUSH);
       // CreateHatchBrush(HS_DIAGCROSS,RGB(110,20,200)); // 배경과 무니 지정.
       // CreateSolidBrush(RGB(0,0,255));   // RGB색상으로 배경을 칠함.
       // (HBRUSH)GetStockObject(LTGRAY_BRUSH); //LTGRAY_brush(회색)로 배경을 칠함. (기본)
       // (HBRUSH)GetStockObject(BLACK_BRUSH);  //black_brush(검정색)로 배경을 칠함.(기본)
       // (HBRUSH)GetStockObject(WHITE_BRUSH);  //white_brush(백색)로 배경을 칠함.  (기본)
       // 기본 브러쉬는 위의 3개임. <- 10/02/09

 WndClass.hCursor  = LoadCursor(NULL,IDC_ARROW); 
       // IDC_CROSS : 십자가모양.  IDC_IBEAM : I자 모양,  IDC_NO : 원안베 빗금처리. 
       // IDC_ARROW : 기본 화살표.  IDC_WAIT : 모래시계.

 WndClass.hIcon   = LoadIcon(NULL,IDI_APPLICATION); // 기본제공하는 아이콘 (네모 윈도 박스)
       // IDI_EXCLAMATION : 주의 모양 (삼각형)  IDI_ERROR  : 에러모양(원안에 X)
       // IDI_ASTERISK  : 정보모양 (i)    IDI_QUESTION : 질문모양 (물음표)

 WndClass.hInstance  = hInstance; // 윈도 클래스를 등록하는 프로그램의번호.
 WndClass.lpfnWndProc = WndProc;  // 윈도우의 메시지 처리함수 지정.
           // 메세지 발생시 이 멤버가 지정하는 함수가 호출됨

 WndClass.lpszClassName = lpszClass;     // 클레스 이름을 저장한 lpszClass값을 대입.
 WndClass.lpszMenuName = NULL;       // 메뉴
 WndClass.style   = CS_HREDRAW|CS_VREDRAW;  // 윈도우의 스타일 ,CS_HREDRAW : 수평크기가 달라지면 다시 그림
               // CS_VREDRAW :수직의 크기가 달라지면 다시 그려줌.
 RegisterClass(&WndClass);    //WndClass를 등록함(번지를 통해서 ).

 

 hWnd=CreateWindow(
  lpszClass,    // lpszClassName : 클래스 이름
  lpszClass,    // lpszWindowName : 윈도우 이름, 타이틀바에 나타날 문자열.
        //      TEXT("알림"), 등으로 윈도우 이름 변환 가능.

  WS_OVERLAPPEDWINDOW, // dwStyle   : 윈도우의 형태를 지정하는 인수.
 
  //WS_OVERLAPPEDWINDOW : overlapped,caption,sysmenu,thickfream,minimizebox,maximizebox
        //      WS_OVERLAPPEDWINDOW스타일을 사용시 무난함.
        
  100,//CW_USEDEFAULT, // X    : X축 시작위치.
  100,//CW_USEDEFAULT, // Y    : Y축 시작위치.
  320,//CW_USEDEFAULT, // nWidth   : 폭의 크기.
  240,//CW_USEDEFAULT, // nHeight   : 높이의 크기.
  NULL,     // hWndParent  : 부모윈도가 있을경우 부모윈도의 핸들 최상위의 경우 NULL
  (HMENU)NULL,   // hmenu   : 윈도우에서 사용할 핸들을 지정.
  hInstance,    // hinst   : 윈도우를 만드는주체, 핸들을 지정. 프로그램 종료시
        //      파괴되지 않은 윈도우를 자동으로 파괴.
  NULL     // lpvParam   : 여러 개의 윈도우를 만들 때 각 윈도우에 고유의 파라미터를 전달. 특수목적.
  );

 ShowWindow(hWnd,nCmdshow);    // 윈도우의 핸들을(hWnd)가지고 화면 출력하는 방법을 지정.

 while(GetMessage(&Message,NULL,0,0)) // 메시지큐에서 메시지를 읽어옴. WM_QUIT일경우 FALSE출력. 그외의 경우 TRUE
 {
  TranslateMessage(&Message);   // 키보드의 입력을 가공하여 프로그램에 쓸수 있도록 한다.
           // ex) A를 누르면 A문자가 입력되었다는 메시지를 만들어냄.
  DispatchMessage(&Message);   // 메시지 큐에서 꺼낸 메시지를 윈도우의 메시지 처리함수 (WndProc)로 전달.
           // 그후 다시 루프의 선두로 돌아가 다음 메시지를 기다린다.
 }
 return (int)Message.wParam;    // WM_QUIT 메시지로부터 전달된 탈출코드. 운영체제로 리턴된다.
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage ,WPARAM wParam,LPARAM lParam) 
// hWnd : 메세지 받는 윈도우 핸들, iMessage :어떤 종류의 메시지인가, WPRAM,LPARAM :부가적인 정보를 가진다.
// 메시지 발생시 프로그램의 반응을 처리하는 일을 함. 운영체제에 의해 호출됨.
// 이렇게 운영체제에 의해 호출되는 응용 프로그램 내의 함수를 callback함수라고 한다.
{
 static mode=1;

 HDC hdc;
 PAINTSTRUCT ps;
 RECT rt={100,100,400,300};  //x,y축의 시작점과 끝점을 입력.
 TCHAR *strr=TEXT("님은 갔습니다. 아아 사랑하는 님은 갔습니다. 푸른 산빛을 "
  "깨치고 단풍나무 숲을 향하여 난 작은 길을 걸어서 차마 떨치고 갔습니다 "
  "황금의 꽃같이 굳고 빛나던 옛 맹세는 차디찬 티끌이 되어 한숨의 미풍에 "
  "날아갔습니다");  //출력할 문자열.

 switch(iMessage)
 {
 case WM_DESTROY:
  PostQuitMessage(0);  //창을 단으려하거나 alt+f4의 경우 WM_QUIT 메시지를 생성.
  return 0;

 case WM_LBUTTONDOWN:
  mode=2;

  return 0;

 case WM_PAINT:
  if(mode==2)
  {
   ////////////////////////////////////////////////////////////////////////////////////////////////
   //TEXT 출력방법 #1  //단순히 문자를 출력.
   /*         
   hdc=GetDC(hWnd);      //핸들을 얻어옴.
   TextOut(hdc,10,10,TEXT("Bonobono"),8); //문자열을 출력.
   ReleaseDC(hWnd,hdc);     //핸들을 반환.
   */

   ////////////////////////////////////////////////////////////////////////////////////////////////
   //TEXT 출력방법 #2 문자열에 이것저것 속성을 변화시킴.
   /*          
   hdc=BeginPaint(hWnd,&ps);    //핸들을 얻어와서.( PAINTSTRUCT ps 생성 요망)
  
   SetTextAlign(hdc,TA_UPDATECP);   //문자의 표시 속성 setting
         //TA_TOP : 위쪽,  TA_BOTTOM : 아래,
         //TA_LEFT : 제일 왼쪽.TA_CENTER : 중심, TA_RIGHT : 오른쪽. (OR연산자로 연동가능.)
         //TA_UPDATECP : 좌표 무시하고 화면의 왼쪽 제일 위에서부터 출력.
   
   TextOut(hdc,100,10,TEXT("RnA is"),6);   //얻어온 핸들로 10,10에 6의크기를 가진 문자를 출력한뒤.
   TextOut(hdc,100,30,TEXT("My Robot"),7);   //얻어온 핸들로 10,10에 6의크기를 가진 문자를 출력한뒤.
   TextOut(hdc,100,50,TEXT("Turning point"),13); //얻어온 핸들로 10,10에 6의크기를 가진 문자를 출력한뒤.
   EndPaint(hWnd,&ps);
   */

   ////////////////////////////////////////////////////////////////////////////////////////////////
   //TEXT 출력방법 #3 변수를 문자열에 대입하여 출력
   /*         
   hdc=GetDC(hWnd);      // DC 핸들을 얻어와서
   TCHAR temp[100];      // 임시 작업할 공간 생성.
   wsprintf(temp,TEXT("dddd%d"),10);  // 문자열 만들어 값을 대입하거나 할때 사용.
   TextOut(hdc,10,10,temp,lstrlen(temp)); // 핸들로 10,10 위치에 작어한 문자열을 문자열의 크기만큼 출력.
   ReleaseDC(hWnd,hdc);     // 핸들 반환.
   */

   ////////////////////////////////////////////////////////////////////////////////////////////////
   //TEXT 출력방법 #4 문자열을 입력받아 사각형안에만 출력.
   
   // 함수의 시작부분에 선언해야 할 것들. 
   /* RECT rt={100,100,400,300};  //x,y축의 시작점과 끝점을 입력.여기서 정한 만큼의 사각형이 만들어지고 그만큼 출력.
    TCHAR *strr=TEXT("님은 갔습니다. 아아 사랑하는 님은 갔습니다. 푸른 산빛을 "
     "깨치고 단풍나무 숲을 향하여 난 작은 길을 걸어서 차마 떨치고 갔습니다 "
     "황금의 꽃같이 굳고 빛나던 옛 맹세는 차디찬 티끌이 되어 한숨의 미풍에 "
     "날아갔습니다"); */ //출력할 문자열.
   /*
   // 실제 처리 루틴
   hdc=BeginPaint(hWnd,&ps);    // 핸들을 얻어와서.
   DrawText(hdc,strr,-1,&rt,DT_CENTER|DT_WORDBREAK); //RECT에 설정된 크기만큼의 박스를 만들어 출력한뒤.
        // nCount  -1 :
        // lpRect &rt : rt에 만들어논 출력 박스의 크기 를 불러옴.
        // nFormat  : 출력방식-> DT_LEFT,RIGHT,CENTER,BOTTOM : 정렬기준 설정.
        //  _VCENTER: 사각영역의 수직중앙, _WORDBREAK : 사각영역의 오른쪽끝에서 자동줄바꿈.  
        //  _SINGLELINE : 한줄출력,   _NOCLIP  : 사각영역을 벗어나도 출력.(자르지 않고)

   EndPaint(hWnd,&ps);      // 핸들반환.
   */ 
   
   ////////////////////////////////////////////////////////////////////////////////////////////////
  MessageBeep(0);     //비프 메시지.
   return 0;
  }
 }
 return DefWindowProc(hWnd,iMessage,wParam,lParam); //default
}

 

APl 시작하기 #1

학습/API 2009. 2. 10. 21:39 Posted by 보노보노보노


#1 . 단순한 윈도우 생성.

기초가되는 윈도우창을 생성.


#include<windows.h>
// WINAPI : 09년 2월 10일

/* WndClass 정의 -> 클레스 등록- > 메모리상의 윈도우 생성 -> 윈도우 화면에 표시 -> 사용자로부터의 메시지 처리. */


LRESULT CALLBACK WndProc(HWND,UINT,WPARAM,LPARAM);
HINSTANCE g_hlnst;     //인스턴스 핸들형 g_hlst 선언.
LPCTSTR lpszClass=TEXT("first"); //LPCTSTR -> const char* 형태 .
     
int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
      LPSTR lpszCmdLine, int nCmdshow)
{
 /*hInstance   : 프로그램의 인스턴스 핸들,  hPrevInstance : 앞에서 실행된 현재프로그램의 인스턴스 핸들*/
 /*lpszCmdLine : 명령행,입력된 프로그램의 인수. 도스의 argv, 보통 실행직후에 열 파일의 경로.  */
 /*nCmdshow    : 프로그램이 실행될 형태, 최소화,보통모양등*/

 HWND hWnd;        // 윈도으 핸들을 생성.
 MSG Message;       // MSG구조체인 Message생성.
 WNDCLASS WndClass;      // 윈도우 클래스 생성.
 g_hlnst=hInstance;      //

 WndClass.cbClsExtra  = 0;   //예약 영역, 내부적으로 사용하며 아주 특수한 목적에 사용되는 여분의 공간.
 WndClass.cbWndExtra  = 0;   //사용하지 않을시에는 0으로 지정
 WndClass.hbrBackground = CreateSolidBrush(RGB(0,0,255)); // RGB색상으로 배경을 칠함.
       // (HBRUSH)GetStockObject(LTGRAY_BRUSH); //LTGRAY_brush(회색)로 배경을 칠함. (기본)
       // (HBRUSH)GetStockObject(BLACK_BRUSH);  //black_brush(검정색)로 배경을 칠함.(기본)
       // (HBRUSH)GetStockObject(WHITE_BRUSH);  //white_brush(백색)로 배경을 칠함.  (기본)
       // 기본 브러쉬는 위의 3개임. <- 10/02/09

 WndClass.hCursor  = LoadCursor(NULL,IDC_ARROW);  // 윈도우 기본제공하는 커서 
 WndClass.hIcon   = LoadIcon(NULL,IDI_APPLICATION); // 기본제공하는 아이콘

 WndClass.hInstance  = hInstance; // 윈도 클래스를 등록하는 프로그램의번호.
 WndClass.lpfnWndProc = WndProc;  // 윈도우의 메시지 처리함수 지정.
           // 메세지 발생시 이 멤버가 지정하는 함수가 호출됨
 WndClass.lpszClassName = lpszClass;     // 클레스 이름을 저장한 lpszClass값을 대입.
 WndClass.lpszMenuName = NULL;       // 메뉴
 WndClass.style   = CS_HREDRAW|CS_VREDRAW;  // 윈도우의 스타일 ,CS_HREDRAW : 수평크기가 달라지면 다시 그림
               // CS_VREDRAW :수직의 크기가 달라지면 다시 그려줌.
 RegisterClass(&WndClass);    //WndClass를 등록함(번지를 통해서 ).

 

 hWnd=CreateWindow(
  lpszClass,    // lpszClassName : 클래스 이름
  lpszClass,    // lpszWindowName : 윈도우 이름, 타이틀바에 나타날 문자열.
  WS_OVERLAPPEDWINDOW, // dwStyle   : 윈도우의 형태를 지정하는 인수.
        //      WS_OVERLAPPEDWINDOW스타일을 사용시 무난함.
  CW_USEDEFAULT,   // X    : X축 시작위치.
  CW_USEDEFAULT,   // Y    : Y축 시작위치.
  CW_USEDEFAULT,   // nWidth   : 폭의 크기.
  CW_USEDEFAULT,   // nHeight   : 높이의 크기.
  NULL,     // hWndParent  : 부모윈도가 있을경우 부모윈도의 핸들 최상위의 경우 NULL
  (HMENU)NULL,   // hmenu   : 윈도우에서 사용할 핸들을 지정.
  hInstance,    // hinst   : 윈도우를 만드는주체, 핸들을 지정. 프로그램 종료시
        //      파괴되지 않은 윈도우를 자동으로 파괴.
  NULL     // lpvParam   : 여러 개의 윈도우를 만들 때 각 윈도우에 고유의 파라미터를 전달. 특수목적.
  );

 ShowWindow(hWnd,nCmdshow);    // 윈도우의 핸들을(hWnd)가지고 화면 출력하는 방법을 지정.

 while(GetMessage(&Message,NULL,0,0)) // 메시지큐에서 메시지를 읽어옴. WM_QUIT일경우 FALSE출력. 그외의 경우 TRUE
 {
  TranslateMessage(&Message);   // 키보드의 입력을 가공하여 프로그램에 쓸수 있도록 한다.
           // ex) A를 누르면 A문자가 입력되었다는 메시지를 만들어냄.
  DispatchMessage(&Message);   // 메시지 큐에서 꺼낸 메시지를 윈도우의 메시지 처리함수 (WndProc)로 전달.
           // 그후 다시 루프의 선두로 돌아가 다음 메시지를 기다린다.
 }
 return (int)Message.wParam;    // WM_QUIT 메시지로부터 전달된 탈출코드. 운영체제로 리턴된다.
}

LRESULT CALLBACK WndProc(HWND hWnd,UINT iMessage ,WPARAM wParam,LPARAM lParam) 
// hWnd : 메세지 받는 윈도우 핸들, iMessage :어떤 종류의 메시지인가, WPRAM,LPARAM :부가적인 정보를 가진다.
// 메시지 발생시 프로그램의 반응을 처리하는 일을 함. 운영체제에 의해 호출됨.
// 이렇게 운영체제에 의해 호출되는 응용 프로그램 내의 함수를 callback함수라고 한다.
{
 switch(iMessage)
 {
 case WM_DESTROY:
  PostQuitMessage(0);  //창을 단으려하거나 alt+f4의 경우 WM_QUIT 메시지를 생성.
  return 0;
 }
 return DefWindowProc(hWnd,iMessage,wParam,lParam); //default
}

 

조이박스 - 스페셜

감성 2009. 1. 15. 02:10 Posted by 보노보노보노






 feel good
I feel nice
나는 행복해
넌 나의 special
 

이순간
난 알겠어
너없인 단 하루도 살수 없다고
넌 나의 special
and this is for you baby
(cho)

yo lay yo lay yo laylay yo
yo lay yo lay yo laylay yo
yo lay yo lay yo laylay yo~~
and this is for you baby


I feel great
and I feel so fine
다른 누구도 생각할순 없잖아
넌 나의 special,special special ye ye~

따듯한 너의 그손길
아름답던 목소리
아직도 들리는 숨소리
달콤했던 그향기
날 바라보고있던 그눈빛
이제 조금더 가까이.........
이제 조금더 가까이.........
anything for you baby

(Ending cho)
yo lay yo lay yo lay yo ~~~~~
sta ta la ta talala~

Sketch - Kiyoshi Yoshida

감성 2008. 12. 27. 02:24 Posted by 보노보노보노