Image To SWF

카테고리 없음 2013. 6. 13. 13:02

PPT를 SWF를 변환하는 프로그램은 많지만, 죄다 상용.. 


쓰고싶니? 그럼 돈내... 깡패들...


찾아보니 괜찮은 프로그램들이 많던데... 안사주므로... 걍 대충 하나 만듦.

 

근데, 아무래도 이미지로 변환하다보니 품질은 별로임... PDF에서 SWF로 변환하는 것이 가장 품질은 좋긴 한데, Office 2013은 자동으로 지원하지만 그 이하버전에서는 지원하지 않는 것이 단점 아닌 단점. PDF Creator를 설치하면 참 좋은데... 여기다 설명하긴 길고...

 

또 하나. 이렇게 해서 만들어진 SWF는 자동 슬라이드 방식임. 마우스로 클릭한다고 넘어가는 것이 아니라 자동으로 슬라이드가 넘어가는 방식임. 이벤트나, 돌잔치때, 이미지 슬라이드 하는 것과 같다고 생각하면 됨. 아래는 Sample. (작아서 글자 깨져보이는건 기분탓)





준비물: 

 http://swftools.org/download.html



노란 부분을 다운 받아, 긍정적인 마인드로 Next를 누르면서 진행한다. GPL라이센스이고 하니, 아마 바이너리는 프리웨어인 듯...


이 친구들이 프로그램은 다양하게 만들어 놓은건 좋은데, 참... 개발자 프렌들리한 친구들인지 UI라곤 눈 씻고 찾으면 한개 있다.


그래서 하나 만듦. 일단은 Jpeg을 SWF로 쉽게 만들기 위해서 짧게 하나 구현함.



JpegToSWF.exe


이거 다운받아서 실행하면 귀차니즘 이즈 베스트인 프로그램이 하나 뜬다. 


저기 위에 있는 흰 사각형에 Jpg 파일을 드래그 & 드롭하면 확장자가 .jpg인 친구들만 리스트에 뜬다.  중간에 이미지 하나 삭제하려면 어떻게 하냐고? 꼈다 키세요.


그리고나서 Run을 누르면 바탕화면에 OutputSWF.swf란 파일이 생성됨. 이를 익스플로러 하나 띄워서 드래그&드롭하면 실행된다.



만약 실행이 안된다면.. 

http://msdn.microsoft.com/en-us/library/5a4x27ek.aspx


위 링크에 가서 




Stand-Alone이라고 되어 있는 저 부분을 다운로드 받아 설치하면... 아마 실행될꺼임.

 

 

PS. PPT 이미지로 저장하기

 

파일 -> 다른 이름으로 저장 -> 파일 형식 -> JPEG 파일 교환 형식

 

파워 포인트에서 위 순서대로 하면, 폴더에 이미지가 쭉 저장됩니다.



posted by 스펜서.


오늘 회사에서 아는 형이 코드에서 "PInvokeStackImbalance" Exception이 발생한다고 도와달라고 했다.

사실 여기서 가장 큰 문제는 "왜 되던 코드가 안되는 것일까?" 였다. 이전 프로젝트에서는 DLL을 잘 로드해서 썼는데, 새로 프로젝트를 만들고 똑같이 DLL을 로드했는데 갑자기 위의 Exception이 발생했다고 한다.

그래서 두 프로젝트를 비교해봤더니 사용하던 .Net Framework 버전이 달랐다. 잘 되던 곳은 3.0을 쓰고 있었고, 안되는 곳은 4.0을 쓰는 문제가 있었다.

그래서 찾아봤다. 역시 문제는 CallingConvention 문제.

[DllImport("TestDll.dll")]
public static extern int Test(string text);

위와 같이 작성되었던 것을

[DllImport("TestDll.dll", CallingConvention=CallingConvention.Cdecl)]
public static extern int Test(string text);

이렇게 뒤에 CallingConvention을 붙여서 호출하면 된다.


보통 C++에서 DLL을 만들면 cdecl 이란 호출규약으로 만든다. 왜냐면 다들 귀찮으니까 별도의 호출규약을 안써준다. 근데, C#에서 DllImportAttributeCallingConvention은 기본값이 stdcall이다. 그래서 에러가 난거다.


호출규약에 대해서 궁금하면 여기! 를 참고하면 좋다.


뭐... 이거야 쉽게 해결했지만 왜 3.0에서는 된걸까?

여러 글을 찾아보다가 결국 해답은 못찾았다. 하지만 StackOverflow에 같은 질문이 올라온 글에 David Hefferman이란 사람이 아래와 같이 적어놓았다.

Don't kid yourself that your code is alright because .net 3.5 doesn't raise this error. The error detection in .net 4 is better which is why you only see the errors there. But your code is broken in all .net versions.

굳이 해석하자면...

"3.5에서 에러가 나지 않았다고 코드에 이상없다고 착각하지 마. 단지 4.0에서 이러한 에러를 잘 찾아내니까 발생한거야. 니 코드는 모든 .net 버전에서 에러야"


음. 명언이다. 에러가 안난건 단지 4.0의 성능이 좋아서다. 내가 봐도 확실히 에러 맞다.



posted by 스펜서.

AutoHotKey

카테고리 없음 2011. 11. 27. 11:07
F12::                  ;

keyState_01:=Not keyState_01
if(keyState_01)
{
setTimer, myTimerHandler, 4000       ; 반복 입력 주기를 입력

}else{
setTimer, myTimerHandler, off
}
return

myTimerHandler:
Send, {F7}              ; 반복 입력하고 싶은 키

return
posted by 스펜서.
회사에서 Memory 사용량을 실시간으로 파일로 기록하는 아주 단순한 프로그램을 만들었다. 그 동안, 눈으로 작업관리자를 뚫어져라 쳐다봤던 방식보단 조오금 진보했다랄까?

아무튼 유틸리티가 필요했던 이유는 다름이 아니라 바로 개발자의 최대의 적! 메모리 누수가 일어나는 지를 알아보기 위함이다.

회사 프로젝트 특성상, Operation에 따라 메모리 사용량이 출렁거리는 상황이기 때문에 꾸준히 메모리를 본다고 해서 누수가 나는지, 안나는지를 알 수 없었다. 그래서 단순히 실시간으로 프로그램의 메모리 사용량을 파일로 기록하는 프로그램을 만들었는데...

메모리 사용량의 추세를 알기 위해 다음의 짓을 매번 반복했다.
1. 로그 파일을 열어서
2. Excel에 붙여넣고
3. 2차원 꺽은선 그래프를 그리고
4. 추세선 그리기

근데 너무 이 짓이 귀찮아서, 실시간으로 추세선을 알 수 있는 방법이 있지 않을까 해서 사용한 것이 "최소제곱(자승)법" 이다.

뭐... 이쯤되면 최소 자승법이 뭔지는 네이버, 구글에서 뒤져보면 나올 것이고...귀찮은 분은 위에 링크를 클릭~!

이를 구현하기 위해서 수식을 살펴봤는데, 적용하기엔 무리가 있었다. 왜냐하면 "최소제곱법"을 이용해 추세선을 그리기 위해서는 데이터를 모두 가지고 있어야 한다는 점이였다.



위 수식을 보면, 실시간 데이터기 때문에 평균x, y가 매번 바뀌고, 이를 구하기 위해서는 매번 평균 계산을 다시해야 한다. 물론 평균값을 유지하는 것이 아니라 데이터의 총 합만 유지하면 매번 평균값을 구하는 것은 O(1)시간에 구할 수 있다.

그러나... a 공식의 분자, 분모를 계산할 때도 그럴까?

이를 계산하기 위해서는 O(n)의 계산이 필요한데, 매 초당 이런 계산을 한다는 것은 매우 부담스러운 일이고... 시간이 갈 수록 n이 커지기 때문에 점점 계산량이 많아진다는 부담이 있다.

개선의 시작은 다음과 같은 아이디어에서 시작했다.

"n-1번째의 a를 구하고, 여기에 x,y 평균의 변화량을 이용해서 n번째의 a를 구할 수 있지 않을까?"

그래서 각 식을 n-1번째 식으로 전개해서 풀어보았다.

(수식을 타이핑하기 귀찮으므로... 전개는 생략한다...)



는 페르마드립이고, 첨부파일에 스캔해놓은 발로 쓴 공식을 참조하길 바란다.


결국, 1), 2) 식과  각 x, y의 총합만 매 Tick(데이터가 들어오는 순간)마다 업데이트하면 a를 구할 수 있었다.

다음은 이를 c++로 구현한 소스이다.

[LSM Structure.h]
### cpp
struct LSMData
{
    float x, y;
};
struct Linear
{
    float a, b;
};

[LeastSquareMethod.h]
### cpp
#include "LSMStructure.h"
class LeastSquareMethod
{
public:
    LeastSquareMethod(void);
public:
    ~LeastSquareMethod(void);
    int Count() { return m_nCount; };
    void Reset()
    {
        m_lnResult.a = 0;
        m_lnResult.b = 0;

        m_nCount = 0;

        m_fTotalX    = 0.0f;
        m_fTotalY    = 0.0f;
        m_fDeltaX    = 0.0f;
        m_fDeltaY    = 0.0f;
        m_fDeltaXX    = 0.0f;
        m_fDeltaXY    = 0.0f;
    }

    void AddData(const LSMData& data);
    Linear GetTrendency();

private:
    void Update(const LSMData& data);

    Linear m_lnResult;
    int    m_nCount;

    float  m_fTotalX, m_fTotalY;
    float  m_fDeltaX, m_fDeltaY;
    float  m_fDeltaXX, m_fDeltaXY;
};

[LeastSquareMethod.cpp]
### cpp
#include "LeastSquareMethod.h"

LeastSquareMethod::LeastSquareMethod(void)
{
    Reset();
}

LeastSquareMethod::~LeastSquareMethod(void)
{
}

void LeastSquareMethod::AddData(const LSMData& data)
{
    m_nCount++;
    Update(data);
}

Linear LeastSquareMethod::GetTrendency()
{
    return m_lnResult;
}

void LeastSquareMethod::Update(const LSMData& data)
{
    if(m_nCount == 1)
    {
        m_fTotalX    = data.x;
        m_fTotalY    = data.y;
        m_lnResult.a = data.x;
        m_lnResult.b = data.y;
        return;
    }

    float prevAvrX = m_fTotalX / (m_nCount-1);
    float prevAvrY = m_fTotalY / (m_nCount-1);
    float curAvrX = (m_fTotalX + data.x) / m_nCount;
    float curAvrY = (m_fTotalY + data.y) / m_nCount;

    float deltaXavr = curAvrX-prevAvrX;
    float deltaYavr = curAvrY-prevAvrY;

    // 이전 값을 재활용해 LSM 전개
    m_fDeltaXY    = m_fDeltaXY - deltaXavr*m_fDeltaY - deltaYavr*m_fDeltaX
                   + (m_nCount-1)*deltaXavr*deltaYavr        //    상수
                   + (data.x-curAvrX)*(data.y-curAvrY);        //    상수
    m_fDeltaXX    = m_fDeltaXX - 2*deltaXavr*m_fDeltaX + deltaXavr*deltaXavr*(m_nCount-1)
                   + (data.x-curAvrX)*(data.x-curAvrX);
    m_lnResult.a = m_fDeltaXY / m_fDeltaXX;
    m_lnResult.b = curAvrY - curAvrX*m_lnResult.a;

   

    // 다음 계산을 위해 변수 Update
    m_fTotalX += data.x;
    m_fTotalY += data.y;

    m_fDeltaX = m_fDeltaX - (curAvrX-prevAvrX)*(m_nCount-1) + data.x - curAvrX;
    m_fDeltaY = m_fDeltaY - (curAvrY-prevAvrY)*(m_nCount-1) + data.y - curAvrY;
}

[main.cpp]
### cpp
#include <cmath>
#include "LeastSquareMethod.h"
#define FLOAT_EQ(x, y, t) (abs(x-y) < t)

int _tmain(int argc, _TCHAR* argv[])
{
    NLeastSquareMethod nlsm;
    LSMData example[] = {
        {10, 71}, {20, 45}, {30, 24}, {40, 8}
    };
    int numOfData = sizeof(example)/sizeof(LSMData);

    LeastSquareMethod lsm;
    for(int i=0; i<numOfData; i++)
    {
        lsm.AddData(example[i]);
    }
    Linear lsmResult = lsm.GetTrendency();
   


    printf("Answer >> \n");
    printf("a : %.3f\tb : %.3f\n\n", -2.1f, 89.5f);

    printf("Fast LSM >> [%s]\n", (FLOAT_EQ(-2.1f, lsmResult.a, 0.0001f) && FLOAT_EQ(89.5f, lsmResult.b, 0.0001f))?"Success" : "Failed");
    printf("a : %.3f\tb : %.3f\n\n", lsmResult.a, lsmResult.b);
    return 0;
}
posted by 스펜서.

VC++ DLL 자동 버전 빌드 구성하기

Source Code 2010. 8. 6. 20:28

들어가면서……

여러 모듈로 나누어진 프로젝트의 각 모듈 담당자라면 누구나 한번쯤은 DLL의 버전관리가 안돼서 곤란한 경우가 있을 것이다. 언제 빌드한 DLL인지 헷갈리곤 한다. 그렇다고 매번 빌드해서 커밋할 때 마다 Version 리소스를 수정하는 것도 귀찮고, 까먹으면 곤란한 일이 꼭 발생한다. 그래서 이 아티클에서는 자동으로 DLL의 버전을 수정하는 방법을 소개한다. 이 아티클에서는 Visual Studio 2005를 기준으로 설명하겠다.

 

시작!!

Auto Versioning Build는 다음과 같은 단계로 이루어진다.

1. [빌드 전] Version을 정의한 파일을 Update한다.

2. [빌드 중] 정의된 Version을 리소스 파일에 반영한다.

생각보다 단순하다. 지금부터 1번과 2번을 나누어 설명하도록 하겠다.

 

1. [빌드 전] Version을 정의한 파일을 Update한다.

2번을 가능하게 하려면, Version #define 구문을 이용해서 정의해야 한다. 필자는 다음과 같이 정의했다.

 

#define FILE_VERSION    3,0,806,2

#define PRODUCT_VERSION    3,0,0,0

#define STR_FILE_VERSION    "3,0,806,2\0"

#define STR_PRODUCT_VERSION    "3,0,0,0\0"

 

버전을 나타내는 문자열은 다양한 것들이 있지만, 주로 빈번히 바뀔 파일 버전과 제품 버전만 정의하였다. 그리고 “STR_”로 시작하는 선언은 문자열 형태로 버전을 정의한 항목이다. 나중에 리소스파일을 열어보면 문자열로 주어야 하는 항목이 있기 때문이다.

이와 같이 작성한 파일을 [VersionInfo.h]하고 소스가 있는 프로젝트 폴더에 저장했다.

 

그 다음은 이 [VersionInfo.h]를 업데이트할 프로그램을 구현해야 한다. 필자는 버전을 다음과 같은 버전 정책을 사용하였다.

  • 제품 버전의 맨 뒤, 두 자리는 0으로 고정.

  • 제품 버전의 앞 두 자리는 파일 버전의 앞 두 자리와 동일

  • 파일 버전의 세 번째 자리는 빌드 날짜

  • 파일 버전의 네 번째 자리는 해당 날짜에 빌드한 횟수


예를 들어, 제품 버전이 3.0.0.0이고 오늘 날짜가 8 6일이고, 빌드 횟수가 19이면 파일 버전은 3.0.806.19가 되는 것이다. 버전 정책은 사람마다, 회사마다 다르니까 입맛에 맞게 정책을 세우길 바란다.

 

이제, 본인이 세운 버전 정책에 맞게 [VersionInfo.h]를 업데이트 할 프로그램을 구현해야 한다. DLL의 버전 정책을 고민할 개발자라면 이 정도는 구현할 거라 믿는다. [Annex A]에 필자가 구현한 소스를 첨부한다. 참고하실 분은 참고하길 바란다(매우 단순 무식하게 구현하였음). 필자는 제품 버전과 파일 버전을 먼저 파싱하고, 이를 바탕으로 다음 버전을 업데이트 하도록 하였다. 그래서 개발자가 제품 버전의 앞 두 버전을 수정하면 이것이 자연스럽게 파일 버전에 적용되고, 빌드 횟수는 파일 버전의 맨 뒤 버전 +1을 하여 구하도록 하였다. 만약, 날짜를 나타내는 세 번째 버전 필드가 오늘 날짜와 다르면 네 번째 버전 필드를 1로 초기화 하도록 하였다.

 

다음은 [VersionInfo.h]가 버전 리소스에 참조가 되게끔 수정해보자.

 

2. [빌드 중] 정의된 Version을 리소스 파일에 반영한다.

Visual Studio 2005로 개발하면 아마 [(프로젝트명).rc]파일과 [res\(프로젝트명).rc2]라는 파일을 봤을 것이다. 두 파일 모두 리소스를 정의하는 파일이지만 열어보면 많이 다른 것을 알 수 있다.

먼저 [(프로젝트명).rc]를 살펴보자.

 

// Microsoft Visual C++ generated resource script.

//

#include "resource.h"

 

#define APSTUDIO_READONLY_SYMBOLS

////////////////////////////////////////////////////////////////////////////

//

// Generated from the TEXTINCLUDE 2 resource.

//

#include "afxres.h"

(중간 생략)

#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_KOR)

#ifdef _WIN32

LANGUAGE 18, 1

#pragma code_page(949)

#endif //_WIN32

#include "res\MMLayer.rc2"     // non-Microsoft Visual C++ edited resources

#include "l.kor\afxres.rc"     // Standard components

#endif

 

///////////////////////////////////////////////////////////////////////////

#endif    // not APSTUDIO_INVOKED

 

아마 파일이 이와 다를 수 있다. 어쨌든 맨 위를 보면 자동으로 생성되는 스크립트임을 나타내는 주석이 달려있다. 아래를 보니 “non-Microsoft Visual C++ edited resources” 라는 주석이 [res\(프로젝트명).rc2]에 달려 있는 것을 볼 수 있다. rc파일은 IDE에 의해서 자동으로 생성되는 파일이므로 수정하면 안되고, 개발자가 원하는 리소스는 rc2파일에 기록하는 것임을 알 수 있다. 그럼 이제 [res\(프로젝트명).rc2]를 열어보자.

 

//

// MMLAYER.RC2 - resources Microsoft Visual C++ does not edit directly

//

#ifdef APSTUDIO_INVOKED

    #error this file is not editable by Microsoft Visual C++

#endif //APSTUDIO_INVOKED

 

//////////////////////////////////////////////////////////////////////////

// Add manually edited resources here...

//////////////////////////////////////////////////////////////////////////

 

빙고!! 수동으로 리소스를 추가하려면 여기에 하라고 써있다. 그럼 이제 여기에 Version 리소스를 추가해보자. 가장 쉬운 방법은 rc파일에 있는 VS_VERSION_INFO로 시작하는 섹션을 복사/붙여넣기로 추가하거나 아래 코드를 복사하면 된다.

 

VS_VERSION_INFO VERSIONINFO

 FILEVERSION 1.0.0.0

 PRODUCTVERSION 1.0.0.0

 FILEFLAGSMASK 0x17L

#ifdef _DEBUG

 FILEFLAGS 0x1L

#else

 FILEFLAGS 0x0L

#endif

 FILEOS 0x4L

 FILETYPE 0x2L

 FILESUBTYPE 0x0L

BEGIN

    BLOCK "StringFileInfo"

    BEGIN

        BLOCK "041204b0"

        BEGIN

            VALUE "CompanyName", "Medison"

            VALUE "FileDescription", "Version"

            VALUE "FileVersion", “1.0.0.0”

            VALUE "InternalName", "MMLayer.dll"

            VALUE "LegalCopyright", "Copyright (C) 2010"

            VALUE "OriginalFilename", "MMLayer.dll"

            VALUE "ProductName", "Medison Ultrasound Equipment"

            VALUE "ProductVersion", “1.0.0.0”

        END

    END

    BLOCK "VarFileInfo"

    BEGIN

        VALUE "Translation", 0x412, 1200

    END

END

 

천천히 읽어보면 대충 감이 올꺼다. 회사 이름, 파일 설명, 파일 버전, 내부 이름, 회사 이름 등등 IDE에서 우리가 삽입했던 이름들이다. 여기서 우리가 눈 여겨 봐야 할 부분은 아래 4가지이다.

  • FILEVERSION

  • PRODUCTVERSION

  • “FileVersion”

  • “ProductVersion”

이제 위 항목에 1.0.0.0으로 되어 있는 부분을 우리가 정의한 FILE_VERSION, PRODUCT_VERSION, STR_FILE_VERSION, STR_PRODUCT_VERSION을 대입해 주면 된다.

 

어떻게 하면 좋을까? 눈치 빠른 사람이라면 알 것이다. 자세히 보면, C++에 있는 전처리 명령어들이 있는 것을 볼 수 있다. 즉 맨 위에 우리가 만든 [VersionInfo.h] Include하고 1.0.0.0으로 되어 있는 부분을 적절한 define 항목으로 바꾸면 되는 것이다. 아래는 필자의 rc2파일이다.

//

// MMLAYER.RC2 - resources Microsoft Visual C++ does not edit directly

//

#include "..\\VersionInfo.h"

 

#ifdef APSTUDIO_INVOKED

    #error this file is not editable by Microsoft Visual C++

#endif //APSTUDIO_INVOKED

 

 

/////////////////////////////////////////////////////////////////////////////

// Add manually edited resources here...

/////////////////////////////////////////////////////////////////////////////

VS_VERSION_INFO VERSIONINFO

 FILEVERSION FILE_VERSION

 PRODUCTVERSION PRODUCT_VERSION

 FILEFLAGSMASK 0x17L

#ifdef _DEBUG

 FILEFLAGS 0x1L

#else

 FILEFLAGS 0x0L

#endif

 FILEOS 0x4L

 FILETYPE 0x2L

 FILESUBTYPE 0x0L

BEGIN

    BLOCK "StringFileInfo"

    BEGIN

        BLOCK "041204b0"

        BEGIN

            VALUE "CompanyName", "Medison"

            VALUE "FileDescription", "Version"

            VALUE "FileVersion", STR_FILE_VERSION

            VALUE "InternalName", "MMLayer.dll"

            VALUE "LegalCopyright", "Copyright (C) 2010"

            VALUE "OriginalFilename", "MMLayer.dll"

            VALUE "ProductName", "Medison Ultrasound Equipment"

            VALUE "ProductVersion", STR_FILE_VERSION

        END

    END

    BLOCK "VarFileInfo"

    BEGIN

        VALUE "Translation", 0x412, 1200

    END

END

빨간색 부분이 필자가 수정한 부분이다. 이렇게 하면 리소스 파일을 컴파일 할 때, [VersionInfo.h] 파일을 참조해서 컴파일하게 된다.

 

3. IDE 설정하기

여기까지 했으면, 거의 다 했다. 이제, 빌드 하기 전에 [VersionInfo.h]를 업데이트하도록 우리가 1번에서 구현한 프로그램을 실행시키게끔 IDE에 설정하면 된다.

프로젝트 > 속성 > 구성속성 > 빌드 이벤트에 보면 세가지 이벤트가 있다.

  • 빌드 전 이벤트

  • 링크 전 이벤트

  • 빌드 후 이벤트

각각은 이름만 봐도 언제 일어나는 이벤트인지 알 수 있을 것이다. 각각의 이벤트를 눌러보면 [명령줄]이란 항목이 있는데, 여기에 우리가 개발한 프로그램을 등록시키면 간단히 해결된다. 필자는 [DllVersion.exe]이라고 프로그램을 구현했으며, 소스가 있는 폴더에 함께 넣어놓았다. 다음은 설정하는 곳의 스크린샷이다.

 

 

필자는 Release로 빌드 했을 때만 버전 정보를 업데이트 하기 위해서 Release [빌드 전 이벤트]에 추가하였다. 이렇게 설정하고 빌드하면 자동으로 [VersionInfo.h]를 업데이트하고 빌드를 시작하게 된다.

 

끝내며……

비록 중간에 파일을 파싱하고 다시 출력하는 프로그램을 구현해야 하는 귀찮음이 있지만(물론 Annex A의 소스를 가져가면 덜 하겠지만…), 한번 해 놓으면 나중에 발생할 고생을 덜 하게 될 것이다. 한번쯤 해보면, 쉽게 다른 프로젝트에 적용 가능하니 시간 내서 해 보기를 권장한다.


Annex A

 

#include <stdio.h>

#include <time.h>

 

int main()

{

    FILE* version = NULL;

    fopen_s(&version, "VersionInfo.h", "r");

 

    if(version == NULL)

    {

        printf("File is not found. : VersionInfo.h\n");

        return -1;

    }

 

    char bufFileVer[1024];

    char bufProductVer[1024];

    char bufStrFileVer[1024];

    char bufStrProductVer[1024];

 

    fgets(bufFileVer, 1024, version);

    fgets(bufProductVer, 1024, version);

    fclose(version);

   

    int fileVer[4] = {0, };

    int productVer[4] = {0, };

 

    sscanf_s(bufFileVer, "#define FILE_VERSION\t%d,%d,%d,%d",

      &fileVer[0], &fileVer[1], &fileVer[2], &fileVer[3]);

       sscanf_s(bufProductVer, "#define PRODUCT_VERSION\t%d,%d,%d,%d",

         &productVer[0], &productVer[1], &productVer[2], &productVer[3]);

 

    fileVer[0] = productVer[0];

    fileVer[1] = productVer[1];

    productVer[2] = 0;

    productVer[3] = 0;

 

    tm today;

    time_t now;

    time(&now);

    _localtime64_s(&today, &now);

 

    int day = (today.tm_mon + 1) * 100 + today.tm_mday;

 

    if(day != fileVer[2])

    {

        fileVer[2] = day;

        fileVer[3] = 1;

    }

    else

    {

        fileVer[3]++;

    }

    printf(" \n \n");

    printf("= MMLayer Version. =====================\n");

    printf("   File    Ver.%5d,%5d,%5d,%5d\n",

      fileVer[0], fileVer[1], fileVer[2], fileVer[3]);

    printf("   Product Ver.%5d,%5d,%5d,%5d\n",

      productVer[0], productVer[1], productVer[2], productVer[3]);

    printf("========================================\n");

    printf(" \n \n");

 

   

    fopen_s(&version, "VersionInfo.h", "w+");

 

    if(version == NULL)

    {

        printf("File is not found. : VersionInfo.h\n");

        return -1;

    }

 

    sprintf_s(bufFileVer, "#define FILE_VERSION\t%d,%d,%d,%d\n",

      fileVer[0], fileVer[1], fileVer[2], fileVer[3]);

    sprintf_s(bufStrFileVer, "#define STR_FILE_VERSION\t\"%d,%d,%d,%d\\0\"\n",

      fileVer[0], fileVer[1], fileVer[2], fileVer[3]);

 

    sprintf_s(bufProductVer, "#define PRODUCT_VERSION\t%d,%d,%d,%d\n",

      productVer[0], productVer[1], productVer[2], productVer[3]);

    sprintf_s(bufStrProductVer, "#define STR_PRODUCT_VERSION\t\"%d, %d,%d,%d\\0\"\n",

      productVer[0], productVer[1], productVer[2], productVer[3]);

 

    fprintf_s(version, "%s", bufFileVer);

    fprintf_s(version, "%s", bufProductVer);

    fprintf_s(version, "%s", bufStrFileVer);

    fprintf_s(version, "%s", bufStrProductVer);

 

    fclose(version);

   

    return 0;

}

 

 

posted by 스펜서.

다음 영어사전 Ubiquity 명령어

Web 2009. 8. 2. 15:09
다음 영어사전 Ubiquity 명령어입니다. Ubiquity 0.5.1 기준으로 동작하고, 새로 업데이트된 명령구문을 사용하였기 때문에 이전버전 사용자는 정상적으로 작동하지 않을수 있습니다.

명령어는 두가지 입니다.
set-daum-dic-key : 다음 오픈 API에 가셔서 사용자 키를 받으셔야 합니다. "오픈 API 사용자 등록" 이라는 메뉴를 누르셔서 사전 API 키를 발급받으시면 됩니다. 그래서 다음과 같이 입력하면 됩니다.

그림1. 사용자 키 설정
만약 공용으로 쓰는 PC에서 설정하였을 경우, "set-daum-dic-key reset"을 입력하시면 초기화가 됩니다.

정상적으로 Key를 입력하지 않으면 dic 명령을 이용해 검색할 때 다음과 같이 나옵니다.
그림2. 잘못된 키 설정이 되었을 경우의 에러메시지

dic : 사전 검색은 Preview에서 최대 5개의 검색 결과를 보여주며, 엔터를 치면 검색 결과 화면이 새 탭으로 뜨게 됩니다. 다음 그림은 예제입니다.
그림3. 검색 결과

버그나 건의사항은 댓글로 남겨주시거나 메일주시면 빠른 시간내에 반영하도록 하겠습니다.
posted by 스펜서.

jQuery 탭 컨트롤

Web 2009. 6. 2. 03:10
얼떨결에 "한번 만들어볼까?" 해서 만들어본 탭 컨트롤.



jQuery 하면 할수록 재미있는거 같아!!!

첨부된 파일은 소스코드이다.


posted by 스펜서.

자꾸만 까먹는 웹 개발 소스 및 링크

Web 2009. 6. 1. 16:27
SQL 쿼리
     TIP
        1. SELECT에 조인을 잘 쓰자
        2. MySQL 의 주요 SQL 문법 [ http://tinyurl.com/mqc7lk ] 참고 굉장히 자세함.

    - SELECT
SELECT [테이블별칭].[컬럼] AS [별칭] FROM [테이블] AS [별칭], WHERE [조건] AND [컬럼] (NOT) IN (SELECT 쿼리) ORDER BY [컬럼] GROUP BY [컬럼];

    - INSERT
INSERT INTO [테이블]( [컬럼], ) VALUES ( [], );

    - DELETE
DELETE FROM [테이블] WHERE [조건];

    - UPDATE
UPDATE [테이블] SET([컬럼]=[], ) WHERE [조건];

    - 테이블 지우기
DROP TABLE [테이블]

    - 테이블 만들기
CREATE TABLE sms4_long_send(
    no bigint(20) not null auto_increment,
    primary key(no),
    user varchar(255),
    sn_no   varchar(100),
    c_seq   bigint(20),
    c_no    varchar(100),
    time datetime,
    msg text
);
    - 컬럼 추가하기
ALTER TABLE [테이블] ADD ([컬럼] [자료형] [기본값], )

   
- 컬럼 삭제하기
ALTER TABLE [테이블] DROP COLUMN [컬럼];

    - 컬럼 이름바꾸기
ALTER TABLE [테이블] RENAME COLUMN [OLD_컬럼] [NEW_컬럼];

    - 행 개수세기
SELECT COUNT(*) AS [별칭] FROM [테이블] ;

    - 결과 개수 제한하기
SELECT * FROM [테이블] LIMIT [시작], [개수];

jQuery로 작업하기 시리즈

jQuery 항목별 정리

jQuery <select>의 <option>바꾸기



스크롤바 색깔
[ http://imfree.pe.kr/scrollbar1.html ]

자주쓰는 PHP 함수
explode("구분자", "문자열") : "문자열"에서 "구분자"가 있는 곳을 나누어 리턴(array)
ereg("정규식", "문자열") : "문자열"에 "정규식"에 해당하는 것이 있는지 리턴(bool)
iconv("from인코딩", "to인코딩", "문자열") : "from인코딩"으로 인코딩된 "문자열"을 "to인코딩"으로 인코딩하여 리턴(string)
str_replace("단어", "치환", "문자열") : "문자열"에서 "단어"를 "치환"으로 바꾸어 리턴(string)
base64_encode("문자열") : "문자열"을 base64로 인코딩하여 리턴(string)
chunk_split("문자열") : 일정한 길이로 문자열을 잘라주어 리턴(string). 폼메일 만들때 사용
urlencode("문자열") : "문자열"을 url 형태로 인코딩하여 리턴(string)
strtotime("문자열") : "문자열"을 날짜로 리턴(sec)
date("형식"[, "날짜"]) : 오늘의 날짜를 "형식"으로 리턴(string)하거나, "날짜"를 "형식"으로 리턴(string)
substr("문자열", "시작", "개수") : "문자열"을 "시작"에서 부터 "개수"만큼 잘라 리턴(string)

posted by 스펜서.

너무 더워~ㅠ_ㅠ

끄적끄적 2009. 5. 25. 14:33


어휴 연구실 에어콘 고장나서 급히 컴퓨터 쿨러 떼어내서 만든 선풍기-_-

만들고 나니까 더 더워..ㅠ_ㅠ
posted by 스펜서.

L-O-V-E

끄적끄적 2009. 5. 23. 15:57



 - Natalie Cole


L is for the way you look at me.
O is for the only one I see.
V is very very extraordinary.
E is even more than anyone that you adore can
Love, it's all that I can give to you.
Love is more that just a game for two.
Two in love can make it
Take my heart but please don't break it.
Love was made for me and you.



ya~ L is for the way you look at me.
and O is for the only one I see.
V is so very very extraordinary.
E is even more than any any any anyone that you adore can
Love, it's all that I can give to you.
oh~ Love is more that just a game for two.
Two in love can make it
Take my heart but please don't break it.

Love was made for me and you.

I'm giving giving ove that's made for me and you,
just Don't you know that love was made for me and you.




영석이형하고 정민이누나가 윤실누나 결혼식때 멋지게 부른 노래!! 완전 빠졌다~  > _<
posted by 스펜서.