공룡호가 사는 세상 이야기

MFC에서는 모든 문자열 메시지는 CString type로 변환하여 처리해야 한다.
문자열 메시지를 사용하는 Chatting Program에서 채팅 메시지를 전달할 경우,
메시지를 표현하는 Form의 가로크기 (이를테면 ListBox의 width size) 보다 메시지가 길 경우,
적절하게 String을 Cutting해 주어야 하는데, 1byte 문자와 2bytes 한글문자의 판단을 올바로 해 주지 않으면 2bytes를 이용하여 하나의 문자열을 표현하는 Character에서는 오류가 생긴다.

예를 들어,
" abcdef안녕하세요123 " 이라는 문자열이 있다고 가정하고,
이 메시지가 Form크기보다 커져, 11byte번째에서 잘라주어야 한다고 가정한다.
그러나 사실 자세히 보면, 11byte번째는 한글문자 '하'를 표현하는 2개의 byte중 앞쪽 byte를 사용하는 것을 알 수 있다.
따라서, 11byte번째에 강제로 개행을 한다거나 개행문자를 삽입하면 한글문자 '하'는 깨질 수 밖에 없다.

이런경우, 특정부분까지(여기에서는 11바이트) 전송하고 잘라야 할 부분의 byte가 한글인지 판단하여 2바이트씩 잘라주어야 한글이 깨지지 않는다.

한글판단은 어렵지 않다.
USER가 입력할 수 있는 문자들 중 '영문자'와 '특수문자'는 모두 ASCII CODE TABLE에 존재한다. 따라서 양수값으로 모두 존재한다는 의미가 된다.

실제로, 상단에 있는 "abcdef안녕하세요123"을 값으로 하는 Array를 정수로 출력해 보면,
한글이 있는 부분을 제외한 다른 모든 부분은 양수값을 가진다.
한글은 ASCII CODE가 아닌 유니코드 따위를 사용하므로, ASCII CODE TABLE에 존재하지 않는다. 따라서 값은 모두 음수가 출력이 된다.

해당 Byte의 '양/음'을 비교하여 한글을 판단하면 된다.
다음은 채팅 프로그램에서 해당 문자열 메시지를 일정 부분부터 잘라서 전송하는 방법이다.

위의 그림과 같이 메시지가 있다고 가정하고, 처음부터 ~ 2번까지의 크기가 채팅 LIST FORM의 크기라고 가정하자.
그럼 2번까지 무조건 전송하고 나머지를 잘라서 전송하면 되지만 위에서 설명했듯이, 해당 데이터가 한글 데이터일 경우 깨지게 되는 현상이 발생한다.

따라서, 잘라야 할 해당 Byte가 한글을 형성하는 2바이트중의 하나인 부분바이트인지를 판단하여, 적절하게 잘라주면 된다.
하지만 또다른 문제가 발생한다. 잘라내야 하는 부분의 해당 byte가 한글을 형성하는 일부라고 판단되었는데, 이것이 한글의 2bytes중, 전반부 byte인지 후반부 byte인지를 모른다는 점이다.
한글인지 판단은 하였으나, 잘라내야 할지, 잘라내지 말아야 할지 판단해야 하는 문제가 남아있다. 따라서 위 그림에서 3번의 byte가 한글 bytes라면 앞쪽에 위치하는 1, 2번을 보지 않을 수 없다.
알고리즘은 다음과 같다.

if (3 < 0 && 2 < 0 && 1 > 0 ) // 2+3 = 한글
    메시지 += 3;

3번이 한글이라면 2번을 봅니다.
2번도 한글이라면 2+3이 한글일 확률이 있으나, 1번도 음수라면 1번도 한글의 부분 byte이다.
따라서 1번이 양수라면, 2번과 3번을 합하여 하나의 한글을 형성하므로 3번까지 잘라내면 된다.
써놓고 보니 길어졌는데, 간단한 방법이다.

덧붙이자면, ascii code table에 존재하지 않는 한글을 정수값으로 출력하면 음수가 나오는 이유와 음수값의 의미는 무엇을 뜻하는지 아직 잘 모르겠다. -_-;

Anonymous Class

프로그래밍2006. 8. 8. 19:39

일반적으로 클래스는 일단 정의된 후에 new연산자를 통해서 생성하게 된다.
그러나 내부 무명 클래스는 정의하는 부분과 생성하는 부분이 하나에 묶여져 있다. 내부 무명 클래t스는 new연산자의 확장을 이용하여 다음과 같은 형식으로 사용되며 생성된 결과는 상위클래스 래퍼런스가 반환된다.
형식을 보면 알수 있듯이 내부 무명 클래스는 정의와 생성이 한곳에서 일어나므로 클래스의 이름이 없다. 즉 클래스의 인스턴스만이생성된다. 한가지 주의점은 new의 확장이기 때문에 세미콜론은 반드시 붙여야 한다는 것이다.

new 상위크래스_이름(생성자의 인자)
{
클래스 정의
};

외울것
addWindowListener(new WindowAdaper(){
public void windowClosing(WindowEvent evt){
}
}
);

MFC에서는 CAsyncSocket 라는 클래스를 기반으로 소켓을 정의해둠
CAsyncSocket에서는 Create() / Bind() / Listen() / Accept() / Connect() .. ETC

::Server
Create() 소켓 생성
Bind() 포트 지정
Listen() Connect() 신호대기 및 연결
Accept() 접근를 수락

::Client
Create() 소켓 생성
Connect() 서버로 접속 신호 보냄


'프로그래밍' 카테고리의 다른 글

in String 2Bytes 한글 판단법 - 메모  (0) 2006.09.05
Anonymous Class  (0) 2006.08.08
MFC - Chatting 기본 컨트롤 관련 및 복습  (1) 2006.07.21
WINSOCK ERROR  (0) 2006.07.19
CMemFile Class  (0) 2006.06.10

공부한 것들 이제 정리한다 -_-;;
열심히 살겠다고 약속했다. 살길은 공부 뿐..

#1
in Unix -> file scripter
command line : "script" , "exit" use;
(Unix에서 화면 갈무리 방법)

#2
키보드 포커스를 얻는 법.
해당 컨트롤러에 컨트롤 변수를 추가한 후,
Control_Variable.SetFocus(); 함수를 호출한다.
호출 시점은 해당 컨트롤러 생성 이후.

#3
CString chat;                                    //Initialize chat variable
m_InputChat_C.GetWindowText(chat); //Get Text for 'editbox'
m_ChatView.AddString(chat);            //Send the Text of 'Getted Text'

#4 (by snbosoft.com)
CDialog 에서 IDOK에 대한 디폴트 키로서, Return 키가 할당되어있다.
비슷하게 Esc도 같은 기능인데, 원하지 않는 시점에서 프로그램이 종료될 수 있다.

이는 PretranslateMessage() 에서 메세지를 후킹함으로서 간단히 해결된다.

BOOL CTestDlg::PreTranslateMessage(MSG* pMsg)
{
  if( pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN )
    return TRUE;

  return CDialog::PreTranslateMessage(pMsg);
}

#5
CWnd *pWnd = CWnd::GetDlgItem(해당 컨트롤러ID); //get pointer of 'editbox'
pWnd->SetWindowText(_T("초기화할 문자열")); //Re-Initialize of 'editbox'

#6
버튼 활성화/비활성화 방법(MFC)
해당 버튼의 컨트롤 변수를 만든 다음,

Control_Variable.EnableWindow(진리값);

진리값이 TRUE일 경우 = 비활성화 버튼을 활성화로
        FALSE일 경우 = 활성화 버튼을 비활성화로

#7 (About Button activation)
BOOL EnableWindow(
  HWND hWnd,     // handle to window
  BOOL bEnable   // flag for enabling or disabling input
);

함수는 리턴값이

If the window was previously disabled, the return value is nonzero.
If the window was not previously disabled, the return value is zero. To get extended error information, callGetLastError.

이므로, 비활성화시, nonzero를 리턴한다.
즉, 이 함수를 이용하여 체크를 하면 그만이다. 다시 돌려놓으면 되니까..
다른 함수가 있을려나 -_-?

if((Control_Variable.EnableWindow(FALSE)))  //Running Server

else       //or, not
//to do
Control_Variable.EnableWindow(TRUE);

'프로그래밍' 카테고리의 다른 글

Anonymous Class  (0) 2006.08.08
MFC - CAsyncSocket CLASS  (0) 2006.08.06
WINSOCK ERROR  (0) 2006.07.19
CMemFile Class  (0) 2006.06.10
습관  (0) 2006.06.06

WINSOCK ERROR

프로그래밍2006. 7. 19. 05:27
IN Network Programming
project settings (ALT+F7)에 Link TAB - Object/Library Modules
ws2_32.lib - ADD

'프로그래밍' 카테고리의 다른 글

MFC - CAsyncSocket CLASS  (0) 2006.08.06
MFC - Chatting 기본 컨트롤 관련 및 복습  (1) 2006.07.21
CMemFile Class  (0) 2006.06.10
습관  (0) 2006.06.06
printf() flags  (0) 2006.05.23

CMemFile Class

프로그래밍2006. 6. 10. 17:30

::CMemFile Class

메모리에 파일을 생성.
일시적으로 사용할 파일 등을 생성할 때 유용할 것 같아서.
객체를 만들면 바로 사용가능하며, 그 밖에 입출력 함수는 CFile 클래스와 동일.

//Example
void CExFileView::OnLButtonDblClk(UINT nFlags, CPoint point)
{
//Create Object
CMemFile file;

//Write to Memory
int temp = 100;
file.Write(&temp, sizeof(temp));

//Read from Memory
file.SeekToBegin();
file.Read(&temp, sizeof(temp));
TRACE("temp = %d\n", temp);
}

'프로그래밍' 카테고리의 다른 글

MFC - Chatting 기본 컨트롤 관련 및 복습  (1) 2006.07.21
WINSOCK ERROR  (0) 2006.07.19
습관  (0) 2006.06.06
printf() flags  (0) 2006.05.23
fopen() 제발 그만 까먹자.. 제발 좀.  (0) 2006.05.04

습관

프로그래밍2006. 6. 6. 18:20

1. 주석은 반드시 필요한 부분만 달 것.
2. 함수의 첫 머리에는 파라미터와 연산내용 그리고 리턴값을 명시.
3. 생각 없이 코딩부터 시작하는 일은 금물.
4. 디버깅을 위한 코드를 만들어 놓을 것.
5. 메모리 참조와 누수에 항상 신경쓸 것.
6. 자료구조와 알고리즘에 대한 훈련을 게을리 하지 않을 것.
7. 코딩 실력은 코딩 연습의 양에 절대적으로 비례한다는 사실을 잊지 말 것.
8. 프로그래밍이 아름다운 예술이라는 지금의 생각을 잊지 말고 살 것.

'프로그래밍' 카테고리의 다른 글

WINSOCK ERROR  (0) 2006.07.19
CMemFile Class  (0) 2006.06.10
printf() flags  (0) 2006.05.23
fopen() 제발 그만 까먹자.. 제발 좀.  (0) 2006.05.04
Data of Decision Tree (GPS)  (0) 2006.05.03

printf() flags

프로그래밍2006. 5. 23. 10:48
printf() flags list.

%d - decimal
%o - octal
%x - hexadecimal
%p - Address

'프로그래밍' 카테고리의 다른 글

CMemFile Class  (0) 2006.06.10
습관  (0) 2006.06.06
fopen() 제발 그만 까먹자.. 제발 좀.  (0) 2006.05.04
Data of Decision Tree (GPS)  (0) 2006.05.03
Windows Prog. DataType  (3) 2006.03.28

Prototype
FILE *fopen(
  const char *filename,
  const char *mode
);
FILE *_wfopen(
  const wchar_t *filename,
  const wchar_t *mode
);

Parameters
filename -> Filename.
mode -> Type of access permitted.

Return Value
Each of these functions returns a pointer to the open file. A null pointer value indicates an error.

Remarks
The fopen function opens the file specified by filename.
_wfopen is a wide-character version of fopen;
the arguments to _wfopen are wide-character strings.
_wfopen and fopen behave identically otherwise.

제발 그만 좀 까먹자.. 진짜 .. 이젠 막 짜증난다. open mode를 잘못 설정하는 바람에 오늘도 3시간 삽질.
더욱 자세한 것은 MSDN 참조.

The character string mode specifies the type of access requested for the file, as follows:
"r"
Opens for reading. If the file does not exist or cannot be found, the fopen call fails.
"w"
Opens an empty file for writing. If the given file exists, its contents are destroyed.
"a"
Opens for writing at the end of the file (appending) without removing the EOF marker before writing new data to the file; creates the file first if it doesn't exist.
"r+"
Opens for both reading and writing. (The file must exist.)
"w+"
Opens an empty file for both reading and writing. If the given file exists, its contents are destroyed.
"a+"
Opens for reading and appending; the appending operation includes the removal of the EOF marker before new data is written to the file and the EOF marker is restored after writing is complete; creates the file first if it doesn't exist.

'프로그래밍' 카테고리의 다른 글

습관  (0) 2006.06.06
printf() flags  (0) 2006.05.23
Data of Decision Tree (GPS)  (0) 2006.05.03
Windows Prog. DataType  (3) 2006.03.28
널문자가 존재하는 이유  (0) 2006.03.07

Data of Decision Tree (GPS)

'프로그래밍' 카테고리의 다른 글

printf() flags  (0) 2006.05.23
fopen() 제발 그만 까먹자.. 제발 좀.  (0) 2006.05.04
Windows Prog. DataType  (3) 2006.03.28
널문자가 존재하는 이유  (0) 2006.03.07
객체를 (파라메터/리턴값)으로 사용하는 함수  (0) 2006.03.03