레이블이 win32인 게시물을 표시합니다. 모든 게시물 표시
레이블이 win32인 게시물을 표시합니다. 모든 게시물 표시

2010년 7월 9일 금요일

haskell 로 Win32 HelloWorld 만들어봤다..

haskell 에 Win32 패키지가 어느정도 써먹을수 있는지 궁금해서 google 에서 win32 api hello world 코드를 찾아내서 haskell 로 옮겨봤다. 다시 생각해보면 미친짓이었음.

http://www.codepedia.com/1/Win32APIHelloWorld



펼쳐두기..



2010년 4월 14일 수요일

플래폼 SDK? 윈도우 SDK?



내가 윈도코딩하던 시절은 그냥 플래폼 SDK 였는데 지금은 닷넷 SDK 와 함께  윈도 SDK 로 합쳐진 모양.
정확한 용어를 알고 사용해야겠지.

http://en.wikipedia.org/wiki/Microsoft_Windows_SDK

The difference between these three SDKs lies in their area of specialization: Platform SDK specializes in developing applications for Windows 2000, XP and Windows Server 2003. .NET Framework SDK is dedicated to developing applications for .NET Framework 1.1 and .NET Framework 2.0. Windows SDK is the successor of the two and supports developing applications for Windows XP, Windows Vista, Windows 7, Windows Server 2008, .NET Framework 3.0 and .NET Framework 3.5.[2]It contains extensive documentation and nearly 1000 samples.



분명 내기억에는 플래폼 SDK 이고 버전도 연도로 붙던것으로 기억하는데 최근들어 뒤져보니 WinSDK 7.0 뭐 이런식으로 불리고 있길래 궁금해서 찾아봤다.

2010년 3월 9일 화요일

ogre, 비율을 유지하며 리사이징하기

이게 몇년만의 서브클래싱이냐?
win32 API 들이 아직도 기억나는게 신기하다.


그럴듯한 창모드 어플을 만드려면 리사이징이 자연스러워야 하는데 ogre 쪽에선 이걸 해주는 코드를 못찾았다. 윈도이벤트리스너 라고 리스너를 달아서 windowMoved, windowResized 등을 받는게 가능하긴 한데 리사이즈 된 뒤의 이벤트를 받는 거라 내가 원하는 동작을 하기엔 좀 무리가 있었다. 하지만 이 놈은 windowClosed 등 유용한 이벤트들이 떨어지니 어차피 코딩을 해야할놈이긴 하다.. 이쪽 코드는 블로그에 적어두진 않겠지만 필요하면  WindowEventUtilities 와 WindowEventListener 클래스를 참고해보자.


결국 내가 원하는 WM_SIZING 처리를 위해서는.. 서브클래싱을 해야했다. 헐 추억의 서브클래싱. WindowEventUtilities 가 wndProc 을 들고있으니 적절히 참고하면서 아래 코드를 만들었다. 아래 코드는 아직 리사이징이 좀 어색한게 남아있는데.. 일단 여기 적어둔다.

아 리사이징 가장 어색한게 window7 에서 사이징을 하면 모서리에 붙어버리는듯한 동작이 나오던데.. 간만에 msdn 좀 뒤져봐야겠다.

[code cpp]
typedef LRESULT (*WindowProcType)(HWND,UINT,WPARAM,LPARAM);
WindowProcType oldWndProc;
static void subclassRenderWindow(RenderWindow* w);
static LRESULT wndProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam);

void subclassRenderWindow(RenderWindow* w)
{
    if(oldWndProc) return;
    HWND handle;
    w->getCustomAttribute("WINDOW", &handle);
    oldWndProc = (WindowProcType)SetWindowLong(handle, GWL_WNDPROC, (DWORD)&wndProc);
};
LRESULT wndProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
    // WindowEventUtilities::_WndProc 에 의하면 WM_CREATE 보다 WM_SIZE
    // 가 먼저 떨어질수도 있다네. 그랬던가? 어쨌건 저놈이 관련처리를
    // 해주고 있으니 나도 그코드를 퍼올렸다.
    // RenderWindow* w = (RenderWindow*)GetWindowLongPtr(wnd,GWLP_USERDATA);
    // if(!w) return oldWndProc(wnd, msg, wparam, lparam);

    switch(msg)
    {
    // 최소 사이즈 지정
    case WM_GETMINMAXINFO:
    {
        MINMAXINFO* mmi = (MINMAXINFO*)lparam;
        mmi->ptMinTrackSize.x = 800;
        mmi->ptMinTrackSize.y = 600;
        return 0;
    }
    // 아 씨댕 생각보다 복잡한 코드를 만들어야 하네.
    // 어느위치로 땡기는지에 따라 달리 계산해줘야 한다.
    // 조건을 좀더 합치는것도 되겠지만 아직 부자연스러운 움직임이 있어 그냥 둬본다.
    case WM_SIZING:
    {
        const double ratio = 1.33333;
        RECT* rc = (RECT*)lparam;
        int width = rc->right - rc->left;
        int height = rc->bottom - rc->top;
        if(wparam == WMSZ_LEFT || wparam == WMSZ_RIGHT)
        {
            int h = static_cast<int>(width / ratio);
            rc->bottom = rc->top + h;
        }
        else if(wparam == WMSZ_TOP || wparam == WMSZ_BOTTOM)
        {
            int w = static_cast<int>(height * ratio);
            rc->right = rc->left + w;
        }
        else if(wparam == WMSZ_TOPLEFT || wparam == WMSZ_BOTTOMLEFT)
        {
            int w = static_cast<int>(height * ratio);
            rc->left = rc->right - w;
        }
        else if(wparam == WMSZ_TOPRIGHT || wparam == WMSZ_BOTTOMRIGHT)
        {
            int w = static_cast<int>(height * ratio);
            rc->right = rc->left + w;
        }
        return FALSE;
    }
    default:
        break;
    }
    return oldWndProc(wnd, msg, wparam, lparam);
}
[/code]



2010/07/08 추가.

와.. 이게 생각보다 빡치는 문제였네.
이전 코드는 비율만 맟춰본 거였고.. 사실상 크기를 정확히 맟추려면 약간의 보정을 해줘야 한다. WM_SIZING 시 떨어지는 rect 는 스크린좌표이기 때문에 내가 원하는 크기가 800*600 이라고 해서 800*600 으로 맟춰버리면 윈도우가 그려주는 넌클라이언트 영역들때문에 800*600 에서 조금씩 짤린 크기가 되버린다. 이런 경우를 위해 AdjustWindwRect(Ex) 함수가 있는데.. CreateWindow 가 오우거안에 숨어있어서 ( D3DRenderWindow::create 참고 ).. 내가 원하던 클라이언트 사이즈와 만들어진 윈도우의 스크린 사이즈의 차이를 기억해뒀다가 sizing 시 보정해주는 방법을 썼다.

아래는 코드 일부,  내가 원했던 크기와 실제 만들어진 크기의 차이를 기억해 두는 함수
[code cpp]
void FerrariApp::prepareSizing()
{
    HWND handle;
    getRenderWindow()->getCustomAttribute("WINDOW", &handle);

    int wantedWidth  = config.getVideoWidth();
    int wantedHeight = config.getVideoHeight();

    RECT rc;
    GetWindowRect(handle, &rc);
    int realWidth  = rc.right - rc.left;
    int realHeight = rc.bottom - rc.top;

    adjustSize_.first  = realWidth - wantedWidth;
    adjustSize_.second = realHeight - wantedHeight;

    trace("adjustSize_ %d %d\n", adjustSize_.first, adjustSize_.second);
}
[/code]

다시 코드 일부, 처음 적었던 코드에 위에서 기억해둔 사이즈를 보정해주는 코드를 추가한것
[code cpp]
LRESULT FerrariApp::onSizing(HWND hwnd, WPARAM wparam, LPARAM lparam)
{
    const double ratio = static_cast<double>(config.getVideoWidth()) / static_cast<double>(config.getVideoHeight());

    RECT* rc = (RECT*)lparam;

    rc->left   += adjustSize_.first  / 2;
    rc->top    += adjustSize_.second / 2;
    rc->right  -= adjustSize_.first  / 2;
    rc->bottom -= adjustSize_.second / 2;
   
    double width = rc->right - rc->left;
    double height = rc->bottom - rc->top;
    if(wparam == WMSZ_LEFT || wparam == WMSZ_RIGHT)
    {
        int h = static_cast<int>(width / ratio);
        rc->bottom = rc->top + h;
    }
    else if(wparam == WMSZ_TOP || wparam == WMSZ_BOTTOM)
    {
        int w = static_cast<int>(height * ratio);
        rc->right = rc->left + w;
    }
    else if(wparam == WMSZ_TOPLEFT || wparam == WMSZ_BOTTOMLEFT)
    {
        int w = static_cast<int>(height * ratio);
        rc->left = rc->right - w;
    }
    else if(wparam == WMSZ_TOPRIGHT || wparam == WMSZ_BOTTOMRIGHT)
    {
        int w = static_cast<int>(height * ratio);
        rc->right = rc->left + w;
    }

    rc->left   -= adjustSize_.first  / 2;
    rc->top    -= adjustSize_.second / 2;
    rc->right  += adjustSize_.first  / 2;
    rc->bottom += adjustSize_.second / 2;
   
    return FALSE;
}
[/code]

아직도 좀 어색하게 돌아가는데 천천히 잡아보자.






2009년 5월 19일 화요일

GetIt, windows 에서 apt-get 비스무리 흉내내기

http://puchisoft.com/GetIt/

아주 오래전 봐둔 링크가 갑자기 기억나서 깔아보려다가.. 이것저것 깔라는게 많아서 그냥 여기 적어두고 다시 덮어둘란다. 대강 보니까 여러 어플들을 깔아야 완전한 서비스가 되는 모양인데 나중에 왜 이런 꼴인지 읽어보자.

음 방금 깔아보니 다른 두 어플이 리파지토리를 관리하고 GetIt 이 그걸 제어하는 모양인데.. 이 두놈이 피같은 하드를 많이도 처먹네(파이썬으로 만들어서 exe 로 배포.. 후랄 젠장 이딴거 정말 짱난다. 물론 이게 개발자가 편하고, 나도 이런식으로 배포하는걸 먼저 고려하겠지만.. 하드가 이제 싸다느니 램은 이제 문제가 안된다느니 하는 소릴 하는거 보면 정말 욕나온다. 나도 그런개소리를 종종 해야 하지만...)

지워야 쓰것다.

나중에.. 사무실에서 윈도 쓰면 그때 다시 깔아보자.


추가.
가장 가벼운 windows-get 만이라도 깔아봤는데 지금 사이트가 죽은건가 되는게 없네. 다음에 다시 확인해보자.

추가.
음 위 프로젝트는 죽었네. 포럼 가보니 http://win-get.sourceforge.net 도 있던데 이건 일단 리파지토리가 살아있는건 확인을 했지만 이쪽 포럼도 전혀 관리가 안되고 있더라.

그냥 전부 잊어먹고 수작업하자.

추가.
http://win-get.ayalasoft.com/ 이쪽도 win-get 이네.. 돌려보진 않았지만 최근까지 업데이트가 되고있네.

추가.
http://code.google.com/p/qwinapt/ 이런놈도 있다. 어휴.. 이런게 찾으면 자꾸 나오네. 하지만 대세탄 어플은 없으니 뭘 써도 관리문제가 있고 또 apt-get 처럼 편한것도 아니다.


추가 2009/11/11
http://ninite.com/ 클리앙에서 봤는데, 흠 이런식의 모음도 괜찮아 보인다. 다음에 PC 세팅할때 고려해보자. 그때 이게 기억났으면 좋겠다.

2008년 7월 22일 화요일