Gurps 4판/ 국문 2판의 캐릭터 시트입니다.

시트 툴은 언제 MFC로 컨버전하나[..]



크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia
Getting the System Version

The following example uses the GetVersionEx, GetSystemMetrics, GetProductInfo, and GetNativeSystemInfo functions to determine the version information of the currently running operating system. The example displays the information to the console.

Relying on version information is not the best way to test for a feature. Instead, refer to the documentation for the feature of interest. For more information on common techniques for feature detection, see Operating System Version.

If you must require a particular operating system, be sure to use it as a minimum supported version, rather than design the test for the one operating system. This way, your detection code will continue to work on future versions of Windows.

 
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <strsafe.h>

#define BUFSIZE 256

typedef void (WINAPI *PGNSI)(LPSYSTEM_INFO);
typedef BOOL (WINAPI *PGPI)(DWORD, DWORD, DWORD, DWORD, PDWORD);

BOOL GetOSDisplayString( LPTSTR pszOS)
{
   OSVERSIONINFOEX osvi;
   SYSTEM_INFO si;
   PGNSI pGNSI;
   PGPI pGPI;
   BOOL bOsVersionInfoEx;
   DWORD dwType;

   ZeroMemory(&si, sizeof(SYSTEM_INFO));
   ZeroMemory(&osvi, sizeof(OSVERSIONINFOEX));

   osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);

   if( !(bOsVersionInfoEx = GetVersionEx ((OSVERSIONINFO *) &osvi)) )
      return 1;

   // Call GetNativeSystemInfo if supported or GetSystemInfo otherwise.

   pGNSI = (PGNSI) GetProcAddress(
      GetModuleHandle(TEXT("kernel32.dll")), 
      "GetNativeSystemInfo");
   if(NULL != pGNSI)
      pGNSI(&si);
   else GetSystemInfo(&si);

   if ( VER_PLATFORM_WIN32_NT==osvi.dwPlatformId && 
        osvi.dwMajorVersion > 4 )
   {
      StringCchCopy(pszOS, BUFSIZE, TEXT("Microsoft "));

      // Test for the specific product.

      if ( osvi.dwMajorVersion == 6 && osvi.dwMinorVersion == 0 )
      {
         if( osvi.wProductType == VER_NT_WORKSTATION )
             StringCchCat(pszOS, BUFSIZE, TEXT("Windows Vista "));
         else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2008 " ));

         pGPI = (PGPI) GetProcAddress(
            GetModuleHandle(TEXT("kernel32.dll")), 
            "GetProductInfo");

         pGPI( 6, 0, 0, 0, &dwType);

         switch( dwType )
         {
            case PRODUCT_ULTIMATE:
               StringCchCat(pszOS, BUFSIZE, TEXT("Ultimate Edition" ));
               break;
            case PRODUCT_HOME_PREMIUM:
               StringCchCat(pszOS, BUFSIZE, TEXT("Home Premium Edition" ));
               break;
            case PRODUCT_HOME_BASIC:
               StringCchCat(pszOS, BUFSIZE, TEXT("Home Basic Edition" ));
               break;
            case PRODUCT_ENTERPRISE:
               StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
               break;
            case PRODUCT_BUSINESS:
               StringCchCat(pszOS, BUFSIZE, TEXT("Business Edition" ));
               break;
            case PRODUCT_STARTER:
               StringCchCat(pszOS, BUFSIZE, TEXT("Starter Edition" ));
               break;
            case PRODUCT_CLUSTER_SERVER:
               StringCchCat(pszOS, BUFSIZE, TEXT("Cluster Server Edition" ));
               break;
            case PRODUCT_DATACENTER_SERVER:
               StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition" ));
               break;
            case PRODUCT_DATACENTER_SERVER_CORE:
               StringCchCat(pszOS, BUFSIZE, TEXT("Datacenter Edition (core installation)" ));
               break;
            case PRODUCT_ENTERPRISE_SERVER:
               StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition" ));
               break;
            case PRODUCT_ENTERPRISE_SERVER_CORE:
               StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition (core installation)" ));
               break;
            case PRODUCT_ENTERPRISE_SERVER_IA64:
               StringCchCat(pszOS, BUFSIZE, TEXT("Enterprise Edition for Itanium-based Systems" ));
               break;
            case PRODUCT_SMALLBUSINESS_SERVER:
               StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server" ));
               break;
            case PRODUCT_SMALLBUSINESS_SERVER_PREMIUM:
               StringCchCat(pszOS, BUFSIZE, TEXT("Small Business Server Premium Edition" ));
               break;
            case PRODUCT_STANDARD_SERVER:
               StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition" ));
               break;
            case PRODUCT_STANDARD_SERVER_CORE:
               StringCchCat(pszOS, BUFSIZE, TEXT("Standard Edition (core installation)" ));
               break;
            case PRODUCT_WEB_SERVER:
               StringCchCat(pszOS, BUFSIZE, TEXT("Web Server Edition" ));
               break;
         }
         if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
            StringCchCat(pszOS, BUFSIZE, TEXT( ", 64-bit" ));
         else if (si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_INTEL )
            StringCchCat(pszOS, BUFSIZE, TEXT(", 32-bit"));
      }

      if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 2 )
      {
         if( GetSystemMetrics(SM_SERVERR2) )
            StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Server 2003 R2, "));
         else if ( osvi.wSuiteMask==VER_SUITE_STORAGE_SERVER )
            StringCchCat(pszOS, BUFSIZE, TEXT( "Windows Storage Server 2003"));
         else if( osvi.wProductType == VER_NT_WORKSTATION &&
                  si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64)
         {
            StringCchCat(pszOS, BUFSIZE, TEXT( "Windows XP Professional x64 Edition"));
         }
         else StringCchCat(pszOS, BUFSIZE, TEXT("Windows Server 2003, "));

         // Test for the server type.
         if ( osvi.wProductType != VER_NT_WORKSTATION )
         {
            if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_IA64 )
            {
                if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition for Itanium-based Systems" ));
                else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition for Itanium-based Systems" ));
            }

            else if ( si.wProcessorArchitecture==PROCESSOR_ARCHITECTURE_AMD64 )
            {
                if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter x64 Edition" ));
                else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise x64 Edition" ));
                else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard x64 Edition" ));
            }

            else
            {
                if ( osvi.wSuiteMask & VER_SUITE_COMPUTE_SERVER )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Compute Cluster Edition" ));
                else if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Edition" ));
                else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Enterprise Edition" ));
                else if ( osvi.wSuiteMask & VER_SUITE_BLADE )
                   StringCchCat(pszOS, BUFSIZE, TEXT( "Web Edition" ));
                else StringCchCat(pszOS, BUFSIZE, TEXT( "Standard Edition" ));
            }
         }
      }

      if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 1 )
      {
         StringCchCat(pszOS, BUFSIZE, TEXT("Windows XP "));
         if( osvi.wSuiteMask & VER_SUITE_PERSONAL )
            StringCchCat(pszOS, BUFSIZE, TEXT( "Home Edition" ));
         else StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
      }

      if ( osvi.dwMajorVersion == 5 && osvi.dwMinorVersion == 0 )
      {
         StringCchCat(pszOS, BUFSIZE, TEXT("Windows 2000 "));

         if ( osvi.wProductType == VER_NT_WORKSTATION )
         {
            StringCchCat(pszOS, BUFSIZE, TEXT( "Professional" ));
         }
         else 
         {
            if( osvi.wSuiteMask & VER_SUITE_DATACENTER )
               StringCchCat(pszOS, BUFSIZE, TEXT( "Datacenter Server" ));
            else if( osvi.wSuiteMask & VER_SUITE_ENTERPRISE )
               StringCchCat(pszOS, BUFSIZE, TEXT( "Advanced Server" ));
            else StringCchCat(pszOS, BUFSIZE, TEXT( "Server" ));
         }
      }

       // Include service pack (if any) and build number.

      if( _tcslen(osvi.szCSDVersion) > 0 )
      {
          StringCchCat(pszOS, BUFSIZE, TEXT(" ") );
          StringCchCat(pszOS, BUFSIZE, osvi.szCSDVersion);
      }

      TCHAR buf[80];

      StringCchPrintf( buf, 80, TEXT(" (build %d)"), osvi.dwBuildNumber);
      StringCchCat(pszOS, BUFSIZE, buf);

      return TRUE; 
   }

   else
   {  
      printf( "This sample does not support this version of Windows.\n");
      return FALSE;
   }
}













출처는 M$DN
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia

생일

2008/07/11 17:54

뜬금없는 미역국을 마시고도 모르고있다가
알고보니 생일이더군요.

음력 생일이다보니 본인도 잘 모르는 [..]
..라지만 미역국 안의 쇠고기에 더 신경이 쓰이는건 기분 탓 입니까 [..]

오늘은 다행히 모든 문제가 잘 해결된 것 같습니다.
제 개발 일정만 빼고 [..]

뭐 그저께 짤릴 법[..]한 미스 때문에 난리친 뒤니까
바람직한 현상이로군요.

오늘 회식만 잘 가면 되겠습니다.




Ps.  일본 쪽과 작업하는건 무섭게 꼼꼼해야 합니다.
       ( 한국과는 다르다! 한국과는 (...) )

Ps2. 이사님 ㄳ [..]
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia

출처는 데브피아



윈도 탐색기로 부터 정보 빼오기


본 문서는 http://blogs.msdn.com/oldnewthing/archive/2004/07/20/188696.aspx
에서 가져와  본인이 직접 번역한 문서임을 밝혀 드립니다.
본 문서는 역자의 동의 없이 마음대로 복사/배포 할 수 있으며
만약 오역이나 오타가 있으면 댓글로 남겨주세요.


때로 Sotware 개발은 새로운 것들을 만들어낸다.
하지만 때로는 가지고 있는 것들을 조합하기도 한다.
오늘의 문제는 두번째 문제에 대한 것 중의 하나다.

윈도 핸들을 가지고 어떤게 윈도 탐색기인지 알아낼 수 있다,
그리고 만약 그렇다면 어떤 폴더를 보고있고, 어떤 항목이 focus되어있을까..?

이는 본래부터 어려운 작업이 아니다. 단순히 수 많은 작은 조각들을 껴 맞추기만 하면 된다.

열린 shell window들을 가져올 수 있는  ShellWindows object에서 부터 시작하자.
그러면 Item프로퍼티를 가지고 이 모든 항목들을 열거할 수 있다.
이 ShellWindows 객체는 Javascript나 Visual Basic과 같은 스크립팅 언어가 사용하도록
고안되어 있기 때문에 C++에서 사용하기에는 쫌..... 거시기하다.

- Shell Interface가 호환성을 비롯한 여러가지 이유로 COM Interface로 제작됬기 때문입니다.


 IShellWindows *psw;
 if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL,
                                IID_IShellWindows, (void**)&psw))) {
  VARIANT v;
  V_VT(&v) = VT_I4;
  IDispatch  *pdisp;
  BOOL fFound = FALSE;
  for (V_I4(&v) = 0; !fFound && psw->Item(v, &pdisp) == S_OK;
       V_I4(&v)++) {
    ...
    pdisp->Release();
  }
  psw->Release();
 }

각각의 item으로부터 우리는 item의 윈도 핸들을 가져올 수 있고,
그게 우리가 원하는 것이면 볼 수도 있다.

   IWebBrowserApp *pwba;
   if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) {
     HWND hwndWBA;
     if (SUCCEEDED(pwba->get_HWND((LONG_PTR*)&hwndWBA)) &&
       hwndWBA == hwndFind) {
       fFound = TRUE;
       ...
     }
     pwba->Release();
   }

됐다. 이제 우리는 IWebBrowserApp 인터페이스를 통해 폴더를 알아냈으니
Top shell browser로 가야한다.  
이 작업은 SID_STopLevelBrowsser 서비스를 쿼리하고
IShellBrowser인터페이스를 요청함으로 해결된다.

       IServiceProvider *psp;
       if (SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) {
         IShellBrowser *psb;
         if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser,
                              IID_IShellBrowser, (void**)&psb))) {
           ...
           psb->Release();
         }
         psp->Release();
       }

IShellBrowser로부터 우리는 QueryActiveShellView 매서드를 통해 현재 Shell View를 가져올 수 있다.

           IShellView *psv;
           if (SUCCEEDED(psb->QueryActiveShellView(&psv))) {
             ...
             psv->Release();
           }

당연한 이야기지만, 우리가 원하는것은 모든 알짜배기 데이터 값들이 저장되어있는 자동화 객체인
IFolderView인터페이스이다.

             IFolderView *pfv;
             if (SUCCEEDED(psv->QueryInterface(IID_IFolderView,
                                               (void**)&pfv))) {
               ...
               pfv->Release();
             }

OK, 우리는 다 얻었다. 이제 당신은 구한 view로 부터 무엇을 얻으려고 하는가?
현재 보여지고 있는 IShellFolder의 위치를 구해보는건 어떨까?
이 일을 하기 위해 우리는 IPersistFolder2::GetCurFolder매서드를 사용해야 한다.
GetFolder 매서드는 우리에게 IPersistFolder2 인터페이스를 요구함으로 인해
shell folder로 접근이 가능하게 한다.
( 대부분의 경우 IShellFolder 인터페이스만 있으면 될 것이다.
왜냐면 여기서 대부분 대단한 작업(cool stuff)이 끝나기 때문이다. )

               IPersistFolder2 *ppf2;
               if (SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2,
                                            (void**)&ppf2))) {
                 LPITEMIDLIST pidlFolder;
                 if (SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) {
                   ...
                   CoTaskMemFree(pidlFolder);
                 }
                 ppf2->Release();
               }

여기서 우리 노력의 결실을 출력하기 위해 pidl을 path로 바꾸자.

                   if (!SHGetPathFromIDList(pidlFolder, g_szPath)) {
                     lstrcpyn(g_szPath, TEXT("<not a directory>"), MAX_PATH);
                   }
                   ...

- 당연한 이야기겠지만 내 컴퓨터나 내 네트워크 환경, 휴지통 같은 가상 폴더는 Path가 없습니다. IShellFolder 인터페이스를 얻었다면 다음과 같이 확인할 수 있습니다.
 
ulAttribs =  SFGAO_FILESYSTEM | SFGAO_FOLDER | SFGAO_HASSUBFOLDER | SFGAO_CONTENTSMASK |
    SFGAO_CANRENAME | SFGAO_CANCOPY | SFGAO_CANMOVE | SFGAO_CANDELETE | SFGAO_LINK |
    SFGAO_SHARE | SFGAO_GHOSTED | SFGAO_REMOVABLE | SFGAO_NONENUMERATED;
/*
이중에서 필요한 속성을 선택하면 됩니다.
IShellFolder::GetAttributesOf 함수의 3번째 인자는 IN OUT 용입니다.
*/
   pShellFolderParent->GetAttributesOf(1, (LPCITEMIDLIST *)&pidlSub, &ulAttribs);
   if ( !(ulAttribs & SFGAO_GHOSTED) )
   {
// 이 폴더는 가상 폴더입니다.
}

우리가 얻은 것을 가지고 다른 어떤것을 또 할 수 있을까...? 아~~ 맞다. 현재 focus된 객체가 무엇인지 알아보자.

                   int iFocus;
                   if (SUCCEEDED(pfv->GetFocusedItem(&iFocus))) {
                     ...
                   }

focus된 항목의 이름을 출력하자. 이를 위해 우리는 그 항목의 pidl과  IShellFolder가 필요하다.
(자, 내가 대단한 물건(cool stuff)가 있는 곳에 IShellFolder가 있다고 말했지.)
우리가 원하는 항목은 Item 매서드를 통해 나온다(놀랄만큼 충분하다).

                     LPITEMIDLIST pidlItem;
                     if (SUCCEEDED(pfv->Item(iFocus, &pidlItem))) {
                       ...
                       CoTaskMemFree(pidlItem);
                     }

( 만약 우리가 선택된 항목들의 리스트릴 원했더라면
  Items 매서드에 VGIO_SELECTION을 넣어 사용할 수 있었다. )

우리가 item의 pidl을 구한 후에도 역시 IShellFolder인터페이스가 필요하다 :

                       IShellFolder *psf;
                       if (SUCCEEDED(ppf2->QueryInterface(IID_IShellFolder,
                                                          (void**)&psf))) {
                         ...
                         psf->Release();
                       }

그런 다음, 항목의 출력용 이름을 얻기 위해 GetDisplayNameOf매서드의 도움으로
이 2가지를 같이 끼워 넣는다.

                         STRRET str;
                         if (SUCCEEDED(psf->GetDisplayNameOf(pidlItem,
                                                   SHGDN_INFOLDER,
                                                   &str))) {
                           ...
                         }

우리는 괴짜 STRRET구조체를 따분한 문자열 버퍼로 변환하기 위해
GetDisplayNameOf() 함수를 사용할 수 있다.
(괴짜 STRRET 구조체의 이야기는 또 다른 날을 기다려야 할 것이다.)

                           StrRetToBuf(&str, pidlItem, g_szItem, MAX_PATH);	

됐군, 이제 이 모든것을 함께 넣어보세.
이 모든것들을 보조 함수로 자르지 않고 커다란 함수 하나에 몽땅 집어 넣으니
오히려 추악해 보이는군...
하지만 "내 인생"에서는 이들이 더 관리가 잘 될 수있도록 작은 보조 함수들로 나눌것이다.

scratch program으로 시작하고 이 새로운 함수를 추가하라:

#include <shlobj.h>
#include <exdisp.h>

TCHAR g_szPath[MAX_PATH];
TCHAR g_szItem[MAX_PATH];

void CALLBACK RecalcText(HWND hwnd, UINT, UINT_PTR, DWORD)
{
 HWND hwndFind = GetForegroundWindow();
 g_szPath[0] = TEXT('\0');
 g_szItem[0] = TEXT('\0');

 IShellWindows *psw;
 if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL,
                                IID_IShellWindows, (void**)&psw))) {
  VARIANT v;
  V_VT(&v) = VT_I4;
  IDispatch  *pdisp;
  BOOL fFound = FALSE;
  for (V_I4(&v) = 0; !fFound && psw->Item(v, &pdisp) == S_OK;
       V_I4(&v)++) {
   IWebBrowserApp *pwba;
   if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) {
     HWND hwndWBA;
     if (SUCCEEDED(pwba->get_HWND((LONG_PTR*)&hwndWBA)) &&
       hwndWBA == hwndFind) {
       fFound = TRUE;
       IServiceProvider *psp;
       if (SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) {
         IShellBrowser *psb;
         if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser,
                              IID_IShellBrowser, (void**)&psb))) {
           IShellView *psv;
           if (SUCCEEDED(psb->QueryActiveShellView(&psv))) {
             IFolderView *pfv;
             if (SUCCEEDED(psv->QueryInterface(IID_IFolderView,
                                               (void**)&pfv))) {
               IPersistFolder2 *ppf2;
               if (SUCCEEDED(pfv->GetFolder(IID_IPersistFolder2,
                                            (void**)&ppf2))) {
                 LPITEMIDLIST pidlFolder;
                 if (SUCCEEDED(ppf2->GetCurFolder(&pidlFolder))) {
                   if (!SHGetPathFromIDList(pidlFolder, g_szPath)) {
                     lstrcpyn(g_szPath, TEXT("<not a directory>"), MAX_PATH);
                   }
                   int iFocus;
                   if (SUCCEEDED(pfv->GetFocusedItem(&iFocus))) {
                     LPITEMIDLIST pidlItem;
                     if (SUCCEEDED(pfv->Item(iFocus, &pidlItem))) {
                       IShellFolder *psf;
                       if (SUCCEEDED(ppf2->QueryInterface(IID_IShellFolder,
                                                          (void**)&psf))) {
                         STRRET str;
                         if (SUCCEEDED(psf->GetDisplayNameOf(pidlItem,
                                                   SHGDN_INFOLDER,
                                                   &str))) {
                           StrRetToBuf(&str, pidlItem, g_szItem, MAX_PATH);
                         }
                         psf->Release();
                       }
                       CoTaskMemFree(pidlItem);
                     }
                   }
                   CoTaskMemFree(pidlFolder);
                 }
                 ppf2->Release();
               }
               pfv->Release();
             }
             psv->Release();
           }
           psb->Release();
         }
         psp->Release();
       }
     }
     pwba->Release();
   }
    pdisp->Release();
  }
  psw->Release();
 }
 InvalidateRect(hwnd, NULL, TRUE);
}

이제 우리가 해야할 일은 이 함수를 주기적으로 호출하고 결과를 출력하는 것이다.

BOOL
OnCreate(HWND hwnd, LPCREATESTRUCT lpcs)
{
    SetTimer(hwnd, 1, 1000, RecalcText);
    return TRUE;
}

void
PaintContent(HWND hwnd, PAINTSTRUCT *pps)
{
  TextOut(pps->hdc, 0, 0, g_szPath, lstrlen(g_szPath));
  TextOut(pps->hdc, 0, 20, g_szItem, lstrlen(g_szItem));
}

이제 굴릴 준비가 되었다. 이 프로그램을 실행하고 옆에다 두어라.
그 다음에 윈도 탐색기를 실행하고 방금 실행한 프로그램을 보고 선택한 항목이 무엇인지
당신이 어떤 폴더에 있는지 추적하여라.

자... 어쨌든 나는 내 목적을 이루었다:)
때론 당신이 원하는 조각들이 이미 거기에 있다
그리고 당신은 단지 어떻게 그것들을 함께 껴 넣을 수 있는지를 알기만 하면 된다.
각각의 그 조각들에 대해 그 자체는 아주 크지 않다는 것을 알아두라.
당신은 단시 얘네들이 흥미가 있는 방향으로 껴넣어질 수 있다는 것을 알아야 한다.

숙제 : 이 프로그램을 수정해서 폴더를 가져와서 detail view로 바꿔보도록 하라.

- IShellView2::GetView Method 를 사용하면 자세히 / 간단히 / 크게 / 작게 / 미리보기의
  뷰를 얻을 수 있습니다. 다른 방법도 있을 것 같은데 당장은 이것만 생각나는군요.



감사합니다.

최대한 원 글쓴이의 어투에 맞도록 했는데 어색한곳은 없는지요.

오타/오역이 있으면 댓글로 남겨주세요.

박명정 (kingsky) 





적당히 주석을 달려고 했는데 정신이 없군요. 시간 되는대로 부가적인 주석을 달아봐야겠습니다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia

basename -- 경로명에서 파일이름만 반환합니다
chgrp -- 파일의 그룹을 변환합니다
chmod -- 파일의 모드 변경
chown -- 파일의 소유자 변경
clearstatcache -- 파일의 통계(stat) 캐시를 삭제합니다.
copy -- 파일을 복사합니다
delete -- 실제로는 없는 명령
dirname -- 경로의 구성요소중에서 디렉토리 이름만 반환합니다.
disk_free_space -- Returns available space in directory
disk_total_space -- Returns the total size of a directory
diskfreespace -- 디렉토리의 사용가능한 공간을 반환합니다.
fclose -- 열려있는 파일 포인터를 닫습니다.
feof -- 파일의 끝이 파일포인터에 있는지 테스트합니다.
fflush -- 출력결과를 파일로 보냅니다.
fgetc -- 파일포인터로부터 문자 가져오기
fgetcsv -- 파일포인터에서 라인을 가져오고 CVS 에 맞게 변환합니다.
fgets -- 파일 포인터에서 라인 가져오기
fgetss -- 파일포인터에서 라인을 가져오고 HTML 태그를 없애기
file_exists -- 파일이 있는지 체크
file_get_contents -- Reads entire file into a string
file_put_contents -- Write a string to a file
file -- 파일전체를 배열로 읽어들임
fileatime -- 최근에 파일에 접근한 시간을 가져옴
filectime -- 파일의 아이노드 변경시간을 가져옵니다
filegroup -- 파일의 그룹을 가져옵니다
fileinode -- 파일의 아이노드를 가져옵니다
filemtime -- 파일이 수정된 시간을 가져옵니다
fileowner -- 파일의 소유자를 가져옵니다
fileperms -- 파일의 권한을 가져옵니다
filesize -- 파일의 크기를 가져옵니다
filetype -- 파일의 형식을 가져옵니다
flock -- 파일 잠김에 관한 간단한 도움말
fnmatch -- Match filename against a pattern
fopen -- 파일이나 URL을 엽니다
fpassthru -- 파일 포인터에 남아있는 모든 데이타를 출력합니다
fputs -- 파일 포인터에 기록하기
fread -- Binary-safe 파일 읽기
fscanf -- 형식에 따라서 파일로 부터 분석하여 입력하기
fseek -- 파일 포인터에서 찾기
fstat -- 오픈 파일 포인터를 사용하는 파일에 대한 정보 가져오기
ftell -- 파일포인터의 읽기/쓰기 위치 말하기
ftruncate -- 주어진 길이로 잘라내기
fwrite -- Binary-safe 파일 쓰기
glob -- Find pathnames matching a pattern
is_dir -- filename 이 디렉토리인지 아닌지 이야기하기
is_executable -- filename이 실행가능한 것인지 아닌지 이야기하기
is_file -- filename이 보통 파일인지 아닌지 이야기하기
is_link -- filename이 심볼릭 링크인지 아닌지 이야기하기
is_readable -- filename이 읽기 가능한 것인지 아닌지 이야기하기
is_uploaded_file -- file이 HTTP POST를 통해 업로드된 것인지 아닌지 이야기하기
is_writable -- filename이 쓰기가능한 것인지 아닌지 이야기하기
is_writeable -- Alias of is_writable()
link -- hard link 만들기
linkinfo -- 링크 정보 가져오기
lstat -- 파일이나 심볼릭 링크에 관한 정보를 제공
mkdir -- 디렉토리 만들기
move_uploaded_file -- 업로드된 파일을 다른곳으로 이동하기
parse_ini_file -- Parse a configuration file
pathinfo -- Returns information about a file path
pclose -- 진행되는 파일 포인터 닫기
popen -- 진행되는 파일 포인터를 열기
readfile -- 파일을 출력합니다
readlink -- symbolic link의 target 반환
realpath -- 표준화된 절대 경로명을 반환합니다
rename -- 파일을 새 이름으로 고치기
rewind -- 파일포인터의 위치를 되돌립니다(rewind).
rmdir -- 디렉토리 제거하기
set_file_buffer -- 주어진 파일 포인터에 파일 버퍼링 설정하기
stat -- file에 대한 정보 제공
symlink -- 심볼릭 링크 만들기
tempnam -- 유일한 파일 이름 만들기
tmpfile -- 임시 파일 만들기
touch -- 파일의 수정시간을 설정합니다
umask -- 현재의 umask를 변경하기
unlink -- 파일을 삭제하기
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia

AddCSlashes -- C 형식으로 문자열에 슬래쉬를 덧붙입니다.
addslashes -- 문자열에 슬래쉬를 덧붙입니다.
bin2hex -- 바이너리 데이터를 16진수 표현으로 바꿉니다.
chop -- rtrim()의 별칭.
chr -- 특정 문자를 반환합니다.
chunk_split -- 문자열을 작은 조각으로 나눕니다.
convert_cyr_string -- 키릴 문자셋을 다른 것으로 변환합니다.
convert_uudecode -- Decode a uuencoded string
convert_uuencode -- Uuencode a string
count_chars -- 문자열 안에 사용한 문자에 대한 정보를 반환합니다.
crc32 -- 문자열의 crc32값을 계산합니다.
crypt -- 단방향 문자열 암호화(해슁).
echo -- 하나 이상의 문자열을 출력합니다.
explode -- 문자열을 주어진 문자열을 기준으로 분리합니다.
fprintf -- 문자열을 형식화하여 스트림에 기록합니다.
get_html_translation_table -- htmlspecialchars()와 htmlentities()에서 사용하는 변환표를 반환합니다.
hebrev -- 논리 헤브라이어 텍스트를 표시 텍스트로 변환합니다.
hebrevc -- 개행 문자를 포함하여 논리 헤브라이어 텍스트를 표시 텍스트로 변환합니다.
html_entity_decode -- 모든 HTML 엔티티를 해당하는 문자로 변환합니다.
htmlentities -- 해당하는 모든 문자를 HTML 엔티티로 변환합니다.
htmlspecialchars -- 특수 문자를 HTML 엔터티로 변환합니다.
implode -- 문자열로 배열 요소를 결합합니다.
join -- implode()의 별칭.
levenshtein -- 두 문자열 사이의 Levenshtein distance를 계산합니다.
localeconv -- 숫자 형식화 정보를 얻습니다.
ltrim -- 문자열 시작 부분의 공백을 제거합니다.
md5_file -- 주어진 파일명의 md5 해쉬를 계산합니다.
md5 -- 문자열의 md5 해쉬를 계산합니다.
metaphone -- 문자열의 메타폰 키를 계산합니다.
money_format -- Formats a number as a currency string
nl_langinfo -- 언어와 로케일 정보를 얻습니다.
nl2br -- 문자열의 모든 줄바꿈 앞에 HTML 줄바꿈 태그를 삽입합니다.
number_format -- Format a number with grouped thousands
ord -- 문자의 아스키 값을 반환합니다.
parse_str -- 문자열을 처리하여 변수를 생성합니다.
print -- 문자열을 출력합니다.
printf -- 형식화한 문자열을 출력합니다.
quoted_printable_decode -- 인용되어 있는 출력 가능 문자열을 8비트 문자열로 변환합니다.
quotemeta -- 메타 문자를 인용합니다.
rtrim -- 문자열 끝 부분의 공백을 제거합니다.
setlocale -- 지역적보를 지정한다.
sha1_file -- 파일의 sha1 해쉬를 계산합니다.
sha1 -- 문자열의 sha1 해쉬를 계산합니다.
similar_text -- 두 문자열 간의 유사성을 계산합니다.
soundex -- 문자열의 soundex 키를 계산합니다.
sprintf -- 형식화한 문자열을 반환합니다.
sscanf -- 문자열을 형식에 따라 처리합니다.
str_ireplace -- 대소문자를 구별하지 않는 str_replace().
str_pad -- 문자열을 어떠한 길이가 되도록 다른 문자열로 채웁니다.
str_repeat -- 문자열을 반복합니다.
str_replace -- 발견한 모든 검색 문자열을 치환 문자열로 교체합니다.
str_rot13 -- 문자열에 rot13 변환을 수행합니다.
str_shuffle -- 문자열을 랜덤하게 섞습니다.
str_split -- 문자열을 배열로 변환합니다.
str_word_count -- 문자열에서 사용한 단어에 대한 정보를 반환합니다.
strcasecmp -- 대소문자를 구별하지 않는 바이너리 호환 문자열 비교
strchr -- strstr()의 별칭.
strcmp -- 바이너리 호환 문자열 비교
strcoll -- 로케일 기반 문자열 비교
strcspn -- 마스크에 매칭하지 않는 처음 세그먼트의 길이를 찾습니다.
strip_tags -- 문자열에서 HTML과 PHP 태그를 제거합니다.
stripcslashes -- addcslashes()로 처리한 문자열을 되돌립니다.
stripos -- 대소문자를 구별하지 않고 문자열이 처음 나타나는 위치를 찾습니다.
stripslashes -- addslashes()로 처리한 문자열을 되돌립니다.
stristr -- 대소문자를 구별하지 않는 strstr()
strlen -- 문자열의 길이를 구합니다.
strnatcasecmp -- "natural order" 알고리즘을 이용한 대소문자를 구별하지 않는 문자열 비교.
strnatcmp -- "natural order" 알고리즘을 이용한 문자열 비교
strncasecmp -- 대소문자를 구별하지 않는 처음 n 문자의 이진 호환 문자열 비교
strncmp -- 처음 n 문자의 이진 호환 문자열 비교
strpbrk -- Search a string for any of a set of characters
strpos -- 문자열이 처음 나타나는 위치를 찾습니다.
strrchr -- 문자열에서 문자가 마지막으로 나오는 부분을 찾습니다.
strrev -- 문자열을 뒤집습니다.
strripos -- 문자열에서 대소문자 구별 없이 문자열이 나타나는 마지막 위치를 찾습니다.
strrpos -- 문자열에서 마지막 문자의 위치를 찾습니다.
strspn -- 마스크에 매칭되는 초기 세그먼트의 길이를 찾는다.
strstr -- 문자열이 처음으로 나타나는 부분을 찾습니다.
strtok -- 문자열을 토큰화 합니다.
strtolower -- 문자열을 소문자로 만듭니다.
strtoupper -- 문자열을 대문자로 만듭니다.
strtr -- 특정 문자를 번역한다.
substr_compare -- Binary safe optionally case insensitive comparison of 2 strings from an offset, up to length characters
substr_count -- 부분문자열의 수를 센다
substr_replace -- 문자열의 일부를 치환한다.
substr -- 문자열의 일부를 반환한다.
trim -- 문자열의 처음과 끝에 있는 공백을 제거한다.
ucfirst -- 문자열의 처음 글자를 대문자로 만든다.
ucwords -- 문자열에 있는 각 단어의 처음 글자를 대문자로 바꾼다.
vprintf -- Output a formatted string
vsprintf -- Return a formatted string
wordwrap -- 정지문자를 이용해 주어진 수 만큼의 문자를 래핑한다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia
http://www.hsc.fr/ressources/articles/win_net_srv/index.html
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia


CreateFile의 옵션에 따라서 파일 관련 함수들은 성공할 수도, 실패할 수도 있습니다.
아래의 구문은 SetFilePointerEx의 정상적인 사용입니다.

//-------------------------------------------------------------------------
 HANDLE hFile = NULL;

 hFile = CreateFile( FilePath , GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_NEW,
        NULL,
        NULL
        );

  if (hFile == INVALID_HANDLE_VALUE)
        TRACE( "Fail to CreateFile\n" );

  LARGE_INTEGER FileSize;
  FileSize.QuadPart = 1024 * 24;     // 24 Kb

  if( !SetFilePointerEx(hFile, FileSize, 0, FILE_BEGIN) )
      TRACE( "Fail to Set FP\n" );
  
  CloseHandle( hFile );

//-------------------------------------------------------------------------

하지만 특정한 경우, 아래의 구문은 정상적으로 수행되지 않을 수 있죠.

//-------------------------------------------------------------------------
 hFile = CreateFile( FilePath , GENERIC_READ | GENERIC_WRITE,
        FILE_SHARE_READ | FILE_SHARE_WRITE,
        NULL,
        CREATE_NEW,
        FILE_FLAG_NO_BUFFERING,
        NULL
        );

  if (hFile == INVALID_HANDLE_VALUE)
        TRACE( "Fail to CreateFile\n" );

  FileSize.QuadPart = 107;     // 107 byte

  if( !SetFilePointerEx(hFile, FileSize, 0, FILE_BEGIN) )
      TRACE( "Fail to Set FP\n" );
//-------------------------------------------------------------------------

GetLastError 로 원인을 살펴보면 87 ERROR_INVALID_PARAMETER 로
잘못된 인자를 사용했다는 메시지를 얻을 수 있습니다.
...뭐시기?! SetFilePointerEx 부분은 복사해 붙였단 말이다!


..냉정을 되찾고 M$DN의 CreateFile 설명을 살펴보면
FILE_FLAG_NO_BUFFERING 옵션에 관한 부분을 찾을 수 있군요.
아래의 설명을 주목해봅시다.

An application must meet certain requirements when working with files that are opened with FILE_FLAG_NO_BUFFERING:

  • File access must begin at byte offsets within a file that are integer multiples of the volume sector size.
  • File access must be for numbers of bytes that are integer multiples of the volume sector size. For example, if the sector size is 512 bytes, an application can request reads and writes of 512, 1024, or 2048 bytes, but not of 335, 981, or 7171 bytes.
  • Buffer addresses for read and write operations should be sector aligned, which means aligned on addresses in memory that are integer multiples of the volume sector size. Depending on the disk, this requirement may not be enforced.

이 옵션을 사용했을 경우 파일에 접근할 때 반드시
해당 파일이 위치한 볼륨의 섹터 크기 단위로 읽어와야 한다는 것입니다.

디스크 섹터 크기가 107 Byte 라는 변태적인 크기일 확률은 0.0001%도 안될 것이기에
두 번째 예시는 거의 반드시 실패한다고 볼 수 있겠군요.

역시 저수준으로 접근이 가능할수록, 개발자가 신경써야 하는 점은 늘어나나봅니다.
전 CFile이 좋아요 [..]

Viva Developer Life! s( =_=)v-~@

크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia

이 녀석은 Sparse File 을 만들때 사용되는 인자입니다.

Sparse File 은 NTFS5(Windows 2K)에 추가된 기능으로
일반 파일에서 사용하는 공간보다 훨씬 적은 디스크 공간을 사용하여 처리되는 파일입니다.
Sparse  지원을 사용하면 0 이 아닌 영역만 디스크 공간을 할당하고
나머지 0인 영역은 할당하지 않음으로써, 디스크 공간을 사용하지 않고도
대용량의 파일을 작성할 수 있습니다.

일례로 윈도우가 설치된 폴더의 속성을 보면 폴더의 원래 크기보다
디스크 할당 크기가 200M 정도 적게 잡혀있는 것을 볼 수 있죠

Sparse File 을 FAT 계열 또는 NTFS5 이외의 볼륨으로 복사/이동하면
원래 크기로 생성되므로, 공간이 충분치 않을 경우 실패합니다.
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia
2009 년 가을 발매 예정.
질러라~ 질러라~

http://dory.mncast.com/mncHMovie.swf?movieID=10052408220080402113116&skinNum=1
 
크리에이티브 커먼즈 라이선스
Creative Commons License
Posted by Xenosia

BLOG main image
Find the way you shall within yourself! by Xenosia

공지사항

카테고리

분류 전체보기 (42)
일상 (16)
RPG (8)
건담 (1)
Programming (15)
게임 (2)

최근에 받은 트랙백

글 보관함

달력

«   2009/07   »
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  
Total : 8,388
Today : 0 Yesterday : 5