윈도우에서 리눅스로 압축파일을 보낼 일이 생겨 소스를 찾아 다녔지만..
MFC 또는 C++ 소스를 구하지 못했다(리눅스에서 압축이 풀리는 소스를...)
그래서 만들어보자해서 구조분석을 통해 간단히 압축만 되는 Tar소스를 만들었다.
푸는것은 리눅스 명령어나 윈도우 압축 프로그램으로 그냥 풀리기에...압축만 했다.
| CString형 변수....사용상 주의 할점 한가지 (0) | 2010/03/19 |
|---|---|
| Visual Studio "cmd.exe" 실행 에러 (0) | 2009/03/25 |
| [MFC] Tar 압축 (묶기) (0) | 2008/04/11 |
| DLL의 리소스 가져다 쓰기 (0) | 2008/03/24 |
| [스크랩]DLL리소스에 있는 다이얼로그 생성 (0) | 2008/03/05 |
| [API]간단한 현재 네트워크 연결 상태 확인 소스 (0) | 2008/01/30 |
Tag : C++ / MFC
어느날... DLL의 특정 함수에서 DLL리소스에 있는 다이얼로그를 모달로 띄우려 하는데...
생성이 안되는 것이 아닌가...왜 그런가 찾아 봤더니 글쎄...ㅡㅡ;;
다이얼로그 생성시 넘겨주는 핸들이 잘못되었지 뭐야...
생성하려는 다이얼로그가 위치한곳의 핸들이 필요하더군...
EXE의 다이얼로그라면 EXE의 HINSTANCE가 필요하고 DLL의 다이얼로그라면 DLL의 HINSTANCE가 필요하지...
EXE의 HINSTANCE는 WinMain()에 들어오는 것이고...
DLL의 HINSTANCE는 DllMain()에 들어오는 것이지...
일단 요렇게 해서 전역변수에 dll의 핸들을 저장하고...
BOOL APIENTRY DllMain( HANDLE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved )
{
switch ( ul_reason_for_call )
{
case DLL_PROCESS_ATTACH:
g_hDll = hModule;
break;
}
return TRUE;
}
전역 함수로 어디서든 가져다 쓸수 있게 한다..
HANDLE GetDllHandle()
{
return g_hDll;
}
그리고나서 다이얼로그를 생성할때 첫번째 인자인 HINSTANCE를 저장해둔 넘으러 넘겨준다...
int CDialog::DoModal()
{
return (int) ::DialogBoxParam( (HINSTANCE) GetDllHandle(), MAKEINTRESOURCE( m_nTemplateName ), m_hParentWnd, CDialog::__cbDlgProc, (LPARAM) this );
}
요렇게 하믄 다이얼로그가 정상적으로 뜬다~
보너스로 MFC에서는 아래와 같이 쓰면 된다~
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CDialog dlg;
dlg.DoModal();
이건 여담인데...저렇게 하니깐 다이얼로그가 뜨긴 뜨는데 이상하게 타이틀바나 배경이 안그려 지더군...
왜그런가 했더니 DlgProc에서 기본적으로 false를 리턴해야 시스템에서 처리를 하는데 무조건 true를 넘기니...
시스템이 삐쳐서 안그려주더군...제길...
| [MFC] Tar 압축 (묶기) (0) | 2008/04/11 |
|---|---|
| DLL의 리소스 가져다 쓰기 (0) | 2008/03/24 |
| [스크랩]DLL리소스에 있는 다이얼로그 생성 (0) | 2008/03/05 |
| [API]간단한 현재 네트워크 연결 상태 확인 소스 (0) | 2008/01/30 |
| [API] Winsock을 사용한 간단한 계산 통신 (0) | 2008/01/30 |
| [MFC] INI File 입출력 (0) | 2008/01/29 |
Tag : C++ / MFC
위에 정의된 함수들을 이용해 입출력한다.
ini 파일은 세션명 = 설정값 형식을 갖는다.
보는데로 앞에 Get이 붙은 함수는 읽어오는 함수이고
Write가 붙은 함수는 기록하는 함수이다.
GetPrivateProfileInt 함수는
UINT GetPrivateProfileInt(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
INT nDefault,
LPCTSTR lpFileName
)
형태로 정수형(숫자)값을 읽어온다.
LPCTSTR lpAppName 은 파일안에 []형태로 기록되며
주로 옵션의 그룹명 등으로 사용되어 진다.
LPCTSTR lpKeyName 은 세션의 이름으로 옵션의 이름을 주로 준다.
INT nDefault, 는 세션검색값이 없을때 설정되어지는 기본값이다.
LPCTSTR lpFileName 은 보는그대로 파일명이지만 경로명을 절대값으로 주어야 자신이
원하는 위치에 저장이 가능하다. 그렇지 않으면 윈도우폴더에 기록되어진다.
BOOL WritePrivateProfileString(
LPCTSTR lpAppName,
LPCTSTR lpKeyName,
LPCTSTR lpString,
LPCTSTR lpFileName
);
위의 함수는 기록하는 함수로 위에 설명했던 인자들로 구성되어 있으나 디폴트값이 없고
LPCTSTR lpString,가 위치하고 있다.
이 변수는 저장되어질 문자열 변수의 포인터나 스트링형 변수명을 대입하면 된다.
기록하는 변수는 끝에 Int로 끝나는 함수가 없다. 즉 문자열로 기록한다는 말이다.
위에 두 함수를 가지고 간단한 사용예를 적으면
WritePrivateProfileString("그룹명","키명","값","절대경로명\\파일명.ini");
이렇게 작성하였다면
파일명.ini 안에
[그룹명]
키명=값
형태로 기록이 되어진다.
읽어올때에는
int 변수명 = GetPrivateProfileInt("그룹명","키명","디폴트값(0)","절대경로\\파일명.ini");
파일명.ini 파일에 가서 그룹명으로 먼저 검색을 한 후 키명으로 위치를 찾는다 그리고 값을 읽어와 변수명에 넣어준다.
찾는 키명이 없으면 디폴트값(0)을 변수명에 넣어준다.
| [API]간단한 현재 네트워크 연결 상태 확인 소스 (0) | 2008/01/30 |
|---|---|
| [API] Winsock을 사용한 간단한 계산 통신 (0) | 2008/01/30 |
| [MFC] INI File 입출력 (0) | 2008/01/29 |
| [MFC]CSocket 통신 (0) | 2008/01/23 |
| [MFC]탭컨트롤 (0) | 2008/01/22 |
| 드라이버 학습에 참고 사이트 (0) | 2008/01/21 |
Tag : C++ / MFC
기본적인 화면을 구성하였다는 가정하에
아래 코드를 App클래스의 InitInstance()함수에 추가한다
//소켓 초기화
if (!AfxSocketInit())
{
AfxMessageBox(IDP_SOCKETS_INIT_FAILED);
return FALSE;
}
// OLE 라이브러리를 초기화합니다.
if (!AfxOleInit())
{
AfxMessageBox(IDP_OLE_INIT_FAILED);
return FALSE;
}
CSocket을 상속받은 클래스를 2개 생성한다.
한개의 소켓은 클라이언트가 접속하기를 대기하면서 연결 시키는 역할이고
한개의 소켓은 클라이언트와 데이터를 주고받는 역할을 한다.
(대기 소켓을 ListenSocket, 실 통신을 하는 소켓을 DataSocket 이라 정의 했다 치자)
ListenSocket의 클래스에 OnAccept()함수를 재정의 한다.
DataSocket의 클래스에는 OnClose()와 OnReceive()한수를 재정의한다.
OnClose()는 접속 종료를 알려주는 함수이고
OnReceive()는 메시지를 받는다는 것을 알려주는 함수이다.
서버 프로그램에서 서버를 초기화 한다.
InitServer(void)
{
m_pServer = new ListenSocket;
m_pServer->Create(포트번호);// ??
m_pServer->Listen();
}
클라이언트 초기화
InitClient()
{
pSocket = new Socket();
if(!pSocket->Create())
{
AfxMessageBox(_T("클라이언트 소켓 생성 실패"));
delete pSocket;
return false;
}
if(!pSocket->Connect(아이피주소,포트번호))
{
AfxMessageBox(_T("서버접속실패"));
pSocket->Close();
delete pSocket;
pSocket = NULL;
return false;
}
return true;
}
OnAccept()함수 내에서는 데이타 소켓을 생성해서 클라이언트의 접속을 허용해주고 클라이언트 리스트에 추가해주는 역할을 한다.
EX>
Accept(void)
{
DataSocket* pChild = new DataSocket;
if(!m_pServer->Accept(*pChild))
AfxMessageBox("접속 허용 실패");
m_pSockList.AddTail(pChild);
CString PeerAddr;
UINT PeerPort;
pChild->GetPeerName(PeerAddr, PeerPort); //IP주소와 포트번호를 알아낸다.
CString str;
str.Format("접속 주소: %s, 포트 번호: %d\r\n", PeerAddr, PeerPort);
//로그를 남기고 싶다면 위의 srt변수를 로를 기록하는곳에 넘기면 접속한 클라이언트 정보를 기록한다.
}
OnReceive(){}함수는 데이터를 받는 함수는 클라이언트와 실제 통신을 하는 DataSocket을 이용
데이터를 받는다.
EX>
Receive(DataSocket * pSocket)
{
DWORD FLAG;
pSocket->Receive(&FLAG,4);
}
OnClose()함수는 소켓통신의 끝을 알리는 함수이다.
서버측 : 접속 종료된 클라이언트를 찾아서 메모리 해제
SocketClose(DataSocket * pSocket)
{
DataSocket* pChild;
POSITION pos = m_pSockList.GetHeadPosition();
while( pos !=NULL)
{
pChild = (DataSocket *)m_pSockList.GetAt(pos);
if(pChild == pSocket)
{
m_pSockList.RemoveAt(pos);
CString Log; //로그메시지
CString PeerAddr; //IP주소
UINT PeerPort; //포트번호
pChild->GetPeerName(PeerAddr,PeerPort);
Log.Format("%s : %d Disconnect.",PeerAddr,PeerPort);
//로그파일에 기록하는 위치..
delete pChild;
break;
}
m_pSockList.GetNext(pos);
}
}
클라이언트 측 : 서버와의 접속알림
SocketClose()
{
//서버와 접속이 끊어졌음을 알리는 코드 생성.
}
위에 정의한 코드들은 App클래스에 생성하였으며 해당 코드들을 불러 쓰는 형식을 취하였다.
소켓 클래스에 정의했더
OnAccept 함수에서는 App클래스의 Accept함수를
OnClose함수에서는 App클래스의 SocketClose함수를
OnReceive함수에서는 App클래스의 Receive 함수를 호출하는 형식을 취한다.
인자로 넘기는 DataSocket은 통신하는 클래스가 DataSocket이므로 자신을 인자로 넘겨서
((프로젝트명App*)AfxGetApp())->Receive(this); 이런식으로 호출하면 가능하다.
클라이언트 측에서는 통신하는 소켓이 하나면 되므로 소켓에서 App에 정의한 함수를 호출할때
인자를 넘겨주는 식으로 하지 않아도 된다.
| [API] Winsock을 사용한 간단한 계산 통신 (0) | 2008/01/30 |
|---|---|
| [MFC] INI File 입출력 (0) | 2008/01/29 |
| [MFC]CSocket 통신 (0) | 2008/01/23 |
| [MFC]탭컨트롤 (0) | 2008/01/22 |
| 드라이버 학습에 참고 사이트 (0) | 2008/01/21 |
| 파일검색 루틴 (0) | 2008/01/18 |
1. 기본 다이얼로그 창에 탭컨트롤을 배치한다.
2. 탭컨트롤 변수를 생성한다 : 변수는 컨트롤 변수로 생성
3. 탭컨트롤의 탭 화면으로 사용될 다이얼로그를 생성한다. : 클래스까지 선언
다이얼로그의 속성중 Boder 속성은 None으로 설정 : None으로 주는 까닭은 다이얼로그 테두리가
안보이게 하기 위해서이다.
Style은 Child 속성으로 설정한다.
4. 탭컨트롤의 탭 타이틀을 설정한다.
TCITEM형 탭컨트롤아이템변수를 선언하고
탭컨트롤아이템변수.mask = TCIF_TEXT ; : 텍스트로 설정 -> 다른속성도 있음
탭컨트롤아이템변수.pszText = "탭컨트롤명"; 으로 설정한후
탭컨트롤변수.InsertItem(인덱스 번호,&탭컨트롤아이템변수);를 이용 탭컨트롤에 탭 추가
5. 탭 컨틀롤에 보여질 다이얼로그 화면을 생성.
다이얼로그클래스변수.Create(다이얼로그 ID,부모 윈도우(보통 this)); //생성
6.위치를 잡아준다. 위치를 잡아주기 위해서는
다이얼로그클래스변수.SetWindowPos()를 사용하여 위치를 정해준다.
ex>
CRect m_rClientRect;
탭컨트롤변수.GetItemRect(0,m_rClientRect);
다이얼로그클래스변수.SetWindowPos(&wndTop, m_rClientRect.left+10, m_rClientRect.bottom + 10, 0, 0, SWP_NOSIZE);
7. 이제 탭 화면을 보여주기만 하면된다. 한번에 하나의 화면을 보여주어야 하기 때문에 탭선택에 따라
화면을 보여주도록 설정하는것이 좋다.
// 해더위치에 선언
void ChangeTab(int nIndex);
//CPP파일에 생성
void 클래스명::ChangeTab(int nIndex)
{ //초기에는 화면을 숨긴다. 여려화면이라면 다 숨기도록 하자
다이얼로그클래스변수.ShowWindow(SW_HIDE);
switch(nIndex)
{
case 0 : //첫번째 탭선택;
{ //첫번째 탭에 해당하는 다이얼로그 보여주기
다이얼로그클래스변수.ShowWindow(SW_SHOW);
break;
}
}
}
탭 SELCHANGE이벤트가 발생하였을때
탭의 선택 셀 번호를 가져와서 위의 함수 인자로 넘겨주면 탭선택시의 화면이 화면에 보여지게 된다.
탭의 선택셀값을 가져오기 위해서는 탭컨트롤변수.GetCurSel()를 사용하면 선택한 셀을 얻을 수 있다.
| [MFC] INI File 입출력 (0) | 2008/01/29 |
|---|---|
| [MFC]CSocket 통신 (0) | 2008/01/23 |
| [MFC]탭컨트롤 (0) | 2008/01/22 |
| 드라이버 학습에 참고 사이트 (0) | 2008/01/21 |
| 파일검색 루틴 (0) | 2008/01/18 |
| [MFC]콘트롤의 사이즈나 위치 변경시 깜박임 현상 줄이기 (0) | 2007/10/01 |
Tag : C++ / MFC
콘트롤들의 위치나 크기를 변경하고자 할 때 통상 SetWindowPos()나 MoveWindow() 함수를 이용합니다.
그런데 이 함수들은 각각의 콘트롤들이 개별적으로 그려지기 때문에 화면 깜박임이 심합니다.
이럴때 BeginDeferWindowPos(), DeferWindowPos(), EndDeferWindowPos()라는 Window API 함수를 써보세요. 자세한 사용법은 Help를 보시면 되지만 간단히 요약하면
HDWP hdwp = ::BeginDeferWindowPos (2);
::DeferWindowPos (hdwp, ctrl1.GetSafeHwnd (), HWND_TOP,
Rect1.left, Rect1.top, Rect1.Width (), Rect1.Height (),
SWP_NOZORDER | SWP_SHOWWINDOW);
::DeferWindowPos (hdwp, ctrl2.GetSafeHwnd (), HWND_TOP,
Rect2.left, Rect2.top, Rect2.Width (), Rect2.Height (),
SWP_NOZORDER | SWP_SHOWWINDOW);
::EndDeferWindowPos (hdwp);
이러면 각 콘트롤의 위치와 크기가 결정된후, 한꺼번에 갱신되기 때문에 화면 깜박임이 훨씬 줄어듭니다.
화면 깜박임을 없애는 가장 간단하면서도 강력한 방법은 WS_CLIPCHILDREN을 사용하는 방법입니다.
다이얼로그 리소스의 프로퍼티에서 WS_CLIPCHILDREN이라는 style만 추가해주시면 대부분의 컨트롤들이 깜박거리지 않으면서 리사이징 됩니다.
| 드라이버 학습에 참고 사이트 (0) | 2008/01/21 |
|---|---|
| 파일검색 루틴 (0) | 2008/01/18 |
| [MFC]콘트롤의 사이즈나 위치 변경시 깜박임 현상 줄이기 (0) | 2007/10/01 |
| [MFC]타이틀바 제거 (0) | 2007/09/30 |
| 파일명 바꾸기 간단소스 (0) | 2007/09/18 |
| [API] Msn 메신저(모양은 NateOn) (0) | 2007/01/31 |
MainFrame에 다음을 재정의 해준다.
해더파일
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle , CWnd* pParentWnd , CCreateContext* pContext);
CPP파일
BOOL CMainFrame::LoadFrame(UINT nIDResource, DWORD dwDefaultStyle , CWnd* pParentWnd , CCreateContext* pContext)
{
// TODO: 여기에 특수화된 코드를 추가 및/또는 기본 클래스를 호출합니다.
BOOL bRet = CFrameWnd::LoadFrame(nIDResource, dwDefaultStyle, pParentWnd, pContext);
if(bRet)
{
ModifyStyle(WS_CAPTION,0,SWP_FRAMECHANGED);
}
return bRet;
}
다음 왼쪽마우스 버튼다운의 재정의 후 다음을 추가
CPoint pt = point;
ClientToScreen(&pt);
PostMessage(WM_NCLBUTTONDOWN,HTCAPTION,MAKELPARAM(pt.x,pt.y));
다음 HITTEST재정의 후
리턴값을 HTCAPTION으로 수정
| 파일검색 루틴 (0) | 2008/01/18 |
|---|---|
| [MFC]콘트롤의 사이즈나 위치 변경시 깜박임 현상 줄이기 (0) | 2007/10/01 |
| [MFC]타이틀바 제거 (0) | 2007/09/30 |
| 파일명 바꾸기 간단소스 (0) | 2007/09/18 |
| [API] Msn 메신저(모양은 NateOn) (0) | 2007/01/31 |
| 2005의 void 버그 에러 (0) | 2007/01/25 |
Tag : C++ / MFC