가나소프트 이야기

1) WideString 
캐스팅 시키는 함수. 아래 방법으로 하시면, A에 wchat_t 형식으로 Hello가 들어갑니다. 

A = WideString("Hello"); 

2) StringToOleStr 
원라는 AnsiString용 함수입니다. char 배열도 사용할 수 있습니다. 

A = StringToOleStr("Hello"); 

3) MultiByteToWideChar 
이 방법을 쓰시면 UTF8 형식으로도 변경할 수 있습니다. UniCode를 사용하는 경우, 이 API를 꼭 이용하셔야 합니다. UTF8을 원하시면 CP_ACP 부분을 CP_UTF8 로 바꾸어 주시면 됩니다. 이 방법은 조금 복잡합니다. 먼저 문자열 길이가 얼마나 나오는지 얻어낸 다음, 그 길이만큼 변수를 잡고, 변환을 다시 시켜야 합니다. 

String            stString = "HELLO"; 
int               itWideSize = MultiByteToWideChar(CP_UTF8, 0, stString.c_str(), stString.Length() + 1, NULL, 0); 
wchar_t           *wcTarget = new wchar_t[itWideSize]; 

MultiByteToWideChar(CP_ACP, 0, stString.c_str(), stString.Length() + 1, wcTarget, itWideSize); 
=========================================================================================================

볼랜드포럼 유영인님 글에서 발췌


사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : contact@gana-soft.com | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기

MFC에서 프로젝트를 FormView를 쓰면 화면 전환시에 사용하는 법은 다음과 같이 난 작성한다...

메인폼에 사용자 메시지를 받을 수 있는 함수를 다음과 같이 작성한다..

LRESULT CMainFrame::OnFormChange(WPARAM wParam, LPARAM lParam)
{
// TRACE0(" User Message!!");

// Form Change
CView* pOldActiveView = GetActiveView();
CView* pNewActiveView = (CView*)GetDlgItem(wParam);
if(pNewActiveView==NULL) 
{
switch (wParam)  {
case IDD_LDP_CAL_FORM :
pNewActiveView = (CView*)new CLDPSetupCalView; 
TRACE0(" Menu Cal Form Change!!");
break;
case IDD_LDP_MAIN_FORM :
pNewActiveView = (CView*)new CLDPSetupMainView;
TRACE0(" Menu Cal MainChange!!");
break;
}
CCreateContext context;  
context.m_pCurrentDoc=pOldActiveView->GetDocument() ;
pNewActiveView->Create(NULL,NULL,0L,CFrameWnd::rectDefault,this,wParam,&context) ;
pNewActiveView->OnInitialUpdate() ;
}
SetActiveView(pNewActiveView) ;
pNewActiveView->ShowWindow(SW_SHOW) ;
if    (pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CLDPSetupCalView))      
pOldActiveView->SetDlgCtrlID(IDD_LDP_CAL_FORM);
else if(pOldActiveView->GetRuntimeClass()==RUNTIME_CLASS(CLDPSetupMainView)) 
pOldActiveView->SetDlgCtrlID(IDD_LDP_MAIN_FORM);
pNewActiveView->SetDlgCtrlID(AFX_IDW_PANE_FIRST) ;
RecalcLayout();
delete pOldActiveView;
CurrentForm = wParam;

return 0;
}



이런식의 함수를 사용하고자 하는 곳에서...

::SendMessage(AfxGetMainWnd()->m_hWnd, UM_MENUCHANGE, IDD_LDP_CAL_FORM, NULL); 

이런식으로 호출해서 폼이 바뀌는방식을 주로 쓴다..


그리고 C++ 빌더에서는 다음과 같이 사용한다...
1. 이전 화면이 있으면 삭제..
2. 화면 호출 및 생성
3. 화면 크기를 메인폼에 맞게 수정..(Resize 함수 이용)

// 그려질 폼이 메인폼에 맞게 사이즈를 맞추어 준다...

void __fastcall TMainForm::FormResize(TObject *Sender)

{

if(Frame_User){

Frame_User->Width = ClientWidth;

Frame_User->Height = ClientHeight;

return;

}

else if(Frame_Group)

{

Frame_Group->Width = ClientWidth;

Frame_Group->Height = ClientHeight;

}

}


// 기존의 폼을 제거한다..


int __fastcall TMainForm::DeleteFrame()

{

// 사용자 등록 화면 삭제.

if(Frame_User){

delete Frame_User;

Frame_User = NULL;

}

//...//

}



// 그리고 호출 및 생성은...

void __fastcall TMainForm::N2Click(TObject *Sender)

{ // 사용자 등록

DeleteFrame();  // 호출되어 있는 폼 삭제

Frame_User = new TFrame_User(this); // 현재 폼을 오너로 해서 생성

TRect rect = Rect(0,0, ClientWidth, ClientHeight); // 현재 폼을 전체 덮는 크기로 설정

Frame_User->Dock(this, rect); // 현재 폼을 도킹 시켜 보이게 한다..


다음과 같이 처리한다... 어떤 방식이 더 낫다고 볼 수 없다..


김용유닷컴(kimyongyu.com) 예전글에서 발췌 수정

사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : contact@gana-soft.com | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기

**********************************************************/

/*                                                        */

/*          Test program for Communication functions      */

/*                                                        */

/*  Copyright (C) 1999 MITSUBISHI Electric Corporation    */

/*  All Rights Reserved                                   */

/**********************************************************/

/********************************************

* Include files *

********************************************/

#include        <stdio.h>

#include        <winsock.h>


#define FLAG_OFF  0 // 종료 플래그 OFF

#define FLAG_ON  1 // 종료 플래그 ON

#define SOCK_OK  0 // 정상 종료 

#define SOCK_NG -1 // 이상 종료 

#define BUF_SIZE 80 // 버퍼 사이즈 


#define ERROR_INITIAL  0 // 초기화 에러 

#define ERROR_SOCKET  1 // 소켓 작성 에러 

#define ERROR_BIND  2 // 바인드 에러

#define ERROR_CONNECT  3 // 커넥트 에러

#define ERROR_SEND  4 // 송신 에러 

#define ERROR_RECEIVE  5 // 수신 에러 

#define ERROR_SHUTDOWN  6 // 셧다운 에러 

#define ERROR_CLOSE  7 // 회선 클로즈 에러 


typedef struct sck_inf {

struct in_addr my_addr;

unsigned short my_port;

struct in_addr aj_addr;

unsigned short aj_port;

};


int nErrorStatus; // 에러 정보 저장 변수

int Dmykeyin; // 더미 키 입력

int Closeflag; // 커넥션 종료 플래그

int socketno;


/***************************************************

* Reads in device "D" of specified No              *

* on station No 1                                  *

***************************************************/

int main()

{

WORD wVersionRequested = MAKEWORD(1,1);  

WSADATA wsaData; // Winsock Ver 1.1 요구 

int length; // 교신 데이터 길이 

int result;

unsigned char s_buf[BUF_SIZE]; // 송신 버퍼 

unsigned char r_buf[BUF_SIZE]; // 수신 버퍼 

struct sck_inf sc; // 구조체 변수 선언

struct sockaddr_in hostdata; // 상대 기기측 데이터

struct sockaddr_in aj71e71; // Ethernet 모듈측 데이터 

void Sockerror(int); // 에러 처리 함수 

sc.my_addr.s_addr = htonl(INADDR_ANY); // 상대 기기측 IP Address(PC쪽 IP Address)

sc.my_port = htons(0); // 상대 기기측 Port No.(PC쪽 Port No.)

sc.aj_addr.s_addr = inet_addr("192.168.16.232"); // Ethernet 모듈측 IP Address(C00001FD) - PLC 모듈 IP 셋팅

sc.aj_port = htons(5002); // Ethernet 모듈측 Port No. - PLC 모듈 

// PLC Port No : 138A(16진수)로 셋팅


Closeflag = FLAG_OFF; // 커넥션 종료 플래그 OFF


nErrorStatus = WSAStartup(wVersionRequested, &wsaData);

if (nErrorStatus != SOCK_OK) // Winsock 초기화 처리

{

Sockerror(ERROR_INITIAL);

return(SOCK_NG);

}


printf("Winsock Version is %d, %d\n", HIBYTE(wsaData.wVersion), LOBYTE(wsaData.wVersion));

printf("AJ_test Start\n");


socketno = socket(AF_INET, SOCK_STREAM, 0); // 소켓 생성

if (socketno == INVALID_SOCKET) // TCP/IP의 소켓 작성 

{

Sockerror(ERROR_SOCKET);

return(SOCK_NG);

}

hostdata.sin_family = AF_INET; // PC 쪽 Socket 구조체 정의 

hostdata.sin_port = sc.my_port; // PC 쪽 Port No, IP Address

hostdata.sin_addr.s_addr = sc.my_addr.s_addr;


if (bind(socketno, (LPSOCKADDR)&hostdata, sizeof(hostdata)) != SOCK_OK) // 바인드

{

Sockerror(ERROR_BIND);

return(SOCK_NG);

}


aj71e71.sin_family = AF_INET; // PLC 쪽 Socket 구조체 정의 

aj71e71.sin_port = sc.aj_port; // PLC 쪽 Port No, IP Address

aj71e71.sin_addr.s_addr = sc.aj_addr.s_addr;

// --------------- 커넥트(Active 오픈 요구) ---------------- //

result = connect(socketno, (LPSOCKADDR)&aj71e71, sizeof(aj71e71));


/*if (connect(socketno, (LPSOCKADDR)&aj71e71, sizeof(aj71e71)) != SOCK_OK)

{

Sockerror(ERROR_CONNECT);

return(SOCK_NG);

printf("AJ_test Start4\n");

}*/


if (result == 0)

{

printf("Connect OK\n");

}

else if (result == SOCKET_ERROR)

{

printf("Connect FAIL\n");

}


Closeflag = FLAG_ON; // 커넥션 종료 플래그 ON


// ----------------이 부분까지 Ethernet과 PLC 연결 부분 ----------------- //


// --------------- D0 ~ D4 일괄 쓰기 요구 ----------------- //

// 송신 데이터를 보내면 " 수신할 수 없습니다, 에러 코드는 0입니다 " 라는 

// 메세지가 나옴 

///*

strcpy(s_buf, "500000FF03FF00002C000A14010000D*0000000005112233445566778899AA");


length = strlen(s_buf);

if (send(socketno, s_buf, length, 0) == SOCKET_ERROR) // 데이터 송신 

{

Sockerror(ERROR_SEND);

return(SOCK_NG);

}

printf("\n 송신 데이터 \n%s\n", s_buf);


length = recv(socketno, r_buf, BUF_SIZE, 0); // 응답 데이터 수신 


if (length = SOCKET_ERROR)

{

Sockerror(ERROR_RECEIVE);

return(SOCK_NG);

}


//r_buf[length] = '\0'; // 수신 데이터 끝에 NULL을 세트


printf("\n 수신 데이터 \n%s\n", r_buf);

//*/

// 위의 부분을 주석 처리후 밑의 읽기 요구는 수신 Data가 들어옴 


// --------------- D0 ~ D4 일괄 읽기 요구 ----------------- //

strcpy(s_buf, "50000FF03FF000018000A04010000D*0000000005");


length = strlen(s_buf);


if (send(socketno, s_buf, length, 0) == SOCKET_ERROR) // 데이터 송신 

{

Sockerror(ERROR_SEND);

return(SOCK_NG);

}


printf("\n 송신 데이터 \n%s\n", s_buf);


length = recv(socketno, r_buf, BUF_SIZE, 0); // 응답 데이터 수신 


if (length == SOCKET_ERROR)

{

Sockerror(ERROR_RECEIVE);

return(SOCK_NG);

}


//r_buf[length] = '\0'; // 수신 데이터의 끝에 NULL을 세트 


printf("\n 수신 데이터 : \n%s\n", r_buf);


if (shutdown(socketno, 2) != SOCK_OK) // 송신 금지 처리 

{

Sockerror(ERROR_SHUTDOWN);

return(SOCK_NG);

}


if (closesocket(socketno) != SOCK_OK)

{

Sockerror(ERROR_CLOSE);

return(SOCK_NG);

}


Closeflag = FLAG_OFF; // 커넥션 종료 플래그 OFF

WSACleanup(); // Winsock.DLL 해제


printf("\nAJ_test End. \n\n 정상 완료했습니다. \n");

printf(" 프로그램을 종료하였습니다, 아무 키나 누르십시오.\n");

Dmykeyin = getchar(); // 키 입력 대기

return(SOCK_OK);

}


void Sockerror(int error_kind) // 에러 처리 함수 

{

if (error_kind == ERROR_INITIAL)

{

printf(" 초기화 처리가 이상합니다.");

}

else

{

nErrorStatus = WSAGetLastError();


switch(error_kind)

{

case ERROR_SOCKET:

printf("소켓을 작성할 수 없습니다.");

break;

case ERROR_BIND:

printf("바인드할 수 없습니다.");

break;

case ERROR_CONNECT:

printf("커넥션을 확립할 수 없습니다.");

break;

case ERROR_SEND:

printf("송신할 수 없습니다.");

break;

case ERROR_RECEIVE:

printf("수신할 수 없습니다.");

break;

case ERROR_SHUTDOWN:

printf("Shutdown할 수 없습니다.");

break;

case ERROR_CLOSE:

printf("정상 클로즈 할 수 없습니다.");

break;

}

}


printf("에러 코드는 %d입니다. \n", nErrorStatus);


if (Closeflag == FLAG_ON)

{

nErrorStatus = shutdown(socketno, 2); // 셧다운 처리 

nErrorStatus = closesocket(socketno); // 클로즈 처리 

Closeflag = FLAG_OFF; // 커넥션 종료 플래그 OFF

}


printf("프로그램을 종료했습니다.아무키나 누르십시오.\n");

Dmykeyin = getchar();

WSACleanup();

return;

}



사업자 정보 표시
가나소프트 | 김용유 | 충남 천안시 동남구 목천읍 서리2길 42-1 | 사업자 등록번호 : 312-33-14797 | TEL : 070-8659-0316 | Mail : contact@gana-soft.com | 통신판매신고번호 : 호 | 사이버몰의 이용약관 바로가기