코딩중이던 ActiveX 를 테스트하려고
html 하나 맹글어서
var obj = document.getElementById("MyActiveX");
obj.test();
를 했더니 개체가 이 속성 또는 메서드를 지원 안한단다..

REGSVR32 등록, 실행, 컨트롤 초기화, 동작이 다 되는데
javascript 호출할때만 에러가 나길래 뭐지 고민하다 하루가 갔다 -_-..

결론은!
COM맵(클래스 선언이 아님)에 IDispatch 가 빠져있더라...
그렇다 VBScript 등은 ActiveX 등에 IDispatch 로만 접근이 가능하다..
근데 IDispatchImp 등 필요 코드는 다 집어넣고 정작 COM맵에 빼먹다니;

 자나깨나 IDispatch 조심..

 

Posted by 김모작자

댓글을 달아 주세요

 

ARGB_TO_RGB.txt

Original Posting ::

https://github.com/s-silva/fennec/blob/master/plugins/visualizations/goom/mmx.asm

 대략적인 설명 ::

파라미터

L1 전에 있는 코드를 난 아래와 같이 바꿔 사용했음, C++ 에서 inline asm 으로 사용했기 땀시..
마기막 ecx 에 들어가는 값은 원문에는 바이트로 표시돼 있으나, 뭘 봐도 픽셀 갯수다.. 잘못 쓴듯..

   mov edi, dest; destination
   mov esi, src; source
   mov ecx, px; pixels

 

 

Posted by 김모작자

댓글을 달아 주세요

resource 에 기록된 파일의 정보를 읽는 함수
GetFileVersionInfoSize 두번째 파라미터가 아닌 return 되는 값을 확인해야 한다는 거에 유의!

 

CODE.txt

 

// filename : 조회하려는 파일 전체 경로 (NULL 전달시 현재 실행 파일을 조회)
// FileVersion :: VER 리소스의 파일 버전
// ProductVersion :: VER 리소스의 PRODUCT_VERSION
void GetModuleVersion(LPCTSTR filename, CString& FileVersion, CString& ProductVersion )
{
 LPCTSTR filepath = filename;

 TCHAR module[1024];
 if(filepath == nullptr)
 {
  GetModuleFileName(nullptr, module, 1024);
  filepath = module;
 }

 FileVersion.Empty();
 ProductVersion.Empty();

 DWORD data_len = 0, Handle = 0;
 data_len = ::GetFileVersionInfoSize(filepath, &Handle); // data_len 이 필요, Handle 은 뭐에 쓰는거임?
 if(data_len == 0)
  return ;

 LPVOID data = (LPVOID) new BYTE[data_len];
 if(::GetFileVersionInfo(filepath, 0, data_len, data))
 {
  LPVOID ptr = NULL;
  UINT len = 0;
  if( VerQueryValue( data, _T("\\"), &ptr, &len) && ptr != nullptr)
  {
   VS_FIXEDFILEINFO* info = (VS_FIXEDFILEINFO*) ptr;
   
   FileVersion.Format(_T("%u.%u.%u.%u"), info->dwFileVersionMS >> 16, info->dwFileVersionMS & 0xFFFF,
    info->dwFileVersionLS >> 16 , info->dwProductVersionLS & 0xFFFF);

   ProductVersion.Format(_T("%u.%u.%u.%u"), info->dwProductVersionMS >> 16, info->dwProductVersionMS & 0xFFFF,
    info->dwProductVersionLS >> 16 , info->dwProductVersionLS & 0xFFFF);
  }  
 }
 delete (LPBYTE)data;
}

 

Posted by 김모작자

댓글을 달아 주세요

  1. ninpeng 2013.08.27 19:12  댓글주소  수정/삭제  댓글쓰기

    handle 값은 GetFileVersionInfo 두번째 인자에 들어가는 것인데 아직 사용하지 않는 파라미터라서 무시해도 된다고 하네요.

ffmpeg 등 command line 툴의 콘솔 출력을 잡기 위해선 pipe 를 이용하여
std-in, std-out, std-err 를 redirection 해야한다.

redirection 은 fprintf(stdout)..., printf, fgets  등의 표준 I/O 의 목적지를 화면이 아닌 모(母) 프로그램이 받도록 도와준다.

Win32 함수로 구현하기 위해선 CreatePipe, Duplicate, ReadFile, WriteFile, CloseHandle 함수를 사용해야 한다.
여러 프로그램을 pipe 로 연결시킨 경우 각각의 프로세스를 만들고 앞 프로세스의 output 을 다음 프로세스의 input 에 수동으로 넣어줘야 한다. 난 당연히 자동으로 되겠지 했으나 왜 그런지 에러만 났을 뿐이다.

  CreatePipe(&ReadFromInput, &WriteToInput, nullptr, PIPE_LENGTH);  
  CreatePipe(&ReadFromOutput, &WriteToOutput, nullptr, PIPE_LENGTH);  
  CreatePipe(&ReadFromError, &WriteToError, nullptr, PIPE_LENGTH);

  DuplicateHandle( GetCurrentProcess(), ReadFromInput, GetCurrentProcess(), &exec.hInput, 0, TRUE, DUPLICATE_SAME_ACCESS);   
  DuplicateHandle( GetCurrentProcess(), WriteToOutput, GetCurrentProcess(), &exec.hOutput, 0, TRUE, DUPLICATE_SAME_ACCESS);  
  DuplicateHandle( GetCurrentProcess(), WriteToError, GetCurrentProcess(), &exec.hError, 0, TRUE, DUPLICATE_SAME_ACCESS);   
  
  DuplicateHandle( GetCurrentProcess(), WriteToInput, GetCurrentProcess(), &exec.hWriteToFFMPEG, 0, FALSE, DUPLICATE_SAME_ACCESS); 
  DuplicateHandle( GetCurrentProcess(), ReadFromOutput, GetCurrentProcess(), &exec.hReadFromFFMPEG, 0, FALSE, DUPLICATE_SAME_ACCESS); 
  DuplicateHandle( GetCurrentProcess(), ReadFromError, GetCurrentProcess(), &exec.hReadFromFFMPEGError, 0, FALSE, DUPLICATE_SAME_ACCESS); 

  CloseHandle( WriteToInput ); WriteToInput = NULL;
  CloseHandle( ReadFromOutput ); ReadFromOutput = NULL;
  CloseHandle (ReadFromError); ReadFromError = NULL;

  PROCESS_INFORMATION pi;
  ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));

  STARTUPINFO si;
  ZeroMemory(&si, sizeof(STARTUPINFO));
  si.cb = sizeof(STARTUPINFO);
  si.dwFlags = STARTF_USESTDHANDLES;
  si.hStdInput = exec.hInput;
  si.hStdOutput = exec.hOutput;
  si.hStdError = exec.hError;

  SetLastError(0);
  
  TCHAR CommandLine[10240];
  _tcscpy_s(CommandLine, cei.CommandLine);
  ...

  launch_ok = CreateProcess(nullptr, CommandLine, nullptr, nullptr, TRUE, CREATE_NO_WINDOW, (LPVOID)my_env_param, nullptr, &si, &pi);
  

 

Posted by 김모작자

댓글을 달아 주세요

WinInet 함수가 윈도 서비스 등에 사용할 수 없음이 확인되면서, Microsoft 에서 권장하는 WinHttp 함수군으로 framework 코드를 만들었다.

요점 사항

WinHttpAddRequestHeaders - 헤더의 유효성(validation)을 체크한다.

WinHttpSendRequest 에서 POST 인 경우 TotalLength 파라미터를 기록해줘야한다.

TotalLength 가 실제 전송하는 데이터 길이 보다 길게 기록한 경우 WinhttpReceiveResponse 에서 15초 정도의 시간이 걸린다. 이는 서버측에서 timeout 시간동안 데이터를 더 기다리고 있기 때문에 발생한다.

개발 기준 : Visual Studio 2010 SP1, ATL, MSXML6

  SimpleHttpIO.cpp

SimpleHttpIO.h

Posted by 김모작자

댓글을 달아 주세요

특징? 일단 로컬에서는 빠르다.. remote 파일이라면? 못해도 fread 등 보다는 빠르다 -_-
왜냐 미리 페이지 단위로 prefetch 를 하기 땀시/

구현은 안했지만서도 Read 함수 외에 일종의 Lock 함수를 만들면 직접 메모리 접근이 가능하기 때문에 더 빠른 처리를 할 수 있을것 같다.

현재 구현 : read -> copy
최선의 구현 : read and process !  (버퍼의 공유)

 

 

FileMappingReader.h

Posted by 김모작자

댓글을 달아 주세요

세상에서 제일 짜증나는게

콘솔 프로젝트 빌드했더니

1>nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z)이(가) LIBCMT.lib(new.obj)에 이미 정의되어 있습니다.
1>nafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z)이(가) LIBCMT.lib(delete.obj)에 이미 정의되어 있습니다.
1>c:\users\administrator\documents\visual studio 2010\Projects\2012\Release\mediaServer.exe : fatal error LNK1169: 여러 번 정의된 기호가 있습니다.

이딴 에러가 나는 경우다

이건 C Runtime Library 와 MFC 라이브러리의 importing 순서 때문에 발생하는거라고 한다.

따라서

Link 탭에 추가 종속성(Additional Libraries) 에 nafxcw.lib; libcmt.lib;  두개를 추가해주면 되겠다.

 

Posted by 김모작자

댓글을 달아 주세요


원문 : http://www.cplusplus.com/forum/beginner/1501/

사용할 Win32 함수 : SetConsoleCtrlHandler

Posted by 김모작자

댓글을 달아 주세요

const CComVariant MissingParam(DISP_E_PARAMNOTFOUND, VT_ERROR);
Posted by 김모작자

댓글을 달아 주세요

ACE 컴파일 하기

Win32 , C++ 2009. 7. 14. 14:08

1. 우선 ACE 를 다운로드 받고.. [http://www.cs.wustl.edu/~schmidt/ACE.html]

2. 하드에 압축을 풀고.. (난 간편하게 C:\에 풀어버렸다.. 나중에 지우기 편하게..)

3. ACE_wrappers\ace 폴더에 config.h 를 만들어 준다
config.h 에는 컴파일 되는 플랫폼에 대한 정의가 들어간 헤더 파일을 포함 시켜주면 되는데..
내용은 저게 전부다..

4. 컴파일 시작
난 Visual Studio 2008 을 사용하기에
ACE_wrappers_vc9.sln
ACE_wrappers_vc9_Static.sln
두 개의 솔루션 파일을 Batch build 로 Debug, Release 버전에 대해 빌드 하였다.

참 쉽지 아니한가? config.h 가 왜 없는지 고민하다 겨우 찾아 써봤음..
Posted by 김모작자

댓글을 달아 주세요


헤더 파일에
 
#import "C:\Program Files\Common Files\Microsoft Shared\Office12\MSO.DLL"       rename("RGB","_RGB")
#import "C:\Program Files\Common Files\Microsoft Shared\VBA\VBA6\VBE6EXT.OLB"
#import "C:\\Program Files\\Microsoft Office\\Office11\\EXCEL.EXE" \
      rename("RGB","_RGB") \
      rename("DialogBox","_DialogBox") \
      rename("CopyFile","_CopyFile") \
      rename("ReplaceText","_ReplaceText") \
      exclude("IFont","IPicture","_IMsoDispObj")

....

실제로 사용하는 코드 예시 :  

 Excel::_ApplicationPtr m_Excel;
 m_Excel.CreateInstance(L"Excel.Application");
 m_Excel->put_Visible(0, VARIANT_TRUE);

 Excel::WorkbooksPtr books = m_Excel->Workbooks;
 m_Workbook = books->Add();
 m_Worksheet = m_Workbook->Worksheets->Add(); 
Posted by 김모작자

댓글을 달아 주세요

IME 상태 변경

Win32 , C++ 2009. 2. 20. 13:13
void SetHanMode(HWND hWnd,BOOL isHan)
{
// hWnd : 상태를 변경할 윈도 핸들
// isHan : 한글로 전환할지..
    HIMC hIMC = ImmGetContext(hWnd);
    DWORD dwConv, dwSent;
    DWORD dwTemp;

    ImmGetConversionStatus(hIMC,&dwConv,&dwSent);
    if(isHan){
        dwTemp = dwConv & ~IME_CMODE_LANGUAGE;
        dwTemp |= IME_CMODE_NATIVE;
        dwConv = dwTemp;
    }else dwConv=0;
    ImmSetConversionStatus(hIMC,dwConv,dwSent);
    ImmReleaseContext(hWnd,hIMC);
}
Posted by 김모작자

댓글을 달아 주세요

// #1 : RDS 로드
IDispatch *pDispatch = NULL;
RDS::IDataspacePtr pDS;
HRESULT hr_CreateInstance = pDS.CreateInstance(OLESTR("RDS.DataSpace")); //
if (FAILED(hr_CreateInstance))
{
  // assertion
}
// #2 : 해당 COM+ 서버에서 객체 가져오기
 Result = pDS->CreateObject(_bstr_t("Object Program ID"), _bstr_t("Remote Address"));
 HRESULT hr = Result.pdispVal->QueryInterface(_uuidof(IDispatch), (LPVOID*) &pDispatch);
}

// #3 : 해당 컴포넌트의 멤버 함수 번호(Dispatch ID)찾기
// DISPID 는  Type Library 에 함수이름 앞에 나오는 번호와 같다..

LPOLESTR strFuncName = L"Member-Function Name"; // 찾으려는 함수이름
DISPID dispidIssueAdmissionTicket = 0; // 찾으려는 함수의 DISPID

HRESULT hr = pConn->GetIDsOfNames(IID_NULL, &strFuncName, 1, LOCALE_SYSTEM_DEFAULT, &dispidIssueAdmissionTicket);
if( FAILED( hr ) )
{
 // assertion
}

// #4 : 함수 호출하고 문자열 리턴값 가져오기
// string SomeFunction (string, string, string) 형태라고 가정하자...

_bstr_t result; // 리턴값 저장용
BSTR tmp = NULL;
hr = _com_dispatch_method( pConn,  // IDispatch
           dispidIssueAdmissionTicket,  // 아까 찾아낸 DISPID
           DISPATCH_METHOD, // 매서드
           VT_BSTR, // 린턴값 타입
           &tmp,       // 리턴값 들구 올 변수
           L"\x0008\x0008\x0008" ,  // 다음에 나올 파라미터의 종류
           (BSTR)  something1,  // 파라미터1 : 문자열
           (BSTR) something2, // 파라미터2 : 문자열
           (BSTR)something3); // 파라미터3 : 문자열
     if( SUCCEEDED(hr) && tmp != NULL)
     {
      result = tmp; // 내 변수로 복사 (대입이 아님)
      ::SysFreeString( tmp ); // 리턴값은 내가 해제한다
     }

 

 

Posted by 김모작자

댓글을 달아 주세요

직접적으로 MFC 프로젝트에서 쓸 일은 별로 없긴한데, 가끔 쓸때마다 삽질을 해서 정리함.

1. 현재 레코드의 필드값 가져오기 (서수 번호로)

  spRecordset->Fields->GetItem(CComVariant((short) idx));

Field 번호를 지정해서 가져오는 경우 (short) 로 필드 번호를 기록해 준다. 그렇지 않으면
'800a0bcd', '0x800A0CC1' 등의 예외가 발생한다.

2. 커서 종류를 보고 MoveFirst 를 하자..
 
  Forward only 커서 계통은 MoveNext 만 가능하다.
  역시나 이 부분 때문에 예외가 발생한다.

3. VARIANT 에 대한 처리 확실히 하기

  확인은 안해 봤지만 아래처럼 과감하게 -_-

  CString str;
  switch(var.vt)
  {
  case VT_I8:
   str.Format(_T("%I64d"), var.llVal);
   break;
  case VT_I4:
   str.Format(_T("%d"), var.lVal);
   break;
  case VT_UI1:
   str.Format(_T("%u"), (UINT)var.bVal);
   break;
  case VT_I2:
   str.Format(_T("%d"), var.iVal);
   break;
  case VT_R4:
   str.Format(_T("%f"), var.fltVal);
   break;
  case VT_R8:
   str.Format(_T("%f"), var.dblVal);
   break;
  case VT_BOOL:
   str.Format(_T("%s"), var.boolVal == VARIANT_TRUE ? _T("true") : _T("false"));
   break;
  case VT_BSTR:
   str = (LPTSTR) (_bstr_t( var.bstrVal));
   break;
   case VT_DECIMAL: // oracle 의 숫자필드 등에 쓰이더라
    str.Format(_T("%s%I64u"),((var.decVal.sign & DECIMAL_NEG) == DECIMAL_NEG) ? _T("-") : _T("") , var.decVal.Lo64);
   break;
  case VT_DATE: // 날짜 형태는 적절히 변환해서 쓰는게 좋을듯,
  str = COleDateTime(var).Format();
  break;
  }
Posted by 김모작자

댓글을 달아 주세요

보통 수정을 하지 않은 상태에서
MFC 에 있는 MessageBox 또는 AfxMessageBox 를 사용할 때
메세지박스의 제목(caption) 을 지정하지 않을 경우
실행 파일의 이름이나 처음 프로젝트 만들때 지정한 텍스트가 나오게 된다

더구나 그 제목에 표시되는 텍스트가 레지스트리/INI 에 저장할 때도 그대로 쓰이게 된다

이를 바꾸기 위해서는
1. 리소스 스트링 테이블에 AFX_IDS_APP_TITLE 이 있는 경우 해당 값을 바꾸면 되고
2. CWinApp 의 m_pszAppName 을 초기 코드에서 바꿔주면 된다

참고로 m_pszAppName 을 수정하기 할때 문자열이 지속적으로 메모리에 남아있도록 해야한다.

//First free the string allocated by MFC at CWinApp startup.
//The string is allocated before InitInstance is called.
free((void*)m_pszAppName);
//Change the name of the application file.
//The CWinApp destructor will free the memory.
m_pszAppName=_tcsdup(_T("호호호호"));


MFC 예제
Posted by 김모작자
TAG MFC

댓글을 달아 주세요

원본글에 있는 프로젝트를 받아 간단하게 함수 형태로 변환한 소스.
WOL 등에 필요한 Mac Address 를 구하기 위해.

원본글 : 찾아가기
----------------------------------

#include
#pragma comment(lib, "iphlpapi.lib")
CString GetMacByIP(const CString& strIP)
{
       CAsyncSocket sock;
       sock.Create(1000, SOCK_DGRAM);
       sock.SendTo(&sock, 1, 1000, strIP);

       CString strMAC;
       PMIB_IPNETTABLE pIPNetTable;
       pIPNetTable = (MIB_IPNETTABLE*) malloc( sizeof( MIB_IPNETTABLE) );

       DWORD dwSize = 0, dwRetVal=0;
       if ( (dwRetVal=GetIpNetTable(pIPNetTable, &dwSize, 0)) == ERROR_INSUFFICIENT_BUFFER)
       {
               free( pIPNetTable );
               pIPNetTable = (MIB_IPNETTABLE *) malloc ( dwSize );
       }
       else
       {
               CString strErr;
               LPTSTR lpMsgBuf;
               FormatMessage(                         FORMAT_MESSAGE_ALLOCATE_BUFFER |
                                                               FORMAT_MESSAGE_FROM_SYSTEM |
                                                               FORMAT_MESSAGE_IGNORE_INSERTS,
                                                               NULL,
                                                               WSAGetLastError(),
                                                               MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
                                                               (LPTSTR) &lpMsgBuf,
                                                               0,
                                                               NULL );

               OutputDebugString(lpMsgBuf);
               LocalFree( lpMsgBuf );
       }

       // Make a second call to GetIpAddrTable to get the
       // actual data we want
       if ( (dwRetVal = GetIpNetTable( pIPNetTable, &dwSize, 0 )) == NO_ERROR )
       {
               for (UINT i=0;idwNumEntries;i++)
               {
                       if ((pIPNetTable->table[i].dwAddr) == inet_addr(strIP))
                       {
                               BYTE *pt = (BYTE*)&pIPNetTable->table[i].bPhysAddr;
                               for (int j=0;j<6;j++)
                                       strMAC.AppendFormat(_T("%02X"),*pt++);
                               break;
                       }
               }
       }
       //Cleanup
       if(pIPNetTable)
       {
               free( pIPNetTable );
               pIPNetTable = NULL;
       }
       return strMAC;
}
Posted by 김모작자
TAG mac, MFC

댓글을 달아 주세요

항상 잊을만 하면 쓸 필요가 생기는 코드.

내부적으로 trace 를 구현할 때 참 유용하다.
특히 MFC 의 TRACE 는 유니코드 문자열을 지원하지 못하기 때문에 MFC 로 유니코드 어플리케이션을 만들때 急 필요한 코드 조각이다.

기왕이면 아래 1024 바이트를 스택에 만드는 것보다 스레드 별로 TLS 를 만드는 편이 더 낫겠다는 생각이 글 쓰면서 들었다 -_-

// 1. 일반적인 코딩
void _DBGTRACE(TCHAR* format, ...)
{
       TCHAR buf[1024];
       va_list        marker;
       va_start(marker, format);
       _vstprintf(buf, format, marker);
       va_end(marker);

       OutputDebugString(buf);
}

// 2. 안전+LFH힙을 이용한 문자열 포맷팅
 LPCTSTR HFormat(LPCTSTR format, ...)
 {
  va_list        marker;
  va_start(marker, format);

  int len = _vsctprintf( format, marker ) + 1;
  LPTSTR buf = (LPTSTR)Alloc(len);
  _vstprintf_s(buf, len, format, marker);

  va_end(marker);

  return buf;
 }

문자열의 경우 LFH(Low Fragment Heap) 을 사용하면 이득을 볼 수 있기 때문에 Alloc 에 해당하는 함수에서 적절히(?) 처리해주고.. _s 계열 함수를 이용해 버퍼 오버런에 대응할 수 있도록 한다..

Posted by 김모작자
TAG MFC, Trace

댓글을 달아 주세요

  1. 해보리 2009.02.17 19:53  댓글주소  수정/삭제  댓글쓰기

    vsprintf()에서 char 형변환 때문에 문제가 생기지 않았는지 궁금하네요...
    유니코드로 하면 함수 자체는 char*를 받아가는 거라... 오류가 발생할텐데요...

실제 표시되는 다이얼로그


CredUIPromptForCredentials - creates and displays a configurable dialog box that accepts credentials information from a user.

예)

#include <WinCred.h>
#pragma comment(lib, "Credui.lib")

...
       TCHAR name[100] = _T("화면에 미리 표시될 이름");
       TCHAR passwd[100] = _T("화면에 미리 표시될 비밀번호");
       BOOL save = FALSE;

       CREDUI_INFO info;
       info.cbSize = sizeof(CREDUI_INFO);
       info.hwndParent = NULL;
       info.pszCaptionText = _T("제목!");
       info.pszMessageText = _T("물어볼 메세지");
       info.hbmBanner = NULL;

       DWORD v = CredUIPromptForCredentials(&info, _T("."), NULL, 0, name, 99, passwd, 99, &save, 0);

리턴된 v 가 NO_ERROR 인 경우 name, passwd 에 해당 ID, 비밀번호가 들어가 있다

Posted by 김모작자

댓글을 달아 주세요

DLL 만드는 기초

우선 아래에 대해 이해를 해야한다
1) C++컴파일러의 특성
2) 인터페이스 규칙
3) 헤더 만들기

1. 다른 제품간의 C++ 호환성
컴파일러에 의해 생성되는 .obj/.lib 파일 출력에서 OMF, COFF 형식의 차이가 발생한다
이는 C++ 컴파일러에 의해 함수명 앞뒤로 전달 인자에 대한 정보가 붙기 때문이다.

예를 들어 Microsoft C++ 컴파일러는
int CPUReset(void *)
를 별도의 설정이나 명시된게 없을 경우
?CPUReset@@YAHPAX@Z
이런 이름으로 내보내게 된다.

문제는 앞뒤에 달라 붙는 정보가 컴파일러 제조사/규격 마다 다르기 때문에 호환이 되지 않게 된다. 따라서 이기종 컴파일러와 인터페이스를 하기 위해선 앞뒤에 정보가 빠진 함수 본래 이름만 내보내도록 해야한다

2. 인터페이스 규칙 (Calling Conventions)
이 부분은 공통적인 사실상의 표준이 있기 때문에.. 편리하거나 혹은 양쪽이 지원하는 방법을 택하도록 한다. 현재 많이 쓰는 규칙으로는 cdecl, stdcall, pascal 등이 존재한다.
기본 설정이 있지만 프로젝트마다 다를 수 있기 때문에 소스상에 규칙을 정확하게 명시하는게 좋다.

3. 헤더 만들기
Borland C++ Builder, Delphi 등 에서 사용하기 위해서 중요한 작업으로 인터페이스 규칙, 전달 인자 등의 구체적인 기록 작업이다.
같은 데이터 타입이라도 Call by value/reference/pointer 에 따라 세부적인 데이터 형태가 바뀔 수 있다

Delphi 예:
 function CPUReset(handle : longword):longword;stdcall; external 'dllfile.dll';
기타 C 컴파일러 호환:
 Borland C++ 쪽은 일단 Explicit loading 으로 해결하는 것 밖에 모르겠다.
Posted by 김모작자

댓글을 달아 주세요

예전에 Pubby 만들때 몰라서 애먹었다 -_-


기본 과정 :

1. RESOURCE 파일에 HTML (VS2002 이상에서는 HTML 문서로 인식해 편집에 편리) 등의 항목을 추가후에.. HTML 파일을 추가해준다
2. HTML 파일 내에 이용하는 이미지 파일을 포함시키기 위해 별도의 리소스 섹션을 만들어 추가
  이 때 가급적 숫자로 해당 이미지를 추가하면 작업하기 편하다
3. HTML 파일의 이미지 경로를 수정해준다.
4. HTML 파일의 이미지 또는 href 경로에 "리소스섹션명/ID" 형식으로 기록한다.

---- RC 파일에서 발췌 ---------------

IDR_HTML_PAGE      HTML                    "my_html.htm"

100        MY_IMG        "intro_images/01.gif"
101        MY_IMG        "intro_images/02.gif"
102        MY_IMG        "intro_images/03.gif"
103        MY_IMG        "intro_images/04.gif"
104        MY_IMG        "intro_images/05.gif"
105        MY_IMG        "intro_images/main.jpg"

---- HTML 파일에서 발췌 -------------------

<img ID="HELP" src="MY_IMG/104" border="0">

추가 작업 :
별도의 처리를 하지 않은채 실행하여 오른쪽 버튼을 누르면 Internet Explorer 에서 보던 팝업 메뉴가 생긴다.
이 context-menu가 뜨지 않도록 하기 위해 body 태그에 oncontextmenu 에 대한 핸들러를 추가해준다
또는 이에 상응하는 방법으로 팝업 메뉴를 처리한다.



주의 :
1. CDHTMLDialog 에서 사용할 Dialog 리소스에 Control 속성이 false 가 되도록 하자.
2. 간혹 부모 다이얼로그에 WM_GETDLGCODE 를 무한으로 보낼경우가 있는데, 이 때 부모 다이얼로그에 WM_GETDLGCODE 핸들러를 추가해
   0 이 아닌 코드를 리턴해주면 해결된다
Posted by 김모작자

댓글을 달아 주세요