Programming/Assembly2008. 9. 15. 12:30
vc++ project setting 메뉴에서

c/c++탭의 category를 listing files로 선택하신후 아래쪽에

listing file type 에서 원하시는 형태를 선택하시면 컴파일

시 자동으로 어셈코드를 만들어 준답니다.(vc++ 6.0기준)
Posted by skensita
Programming/Win32 API2008. 9. 12. 16:33
SendMessage(hwnd, WM_LBUTTONUP, (WPARAM)0, MAKELPARAM(posx1,posy1));

이런식으로 LPARAM을 만들어 보낼 수 있다.
Posted by skensita
Programming/MFC2008. 9. 8. 15:22

Visual C++ 완벽가이드 PPT
Posted by skensita
Programming/MFC2008. 9. 6. 16:31

Connection 객체

 
Connection 객체는 ODBC 데이타 소스와 연결할 때 사용한다.

 
프로퍼티 설명
Attributes 객체에 대한 하나이상의 특성을 나타낸다.
CommandTimeout 명령이 실행되는 최대 시간을 지정한다. 만약 시간이 경과되면 오류를 발행한다.
ConnectionString 데이타 소스와 연결할 때 사용하는 연결정보를 저장한다.
ConnectionTimeout 데이타 소스와 연결할 때 최대 대기 시간을 지정한다.
DefaultDatabase Connection 객체에 대한 기본 데이타베이스를 지정한다.
IsolationLevel Connection 객체에 대한 격리 레벨을 지정한다.
Mode Connection 객체에서 데이타의 변경에 대한 권한을 지정한다.
Provider Connection 객체의 Provider 이름을 나타낸다.
Version ADO의 버젼을 나타낸다.

메소드 설명
BeginTrans 새로운 트랜젝션을 시작한다.
CommitTrans 현재 트랜젝션에서 일어난 변경사항을 저장하고 트랙젝션을 닫는다.
그리고 새로운 트랜젝션을 다시 시작한다.
RollbackTrans 현재 트랜젝션에서 일어난 변경사항을 취소하고 트랙젝션을 닫는다.
그리고 새로운 트랜젝션을 다시 시작한다.
여기서 트랜젝션은 데이타베이스에 가하는 일련의 작업 집합을 말한다.
Open 데이타 소스에 연결한다.
Close 데이타 소스로의 연결을 종료한다.
Execute 지정된 쿼리, SQL 문장 또는 Stored Procedure를 실행한다.
 

 Error 객체

 
ADO의 명령수행중에 발생한 오류에 대한 정보를 담고 있다.

 
프로퍼티 설명
Number 오류 번호
Description 오류에 대한 설명
Source 오류를 발생시킨 객체의 이름을 나타낸다.
HelpFile 오류와 관련된 도움말 파일의 이름을 나타낸다.
HelpContext 오류와 관련된 도움말의 컨텍스트 ID를 나타낸다.
SQLStatus SQL 상태를 나타내는 길이가 5인 문자열을 리턴한다.
NativeError 데이타베이스에서 정의한 오류 번호를 리턴한다.
 

 Command 객체

 
Command 객체는 데이타 소스로 부터 실행할 명령을 정의한다.

 
프로퍼티 설명
ActiveConnection 데이타 소스에 연결된 Connection객체로 Command 객체는 이 연결객체를 통해서 명령을 실행한다.
CommandText 실행할 SQL 문장이나 테이블 이름, 또는 스토어드 프로시져
CommandTimeout 명령이 실행되는데 걸리는 최대 대기 시간을 나타낸다.
CommandType Command 객체의 종류를 지정한다.
Prepared 명령을 실행하기 전에 준비된 문장을 생성할 것인지를 지정한다.

메소드 설명
CreateParameter 새로운 파라메터 객체를 생성한다.
Execute CommandText에서 지정한 쿼리, SQL 문장, 또는 스토어드 프로시듀어를 실행한다.
 

 Parameter 객체

 
파라메터 객체는 파라메터를 가지는 쿼리나 스토어드 프로시듀어를 담고있는 커멘드 객체와 함께 사용된다.

 
프로퍼티 설명
Attributes 파라메터의 속성을 나타내며, adParamSigned, adParamNullable, adParamLong과 같은 값들을 혼합하여 지정할 수 있다.
Direction 파라메터가 입력 파라메터인지 출력 파라메터인지 등을 지정한다.
Name 파라메터 객체의 이름을 나타낸다.
NumericScale 숫자형 파라메터에서 소수점 뒷자리수를 결정한다.
Precision 숫자형 파라메터에서 최대 자리수를 결정한다.
Size 파라메터 값의 바이트 수 또는 문자열 수를 지정한다.
Type 파라메터 값의 데이터 형을 지정한다.
Value 파라메터의 값을 나타낸다.

메소드 설명
AppendChunk 긴 문자열이나 바이너리 타입의 파라메터 객체에 데이터를 추가한다.
 

 Recordset 객체

 
프로퍼티 설명
AbsolutePage 레코드의 절대 페이지를 나타낸다.
만약 여기에 새로운 값을 지정하면, 현재 레코드의 위치가 해당 페이지의 첫 레코드로 이동한다.
페이지란 순차적으로 일정 개수만큼 레코드들을 묶어놓은 단위이다.
페이지는 기본 값으로 10개의 레코드를 가진다.
AbsolutePosition 현재 레코드의 절대 위치를 나타낸다.
첫 레코드의 AbsolutePosition은 1이다.
ActiveConnection 현재 레코드셋이 연결된 Connection 객체를 나타낸다.
BOF, EOF BOF는 현재 레코드가 첫 레코드의 이전에 있는지를 나타낸다.
EOF는 현재 레코드가 마지막 레코드의 다음에 있는지를 나타낸다.
Bookmark 레코드셋에서 현재 레코드의 위치를 저장하고 언제라도 그 위치로 이동할 수 있다.
CacheSize 로컬 메모리에 저장할 레코드의 개수를 지정한다.
CacheSize의 기본값은 ForwardOnly 커서를 가진 레코드 셋의 경우 1이고, 그 외의 경우에는 모두 10의 값을 갖는다.
CursorType 레코드 셋에서 사용할 커서의 유형을 정한다.
커서란 레코드 셋에서 현재 레코드를 가리키는 포인터를 말하고, 커서의 유형은 아래와 같은 유형이 있으며 각각 다른 특성을 가진다.
커서 유형 지원 기능
AdOpenForwardOnly None
AdOpenKeyset adBookmark, adHoldRecords, adMovePrevious, adResync
AdOpenDynamic adMovePrevious
AdOpenStatic adBookmark, adHoldRecords, adMovePrevious, adResync
EditMode 현재 레코드의 편집 상태를 나타낸다.
Filter 레코드셋 객체 안에서 선택적으로 레코드들을 화면에 표시할 때 사용한다.
LockType 레코드를 편집하는 동안 설정할 락 유형을 결정한다.
MaxRecords 쿼리 실행후에 리턴될 최대 레코드 수를 지정한다.
PageCount 레코드셋이 포함하고 있는 페이지 수를 지정한다.
PageSize 페이지당 레코드 수를 결정한다.
RecordCount 레코드셋 객체의 총 레코드 수를 리턴한다.
Source 레코드셋 안의 데이터가 어디로부터 왔는지를 나타낸다.
Status 순차적 업데이트또는 기타 작업에 대한 현재 레코드의 상태를 나타낸다.

메소드 설명
AddNew 레코드셋에 새로운 레코드를 생성한다.
CancelBatch 진행중인 순차 업데이트를 취소한다.
CancelUpdate AddNew나 Edit로 변경한 레코드의 업데이트를 취소한다.
Clone 존재하는 레코드셋의 복사하여 새로운 레코드셋을 생성한다.
Close 열려진 레코드셋을 닫는다.
Delete 레코드셋에서 현재 레코드를 삭제한다.
GetRows 레코드셋에서 여러 개의 레코드를 읽어서 배열에 저장한다.
Move 레코드셋에서 현재 레코드를 이동시킨다.
MoveFirst 현재 레코드를 첫 레코드로 이동시킨다.
MoveLast 현재 레코드를 마지막 레코드로 이동시킨다.
MoveNext 현재 레코드를 다음 레코드로 이동시킨다.
MovePrevious 현재 레코드를 이전 레코드로 이동시킨다.
NextRecordset 현재 레코드셋을 종료하고 다음 레코드셋을 리턴한다.
Open 쿼리나 SQL의 실행한 결과를 가져온다.
Requery 쿼리를 다시 실행하여 레코드셋을 최신 정보로 고친다.
Resync 데이터베이스로부터 현재 레코드셋의 데이터를 최신 정보로 갱신한다.
Supports 레코드셋이 특정 기능을 지원하는지를 결정한다.
Update 현재 레코드의 변경사항을 레코드셋 객체에 저장한다.
UpdateBatch 진행중인 모든 순차 업데이트 작업을 디스크로 저장한다.
 

 Field 객체

 
필드 객체는 레코드셋 객체의 각 필드를 표현하는 객체이다.
레코드셋은 필드 객체들의 모임인 Fields 컬렉션을 가진다.
필드 객체는 레코드셋에 저장되어 있는 실질적인 값들에 접근할 수 있는 방법을 제공한다.
필드 객체에 대한 문법은 아래와 같이 다양한다.

Recordset.Fields.Item(0)
Recordset.Fields.Item("Name")
Recordset.Fields(0)
Recordset.Fields("Name")
Recordset(0)
Recordset("Name")
Recordset![Name]

 
프로퍼티 설명
ActualSize 필드 값의 실제 길이를 나타낸다.
Attributes 필드 객체의 속성을 나타낸다.
DefinedSize 필드 객체의 정의된 길이를 나타낸다.
Name 필드의 이름을 나타낸다.
NumericScale 숫자형 필드의 소수점 이하 자리수를 나타낸다.
OriginalValue 필드의 값이 변하기 전에 원래의 값을 나타낸다.
Precision 숫자형 필드의 최대 자리수를 나타낸다.
Type 필드 객체의 데이터 타입을 나타낸다.
UnderlyingValue 데이터베이스 내의 현재 필드의 값을 나타낸다.
Value 필드의 값을 나타낸다.

메소드 설명
AppendChunk 데이터를 긴 문자열이나 바이너리 타입의 필드 객체에 추가한다.
GetChunk 긴 문자열이나 바이너리 타입의 필드 객체에서 전부 또는 일부 내용을 리턴한다.
 

 Property 객체

 
프로퍼티 설명
Attributes 프로퍼티 객체의 속성을 나타낸다.
Name 프로퍼티의 이름을 나타낸다.
Type 프로퍼티의 데이터 타입을 나타낸다.
Value 프로퍼티의 값을 나타낸다.
Posted by skensita
Programming/MFC2008. 9. 6. 16:30

ADO를 이용한 삽입, 삭제, 업뎃



void CTestADODlg::OnButton3()
{
 // DAO (Access2000) 이후 버젼 리딩가능
 AfxGetModuleState()->m_dwVersion = 0x0601;
 
 // COM이나 OLE를 라이브러리를 초기화한다.
 AfxOleInit();
 
 
 // ADO에 Connection 객체 사용
 _ConnectionPtr pConn;  
 HRESULT hr;
 BOOL IsConnectionOpen = FALSE;
 
 // DB를 열기 위한 예의상 구문으로 인식하고 넘어가자.
 
 CoInitialize(NULL);
 hr = pConn.CreateInstance(__uuidof(Connection));
 //pConn->CursorLocation =adUseClient;
 
 // 데이터베이스 접속
 if(SUCCEEDED(hr))
 {
  // Provider: 여기서는 mdb를 사용하므로, Microsoft.Jet.OLEDB.4.0를 선택한다.
  // Data위치: c:\\TestDb.mdb
  _bstr_t strMode("Provider=Microsoft.Jet.OLEDB.4.0;Data Source= d:\\dbTest.mdb;");
  try
  {
   hr = pConn->Open(strMode,_bstr_t(L""),_bstr_t(L""), -1);
  }
  catch(_com_error& e)
  {
   AfxMessageBox(e.Description());
   AfxMessageBox(e.ErrorMessage());  
  }
 }
 if(SUCCEEDED(hr))
 {
  AfxMessageBox("데이터베이스 연결됨");
  IsConnectionOpen = TRUE;
 }
 
 // 데이터베이스에 연결이 되었다면,
 if(IsConnectionOpen)
 {
  _RecordsetPtr pRs;
  hr = pRs.CreateInstance(__uuidof(Recordset));
  _bstr_t strQuery("Select * from tblTest");
     
  // INSERT 구문
  try
  {
   // 테이블명(tbltest)에서 필드ID에 200, Checker에 300을 삽입한다.
   _bstr_t bstrQuery("INSERT INTO tbltest(ID,Checker) values('200','300')");
   
   // 0L에서 0은 int형 0L은 long형을 의미한다.
   // long형이 int 보다 더 큰수 저장가능

   _variant_t valValue(0L);


   // 새로운 트랜젝션을 시작한다.
   pConn->BeginTrans();
   pRs = pConn->Execute((_bstr_t)bstrQuery, &valValue, adOptionUnspecified);


   // 현재 트랜젝션에서 일어난 변경을 저장하고 트랜젝션을 닫고
   // 새로운 트랜젝션을 시작한다.
   pConn->CommitTrans();
 
  }
  catch(_com_error& e)
  {
   AfxMessageBox(e.Description());
   AfxMessageBox(e.ErrorMessage());  
  }
 
 
  // UPDATE 구문
  try
  {
   // 필드명 ID의 값이 2인 모든 곳의 필드명 ID, Checker의 필드값을 변경
   _bstr_t bstrQuery2("UPDATE tbltest SET ID = 2000 , Checker = 300 WHERE ID = 2 ");
   _variant_t valValue2(0L);
   pConn->BeginTrans();
   pConn->Execute((_bstr_t)bstrQuery2, &valValue2, adOptionUnspecified);
   pConn->CommitTrans();
 
  }
  catch(_com_error& e)
  {
   AfxMessageBox(e.Description());
   AfxMessageBox(e.ErrorMessage());  
  }
 

  // DELETE 구문
  try
  {
   // ID가 200인 tbltest 테이블 내의 Record를 삭제.
   _bstr_t bstrQuery3("DELETE FROM tbltest WHERE ID = 200 ");
   _variant_t valValue3(0L);


  pConn->BeginTrans();
   pConn->Execute((_bstr_t)bstrQuery3, &valValue3, adOptionUnspecified);
   pConn->CommitTrans();
 
  }
  catch(_com_error& e)
  {
   AfxMessageBox(e.Description());
   AfxMessageBox(e.ErrorMessage());  
  }
 }
}

Posted by skensita
Programming/MFC2008. 9. 6. 16:30

MS Access로 mdb를 만들었다고 가정하고 시작해본다.

ADO를 사용하기 위해서는 가령 작업하고 있는 파일(TestADODlg.cpp/TestADODlg.h),

라면 다음과 같은 선언을 상단에 우선적으로 해야한다.



(Step1) - 헤더파일

#if !defined(AFX_TESTADODLG_H__4B76919F_E8B6_4E36_92B4_4F549B5272FC__INCLUDED_)
#define AFX_TESTADODLG_H__4B76919F_E8B6_4E36_92B4_4F549B5272FC__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#import "C:\Program Files\Common Files\System\ADO\msado15.dll" rename("EOF", "EndOfFile")
using namespace ADODB;
// #import "C:\Program Files\Common Files\System\ADO\msado15.dll"no_namespace

// rename("EOF", "EndOfFile")


 

(Step2)

void CTestADODlg::OnTestADO()
{
 
 // DAO (Access2000) 이후 버젼 리딩가능
 AfxGetModuleState()->m_dwVersion = 0x0601;
 
 // COM이나 OLE를 라이브러리를 초기화한다.
 AfxOleInit();
 
 
 // ADO에 Connection 객체 사용
 _ConnectionPtr pConn;  
 HRESULT hr;
 BOOL IsConnectionOpen = FALSE;
 
 // DB를 열기 위한 예의상 구문으로 인식하고 넘어가자. 
 CoInitialize(NULL);
 hr = pConn.CreateInstance(__uuidof(Connection));
 pConn->CursorLocation = adUseClient;
 
 // 데이터베이스 접속
 if(SUCCEEDED(hr))
 {
  // Provider: 여기서는 mdb를 사용하므로, Microsoft.Jet.OLEDB.4.0를 선택한다.
  // Data위치: D:\\tDbTest.mdb
  _bstr_t strMode("Provider=Microsoft.Jet.OLEDB.4.0;Data Source= d:\\dbTest.mdb;");
  try
  {
   hr = pConn->Open(strMode,_bstr_t(L""),_bstr_t(L""), -1);
  }
  catch(_com_error& e)
  {
   AfxMessageBox(e.Description());
   AfxMessageBox(e.ErrorMessage());  
  }
 }
 if(SUCCEEDED(hr))
 {
  AfxMessageBox("데이터베이스 연결됨");
  IsConnectionOpen = TRUE;
 }
 
 // 데이터베이스에 연결이 되었다면,  레코드의 내용을 확인하자.
 if(IsConnectionOpen)
 {
  _RecordsetPtr pRs;
  hr = pRs.CreateInstance(__uuidof(Recordset));
  _bstr_t strQuery("Select * from tblTest");
 
 
  // 레코드셋 설정
  hr = pRs->Open(strQuery, pConn.GetInterfacePtr(),
   adOpenForwardOnly,adLockReadOnly,adCmdText);  
  // 아래와 같은 방식으로 접속해도 된다
  // pRs = pConn->Execute((_bstr_t)strQuery, NULL, adOptionUnspecified);
   
  _variant_t vtColumn;
  _variant_t vtNull;
 
  // _varint_t 형의 Type을 변경한다.
  vtNull.ChangeType(VT_NULL);
 
  TCHAR strDisp[MAX_PATH+1];
  short i;
 
  // Record수를 읽는다.
  long nRecord = pRs->RecordCount;
 
  // Field수를 구한다. 주의해야할 것은 long형이라는 것이다.
  long nRow = pRs->Fields->Count;

  // 다음은 Field수를 구하는 다른 방법이다.
  long nRow2 = pRs->GetFields()->Count;
 
 
  // 필드명 표시
  for(i = 0; i<nRow ; i++)
  {
   // 필드명 취득
   vtColumn = pRs->Fields->GetItem(i)->Name;  
   vtColumn.ChangeType(VT_BSTR);


   // 문자열 복사하는 방법
   lstrcpyn(strDisp,(_bstr_t)vtColumn,MAX_PATH);  
  }

  // 필드값 표시  
  while(!pRs->EndOfFile)
  {
   for(i=0;i<nRow;i++)
   {
    // 필드값을 읽어온다
    vtColumn = pRs->GetCollect(i);

    // 또한 필드값을 읽어오는 다른 방법이다.
    // vtColumn = pRs->Fields->GetItem(i)->Value;

    // 조금더 다르게 하여 특정 필드의 필드값을 읽어온다.
    // vtColumn = pRs->Fields->GetItem("Checker")->Value;

    // 데이터가 NULL이면 ""을 대입
    if(vtColumn == vtNull)
    {
     vtColumn = _variant_t("");    
    }
    else
    {
     vtColumn.ChangeType(VT_BSTR);    
    }
    lstrcpyn(strDisp,(_bstr_t)vtColumn,MAX_PATH);
   
   }
   pRs->MoveNext();
  }
  hr = pRs->Close();
 }

pConn->Close();
}

Posted by skensita
Programming/Win32 API2008. 9. 5. 14:41

Windows Messaging

제프리 릭터의 Programming Applications for Microsoft Windows에 담긴 내용입니다.

쓰래드와 메시지 : 기본 규칙
사용자 삽입 이미지
  • 프로세스 하나가 10,000개에 이르는 제각기 다른 종류의 사용자 객체(아이콘, 커서, 윈도우 클래스, 메뉴, 단축키 테이블 등)를 생성할 수 있다. 한 쓰래드에서 이들 객체 중 하나를 생성하는 함수를 호출했을 때, 생성된 객체는 그 쓰래드의 프로세스가 소유하게 된다(이 말은 프로세스가 죽으면 그 객체도 함께 죽는다는 말이다).

less..

  • 반면 윈도우(window)와 훅(hook) 객체는 그 윈도우를 생성하거나 훅을 설치한 쓰래드가 소유한다(이 말은 그 쓰래드가 죽으면 그 객체도 함께 죽는다는 뜻이다). -> 윈도우를 소유한 쓰래드가 그 윈도우의 모든 메시지를 관장한다. -> 하나 이상의 윈도우를 생성한 모든 쓰래드에는 메시지 큐가 할당되고, 그 때문에 그 쓰래드만의 메시지 루프를 갖게 된다.

  • 또한 각각의 쓰래드는 키보드 포커스라던가, 윈도우 활성화, 마우스 캡쳐 등을 다루는 그 자신만의 환경(simulated environment)이 있다고 생각한다. 그러므로 각 쓰래드에는 이들 환경 변수를 저장할 THREADINFO 구조체가 있고, 이 구조체로써 그 쓰래드만의 붙여진(posted) 메시지 큐, 보내진(send) 메시지 큐, 응답(reply) 메시지 큐, 가상화된(virtualized) 입력 큐, wake 플래그와 그 외의 여러 환경 변수등을 식별해낼 수 있다. (메시지 큐가 하나로만 구성된 것이 아니더라..)

  • 결국 THREADINFO 구조체는 윈도우즈 메시지 시스템의 주춧돌이 되더라. 하지만, UI관련 함수가 호출되기 전까지는 이 THREADINFO를 포함한 관련 리소스가 할당되지 않는다. (근데 이 구조체는 'internal', 'undocumented' 구조체라 직접 뜯어볼 수가 없다. 됀장 MS.)

POST 계열 메시지 함수
  • 붙여진 메시지 큐에 메시지만 넣은 다음, 그 메시지의 처리 여부에 관계없이, 바로 호출자 함수로 되돌아온다.
  • POST 계열 메시지 함수 : PostMessage, PostThreadMessage(다른 쓰래드에 메시지를 붙일 때), PostQuitMessage

SendMessage 함수
  • 메시지를 윈도우 프로시저에 직접 보낸다. 오직 메시지가 처리되었을 때만 호출자 함수로 되돌아온다. 요러한 동기적 처리방식 때문에 주로 사용하게 된다.
  • 다 른 쓰래드에 메시지를 넘길 경우 : 메시지를 보낸 쓰래드는 멈춰서서, 메시지를 받은 쓰래드가 그 메시지를 처리 완료하여 보낸 쓰래드의 응답 메시지 큐에 처리된 결과(SendMessage의 반환값)가 담긴 메시지를 붙일 때에야, 비로소 깨어나 그 결과 처리를 시작으로 다음 실행을 재개한다.
  • 호출된 쓰래드에 문제가 있어 메시지를 처리 못할 경우 : 호출자 쓰래드와, 호출된 쓰래드 모두 deadlock에 걸린다! -> 이를 위해 SendMessageTimeout, SendMessageCallback, SendNotifyMessage, ReplyMessage 함수가 있는 것이다.
  • SendMessageTimeOut 함수 : 보낸 메시지에 대한 응답을 받기까지의 최대 시간을 지정.
  • SendMessageCallback 함 수 : 메시지를 보내고 잽싸게 되돌아온다. 호출된 쓰래드에서 메시지 처리를 마치고 응답을 보내면, 지정한 CallBack 함수가 호출된다. 호출되는 시점은 호출자 함수의 다음번에 응답 메시지 큐에서 메시질 가져올 때이다. 메시지 브로드케스팅에도 이용.
  • SendNotifyMessage 함수 : 이 역시 메시지를 보내고 잽싸게 되돌아온다. 때문에 PostMessage와 비스무리할 수도 있지만, 윈도우에 직접 메시지를 보내기에 붙여진(Posted) 메시지보다 처리 우선순위가 높다.
  • ReplyMessage 함 수 : (deadlock을 피하기 위해) 위의 함수들은 메시지를 보내는 측에서 호출하지만, 이 함수는 받는 쪽에서 호출한다. 이 함수를 호출한다는 것은 시스템에게 메시지 결과를 알 만큼 충분히 처리했고, 처음 메시지를 보낸 측에 결과 메시지를 싸서 보내라고 알리는 것이다. 그 결과, 처음 보낸 측은 깨어나 응답 메시지를 처리하게 될 것이야~

쓰래드 메시지 큐에서의 메시지 추출 메카니즘
  • 쓰래드가 GetMessage나 PeekMessage를 호출했을 때, 시스템은 그 쓰래드 큐의 상태 플래그를 검사하여 어떤 메시지를 처리할지를 결정한다. 다음은 처리 순서다.

      사용자 삽입 이미지

    • QS_SENDMESSAGE 플래그가 켜있으면, 시스템은 메시지를 해당 윈도우 프로시저로 보낸다. 이 때에 GetMessage와 PeekMessage역시 이 작업에 내부적으로 관여하여, 윈도우 프로시저가 그 메시지를 다 처리한 후에도 return하지 않는다. 대신에, 처리할 다음 메시지를 기다린다.
    • 붙여진(posted) 메시지 큐에 메시지가 있으면, GetMessage와 PeekMessage는 이들 함수로 넘겨진 MSG 구조체를 채운다. 이 쓰래드의 메시지 루프는 보통 이 시점에서 DispatchMessage를 호출하여, 적당한 윈도우 프로시저가 그 메시지를 처리하도록 한다.
    • QS_QUIT 플래그가 켜져 있으면, GetMessage와 PeekMessage는 WM_QUIT를 반환하고 QS_QUIT 플래그를 재설정한다.
    • 가상화된 입력 큐에 메시지가 있으면, GetMessage와 PeekMessage는 하드웨어 입력 메시지를 반환한다.
    • QS_PAINT 플래그가 켜 있으면, 이들 함수는 적당한 윈도우를 위한 WM_PAINT 메시지를 반환한다.
    • QS_TIMER 플래그가 켜 있으면, 이들 함수는 WM_TIMER 메시지를 반환한다.

    보 다시피, GetMessage와 PeekMessage는 보내진(send) 메시지를 처리하고 나서는 바로 반환하지 않고, 그 다음 과정으로 넘어가서야 반환한다(특히 붙여진(posted) 메시지를 처리하고나서야 반환한다). 그리고 QS_QUIT에서만 TRUE를 반환한다. 큐를 하나만 사용하는 것도 아니고, 플래그까지 사용하다니, 아주 메카니즘이 지랄같다. 아마 위 설명갖고는 이해가 다 안될 것이다. 더 공부해야..
Posted by skensita
Programming/MFC2008. 9. 5. 01:19

BOOL CEasyInterfaceApp::InitInstance()
{
 HANDLE hMutex = CreateMutex(NULL, TRUE, "EasyInterFace");
 
 if(GetLastError() == ERROR_ALREADY_EXISTS)
 {
  ReleaseMutex(hMutex);
 
  CWnd *pWndPrev, *pWndChild;
 
  if(pWndPrev = CWnd::FindWindow(NULL, "EasyInterFace"))
  {
   pWndChild = pWndPrev->GetLastActivePopup();
   
   if(pWndPrev->IsIconic())
    pWndPrev->ShowWindow(SW_RESTORE);
   
   pWndChild->SetForegroundWindow();
  }
 
  return FALSE;
 }
 ReleaseMutex(hMutex);
}
Posted by skensita
Programming/MFC2008. 9. 4. 19:53
CFileDialog사용시 경로관련 주의사항

[질문 내용]

안녕하세요.

TipsWare 3번째 인터페이스를 사용중입니다. 다이얼로그 베이스로 개발중인데..
기본 다이얼로그 박스에서 버튼을 누르면 또 새로운 다이얼로그 박스가 뜨거든요.
근데 이 새로운 다이얼로그박스가 첨 뜰때는 이미지(로고, 체크박스, 라디오버튼 같은..)가 잘뜨는데..
기본 다이얼로그 박스에서 CFileDialog 박스로 어떤 파일을 하나 열고나면 새로운 다이얼로그박스에서
이미지들이(image 폴더에 있는) 나오지를 않네요..

제 생각에는 대충 CFileDialog에서 파일 경로가 변경되서 그런거 같은데..
어떻게 해결 해야 하는지 답변 부탁드립니다..^^;

[답변 내용]

안녕하세요~!

CFileDialog를 사용하면 내부 작업 경로가 변경되어서 이미지 파일을 정확하게 읽어 오지 못합니다.
따라서 CFileDialog를 사용하기 전에 

GetCurrentPath

함수를 이용하여 현재 작업 경로를 배열에 기억시킨후에, CFileDialog 작업이 끝난후,

SetCurrentPath

함수를 이용하여 기억시킨 경로를 다시 설정해주면 됩니다.

정리하면, GetCurrentPath는 CFileDialog 를 선언하기 전에 사용해야 하구...
SetCurrentPath는 CFileDialog를 DoModal 한 이후에 사용해야 합니다.

그럼, 즐거운 하루되세요~!

[추가답변-즐거운악몽님이 답변하신 내용입니다.]

보통 CFileDialog 대화상자를 사용하다보면 간간히 경로 변경 문제로 인해 원치 않는 결과를 얻게
되기도 합니다. 일반적으로 프로그램 즉 aa.exe 를 실행 시키면 그 파일이 실행된 폴더의 위치가
작업경로가 됩니다.

예로 c:\\work\\a.exe 를 실행 시켰다면 작업경로는 c:\\work\\ 가 되죠. 이때 CFileDialog 대화상자를
이용하면 이 작업경로가 변경되곤합니다.

CFileDialog 대화상자를 DoModal() 한 후 이리저리 폴더를 움직이고나서 OK 버튼을 누르면......
그 마지막 경로가 작업경로로 지정됩니다.

예로 CFileDialog 대화상자를 호출한 후 c:\\sample\\ 이동, 그리고 OK버튼을 눌렀다면 이제부터
작업 경로는 c:\\work\\ 가 아니라 c:\\sample\\ 인 것입니다. 이때 이후부터는 상대경로를 사용한
코드를 만나게 되면 문제가 발생되는것이죠 프로그래머가 .\\\\image\\\\aa.bmp 를 로드하는 코드를
넣었다면 원래는 c:\\work\\image\\aa.bmp 를 로드 해야 하는데 CFileDialog 대화상자로 인해 작업
경로가 변경되었으니 c:\\sample\\image\\aa.bmp 를 로드 하려 시도하게 된다는 것입니다...따라서
원치 않는 작업이 이루어 지게됩니다.

따라서 CFileDialog 대화상자를 호출하는 부분에 코드에 아래와 같이 변경해 보시길 바랍니다.

 char path[MAX_PATH] = {0};
 //현재의 작업경로를 얻어와 저장 한다.
 GetCurrentDirectory(MAX_PATH, path);

 CFileDialog dlg(FALSE);
 if(dlg.DoModal()==IDOK){
    // 가장 마지막에 저장해 두었던 작업경로로 다시금 세팅한다.
    SetCurrentDirectory(path);

    // 하고픈 작업코드.....
 }

혹 이미 위의 코드를 사용중이신데도 문제가 발생되는것이라면 좀더 자세한 설명 부탁드립니다...
그리고 새로이 추가하신 대화상자의 속성이 STYLE 탭에서 ......style -> POPUP 지정,
border -> None 을 지정하셨는지, 그리고 모든 CDialog 를 StandardDialog 로 변경하셨는지 체크해
보시길 바랍니다..

그럼 즐거운 하루되세요!!!

Posted by skensita
Programming2008. 7. 15. 15:57

C/C++

데브피아 - 거의 왠만한 C 관련 문제는 여기서 끝남.

http://www.devpia.com

 

WinAPI - 윈도우즈 API 프로그래밍 관련 강좌 및 예제

http://www.winapi.co.kr/

 

KLDP - 오픈소스 소프트웨어 사용자 및 개발자 커뮤니티

http://kldp.org/

 

자료구조 알고리즘 예제 소스 모음 - 여기에도 많은 양의 자료구조 예제 코드들이 있습니다.

                                                 이번에는 그냥 복사해서 어디 저장해두시는 것이 좋을 듯...

http://kuic.kyonggi.ac.kr/~skpaik/algori.html

 

자료구조 관련 소스 모음 - 위의 페이지와 같이 자료구조 알고리즘 관련 소스가 있습니다.

http://www.geocities.com/SiliconValley/Program/2864/ds.html

 

Koi4u - 정보올림피아드를 준비하는 웹사이트.

           알고리즘을 공부하기 때문에 굳이 시험이 아니더라도 자료구조 알고리즘 공부하기에 좋습니다.

           시험 예제도 제공하니 해보시는 것도 유익할 듯.

http://www.koi4u.net/

 

 

JAVA - 모르실 때 아래 사이트들 다 훑으면 왠만한거 다 나옵니다.

JAVA API Specifications (영문) - 자바 공식 API 소개 페이지야말로 자바 API의 경전이라고 할 수 있죠.

http://java.sun.com/reference/api/index.html

 

자바스터디

http://www.javastudy.co.kr

 

자바누리

http://www.javanuri.com

 

JavaWorld (영문)

http://www.javaworld.com/

 

자바까페

http://www.javacafe.or.kr/

 

MobileJAVA

http://www.mobilejava.co.kr/

 

열린 자바랜드

http://www.javaland.co.kr/

 

J2ee STUDY

http://www.j2eestudy.co.kr/

 

JavaRanch (영문)

http://www.javaranch.com/

 

JavaService NET

http://www.javaservice.net/

 

김상욱 개발자 SIDE - 자바 뿐 아니라 C/C++, 리눅스, 솔라리스 강좌 등도 제공하네요.

http://www.50001.com/ 

 

C#

고수닷넷
http://www.gosu.net/ 

HOONS닷넷
http://www.hoonsbara.com/ 

 

오픈소스

코드구루 (영문)

http://www.codeguru.com

 

코드 프로젝트 (영문)

http://www.codeproject.com

 

소스포지 (영문)

http://www.sourceforge.net

http://www.sf.net

 

 

소스코드 검색 - 코드의 일부를 검색하면 코드를 포함한 소스코드를 찾을 수 있습니다. (고건영 님 제공)

Koders
http://www.koders.com/

Google CodeSearch
http://www.google.com/codesearch

krugle
http://www.krugle.com/

codase
http://www.codase.com/

 

 

웹프로그래밍 & 기타

DebugLab.com - 디버깅의 모든 것

http://www.debuglab.com/

 

PHPSCHOOL - PHP 개발할 때 유용한 웹사이트

http://www.phpschool.com

 

PHP 공식 웹사이트 (영문)

http://www.php.net

 

OK JSP
http://www.okjsp.pe.kr/bbs?act=LIST&bbs=TOOL

 

비주얼베이직 공개 소스 - 원래는 가입하고 포인트 지불해야 이용가능한 사이트지만

                                   게시물을 올리신 분은 공짜로 올려두셨습니다. 물론 회원가입도 필요없음...

http://www.personaldb.net/databank/data_list.asp?group_no=2923&chk_session=Y

 

SQLER - SQL 공부하는 곳입니다.

http://sqler.pe.kr

 

taeyo's ASP & .NET

http://www.taeyo.pe.kr/

 

하야시의 와글와글네 (ASP, 자바스크립트 등등)

http://www.waglwagl.net/

 

LeeChen과 함께 (다이렉트 X 프로그래밍)

http://www.leechen.net/

 

gotAPI (영문) - 각종 언어의 API를 찾을 때

http://www.gotapi.com/html

Posted by skensita