bookmark_borderMFC 파일선택 대화상자

한개의 파일만 선택할 경우



char szFilter[] = “Image (*.BMP, *.GIF, *.JPG) | *.BMP;*.GIF;*.JPG | All Files(*.*)|*.*||”;


CFileDialog dlg(TRUE, NULL, NULL, OFN_HIDEREADONLY, szFilter);


if(IDOK == dlg.DoModal()) {


        CString strPathName = dlg.GetPathName();


}


 


 


여러개의 파일을 복수 선택할 경우


 


dwFlagOFN_ALLOWMULTISELECT 설정한다.


        선택된 여러 파일 리스트가 저장될 버퍼가 제공되야 한다.


        만일 기본 버퍼 이상의 파일을 선택해 확인 버튼을 누른다면,


        DoModal을 실행시켰을 때, IDCANCEL이 리턴되고, 파일 리스트가 넘어오지 않을 것이다.


 


char szFilter[] = “All Files(*.*) | *.* ||”;
CFileDialog dlg(TRUE, NULL, NULL, OFN_ALLOWMULTISELECT, szFiilter);


dlg.m_ofn.lpstrInitialDir = _T(“D:/”); // 오픈할때 초기 경로 지정
// 여기서 버퍼 크기 늘려줘야 함.


char    strFile[4096] = { 0, };               CString fileName;
dlg.m_ofn.lpstrFile = strFile;                 dlg.m_ofn.lpstrFile = fileName.GetBuffer( 4096 );
dlg.m_ofn.nMaxFile = sizeof(strFile);      dlg.m_ofn.nMaxFile = 4096


if (IDOK == dlg.DoModal()) {
   for (POSITION pos=dlg.GetStartPosition(); pos != NULL;)
       CString
strPathName =
dlg.GetNextPathName(pos);
}

파일 선택 필터

static TCHAR BASED_CODE szFilter[] = 
_T(“Chart Files (*.xlc)|*.xlc|”) _T(“Worksheet Files (*.xls)|*.xls|Data Files (*.xlc;*.xls)|”)
_T(“*.xlc; *.xls|All Files (*.*)|*.*||”);


예제

void CMyClass::OnFileOpen() 
{
// szFilters is a text string that includes two file name filters:
// “*.my” for “MyType Files” and “*.*’ for “All Files.”
TCHAR szFilters[]= _T(“MyType Files (*.my)|*.my|All Files (*.*)|*.*||”);

// Create an Open dialog; the default file name extension is “.my”.
CFileDialog fileDlg(TRUE, _T(“my”), _T(“*.my”),
OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, szFilters);

// Display the file dialog. When user clicks OK,

fileDlg.DoModal()

// returns IDOK.
if (fileDlg.DoModal() == IDOK)
{
CString pathName = fileDlg.GetPathName();

// Implement opening and reading file in here.
// Change the window’s title to the opened file’s title.

CString fileName = fileDlg.GetFileTitle();
SetWindowText(fileName);
}
}

============================================================================



CFileDialog dlgFile(TRUE);


CString fileName;
const int c_cMaxFiles = 100;
const int c_cbBuffSize = (c_cMaxFiles * (MAX_PATH + 1)) + 1;


dlgFile.GetOFN().lpstrFile = fileName.GetBuffer(c_cbBuffSize);
dlgFile.GetOFN().nMaxFile = c_cMaxFiles;



dlgFile.DoModal();


fileName.ReleaseBuffer();

============================================================================

CFileDialog::CFileDialog




explicit CFileDialog( BOOL bOpenFileDialog,
LPCTSTR lpszDefExt = NULL,
LPCTSTR lpszFileName = NULL,
DWORD dwFlags = OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,
LPCTSTR lpszFilter = NULL,
CWnd* pParentWnd = NULL,
DWORD dwSize = 0,
BOOL bVistaStyle = TRUE );


BOOL bOpenFileDialog
       생성하는 다이얼로그 박스 타입을 지정해 주는 매개변수
       TRUE => 파일열기 다이얼로그 박스
       FALSE => 파일 저장 다이얼로그 박스

LPCTSTR lpszDefExt
      기본 파일 확장자명(저장할 경우 사용)
       만약 유저가 파일이름 상자 안에 확장자를 포함하지 않는 경우
       lpszDefExt의 파일 확장자명을 자동으로 지정 함
       NULL => 확장자명을 추가하지 않음

lpszFileName
       시작할 때 파일이름 상자에 나타낼 이름 지정
        NULL => 시작할 때 파일이름을 나타내지 않음



dwFlags
       하나이상의 플래그를 사용하여 사용자가 원하는 다이얼로그 박스로 조합

        많이 사용되는 플래그
        OFN_ALLOWMULTISELECT        한번에 여러개의 파일들을 선택 가능하게 함
        OFN_CREATEPROMPT              존재하지 않는 파일명을 입력했을 경우 새로 생성하겠냐는 대화상자 표시
        OFN_EXPLOPER                       열기나 저장하기를 윈도우 탐색기 스타일로 출력
        OFN_FILEMUSTEXIST               기존에 존재하는 파일 이름만 입력할 수 있도록 함
        OFN_HIDEREADONLY                읽기전용 파일은 출력하지 않음
        OFN_LONGNAMES                   긴 파일 이름을 사용할 수 있도록 함
        OFN_OVERWRITEPROMPT        저장할려고 하는 파일명이 존재할 경우 덮어쓰겠냐는 대화 상자 표시
        OFN_PATHMUSTEXIST             오직 유효한 경로나 파일명만을 입력(아님 경고 메세지 출력)

        추가 플래그 참조 :
http://msdn.microsoft.com/ko-kr/library/ms646839(en-us,VS.85).aspx


lpszFilter
    사용할 파일들이 걸러지도록 파일명들을 연속으로 나열 함

pParentWnd
    부모나 소유자 윈도우의 파일 다이얼로그 박스의 포인터

dwSize
    OPENFILENAME 구조체의 크기

bookmark_border윈도우 OS가 몇 비트 인지 알아오는 방법

윈도우 OS가 몇 비트 인지 알아오는 방법에는 2가지가 있습니다.



1. GetSystemInfo, GetNativeSystemInfo 함수 사용.


2. IsWow64Process 함수 사용.



GetSystemInfo 부터 알아 보겠습니다.



GetSystemInfo는 시스템 정보를 얻어오는 함수 입니다.



이렇게 정의 되어 있습니다.



WINBASEAPI VOID WINAPI GetSystemInfo( __out LPSYSTEM_INFO lpSystemInfo ) ;



얻어오는 인자 값으론 SYSTEM_INFO 라는 구조체를 사용 합니다.


typedef struct _SYSTEM_INFO {
    union {
        DWORD dwOemId;          // Obsolete field…do not use
        struct {
            WORD wProcessorArchitecture;
            WORD wReserved;
        };
    };
    DWORD dwPageSize;
    LPVOID lpMinimumApplicationAddress;
    LPVOID lpMaximumApplicationAddress;
    DWORD_PTR dwActiveProcessorMask;
    DWORD dwNumberOfProcessors;
    DWORD dwProcessorType;
    DWORD dwAllocationGranularity;
    WORD wProcessorLevel;
    WORD wProcessorRevision;
} SYSTEM_INFO, *LPSYSTEM_INFO;



OS의 비트를 알아올 때에는 CPU의 아키텍쳐를 이용해서 검사를 하게 됩니다.



왜 OS의 비트를 알아올 때 CPU를 검사 하느냐 하면 32비트의 CPU에서는 64비트의 OS가 깔리지 않습니다.



그러므로 32비트의 CPU를 사용하게 되면 무조건 32비트의 OS가 깔리겠죠?



64비트의 CPU를 사용하게 되면 32비트/64비트의 OS 모두 깔리게 됩니다. 그런데 깔리는 OS에 따라서 CPU의 정보도 바뀌게 됩니다. 32비트 OS면 CPU정보도 32비트, 64비트 OS면 CPU정보도 64비트.



그래서 CPU의 정보 만으로 사용하는 OS가 몇 비트 인지 알아 올 수 있게 됩니다.



다시 돌아가서~



위의 구조체를 보시면 wProcessorArchitecture라는 변수가 있습니다.



MSDN을 보시면 이렇게 정의 되어 있습니다.



wProcessorArchitecture
   The processor architecture of the installed operating system. This member can be one of the following values.

















Value Meaning

PROCESSOR_ARCHITECTURE_AMD64
                           9



       x64 (AMD or Intel)


PROCESSOR_ARCHITECTURE_IA64
                           6



Intel Itanium Processor Family (IPF)


PROCESSOR_ARCHITECTURE_INTEL
                           0




     x86


PROCESSOR_ARCHITECTURE_UNKNOWN
                        0xffff



     Unknown architecture.


 

PROCESSOR_ARCHITECTURE_AMD64 일때 64비트.


PROCESSOR_ARCHITECTURE_INTEL 일때 32비트.



왜 AMD64일때 AMD 아니면 Intel 이냐고 물어보신 다면.. 그건 저도 모릅니다.



테스트 해보니 Intel CPU든, AMD CPU든 64비트 CPU를 가지고 있으면 AMD64, 32비트 CPU를 가지고 있으면 INTEL로 넘어 오는 것을 확인 했습니다.



그러므로 CPU가 AMD인지 Intel 인지 확인 하시려고 저 것을 사용하면 안된다는 말입니다.


자 저것을 이용하면 32비트인지 64비트 인지 알아 올 수 있게 되죠.



근데 문제는 GetSystemInfo 라는 함수에 문제점이 있습니다. 64비트의 OS를 사용하더라도 현재 수행되고 있는 프로세스가 32비트로 만들어진 것이라면(64비트로 만들어진 것이면 상관없을 것입니다.) 자신이 32비트 환경에 있는 것으로 착각을 하게 되어 32비트로 인식을 해버리게 됩니다.



그래서 Windows XP 이상에서 지원되게 나온 것이 GetNativeSystemInfo 라는 함수 입니다.



그것은 32비트로 만들어진 프로세스도 32비트 환경인지 64비트 환경인지 정확하게 알아 냅니다.



물론 Windows XP 이하에선 당연히 안되죠.



GetNativeSystemInfo를 사용하기 위해선 kenel32.dll에서 함수를 가져와서 사용해야 합니다.



코드 )



//GetNativeSystemInfo 함수를 얻어오기 위한 함수 포인터.


typedef void ( WINAPI *PFN_GET_NATIVE_SYSTEM_INFO )( LPSYSTEM_INFO ) ;



//시스템 정보를 가져올 구조체.


SYSTEM_INFO SystemInfo ;



//GetNativeSystemInfo 함수를 얻어오기 위함.
 PFN_GET_NATIVE_SYSTEM_INFO pGetNativeSystemInfo ;



//kernel32.dll에서 GetNativeSystemInfo 함수를 가져옴.
 //윈도우 XP이상에서만 GetNativeSystemInfo를 지원하기 때문에
 //하위 윈도우에서는 NULL이 옴.

 pGetNativeSystemInfo = ( PFN_GET_NATIVE_SYSTEM_INFO )GetProcAddress( GetModuleHandle( TEXT( “kernel32.dll” ) ), “GetNativeSystemInfo” ) ;



//함수를 얻어 왔다면 GetNativeSystemInfo를 이용해서 SystemInfo를 얻어옴.
 if( pGetNativeSystemInfo )
 {
  pGetNativeSystemInfo( &SystemInfo ) ;
 }
 //얻어오지 못했다면 기본적으로 제공되는 GetSystemInfo를 이용.
 else
 {
  GetSystemInfo( &SystemInfo )  ;
 }



위의 방식대로 하게 되면 SystemInfo를 가져올 수 있습니다. SystemInfo.wProcessorArchitecture를 가지고 PROCESSOR_ARCHITECTURE_AMD64 인지, PROCESSOR_ARCHITECTURE_INTEL 인지만 판단해서 32비트 64비트를 판명하면 되게 됩니다.




두번째, IsWow64Process를 이용하는 방법입니다.



Wow라고 하셔서 World of Warcraft 라고 -_- 생각하기면 곤란하고 Window on Window 입니다.



자세한건 검색해 보세요. ^^ ( 64비트 윈도우안에 32비트를 돌아가게 윈도우 가 있다고 해서 wow라고 합니다. )



이방법 역시 간단합니다. kenel32.dll에서 isWow64Process 함수를 가져와서 사용하면 됩니다.



코드 )


//IsWow64PRocess 함수를 얻어오기 위한 함수 포인터.
typedef BOOL ( WINAPI *PFN_ISWOW64PROCESS )( HANDLE, PBOOL )   ;



//시스템 정보를 가져올 구조체.


SYSTEM_INFO SystemInfo ;


 //ISWow64Process 함수를 얻어오기 위함.
 PFN_ISWOW64PROCESS   pIsWow64Process   ;



BOOL Is64Process = FALSE ;



 //이것 역시 XP이상에서만 지원할 것임. ( 테스트는 안해봤음. )
 pIsWow64Process = ( PFN_ISWOW64PROCESS )GetProcAddress( GetModuleHandle( TEXT( “kernel32.dll” ) ), “IsWow64Process” ) ;



//NULL이 아니면 IsWow64Process 함수를 이용해서 OS가 몇 비트인지 얻어옴.
 if( pIsWow64Process )
 {
     pIsWow64Process( GetCurrentProcess(), &Is64Process ) ;
 }
 else
 {
     Is64Process = FALSE ;
 }



위와 같은 방법으로 하면 현재 64비트 환경인지 32비트 환경인지 알 수 있습니다.

bookmark_borderListCtrl

==========================================


1. 특정 ROW 포커스 주기
2. 특정 ROW로 가기
3. 헤더 컬럼수 얻어오기
4. 컬럼의 너비를 이쁘게 주기
5. 한줄 쭉 선택되게 하기, 그리드 라인 주기
6. 선택한 아이템(ROW)를 지우기
7. 두 아이템을 스왑 하기
8. 기존에 선택되어있는 것을 해체하기


9. List Control의 0번째 컬럼 사이즈 변경하지 못 하도록 프로그래밍


10. List Control 에 다른 Control 넣기


11. List Control 행크기 늘리기


12. List Control 에서 시스템 아이콘 사용하기


 


1. 특정 ROW 포커스 주기
—————————————————
리스트 컨트롤에서 어떤 특정 Row를 선택하게 하고 싶을때
( 이때 선택뿐아니라 포커스도 가야 한다.
포커스가 간다는 의미는 다음에 키다운을 하면 바로 부드럽게
다음 아이템을 가리키도록 하는 것이다 )


ListView_SetItemState (pListCtrl->GetSafeHwnd(), // handle to listview
10, // index to listview item
LVIS_FOCUSED | LVIS_SELECTED, // item state
0x000F); //mask


위와 같이 코딩하면 된다.



2. 특정 ROW로 가기
—————————————————
만일 원하는 Row를 스크롤을 하던 어떻게 하든 화면에 보이게
하고 싶을때


pListCtrl->EnsureVisible(15, TRUE);


이렇게 하면 된다.



3. 헤더 컬럼수 얻어오기
—————————————————
헤더 컬럼의 갯수를 알고 싶을때
CHeaderCtrl* pHeader = (CHeaderCtrl*)GetDlgItem(0);
int nColumnCount = pHeader->GetItemCount();


또는 pList->GetHeaderCtrl()을 통해서 얻어올수 도 있다.



4. 컬럼의 너비를 이쁘게 주기
—————————————————
공백없이 잘 채워 준다.


부모 다이얼로그의 OnSize에서
void CAttrListDlg::OnSize(UINT nType, int cx, int cy)
{
CDialog::OnSize(nType, cx, cy);


// TODO: Add your message handler code here
if( IsWindow( z_AttrList.m_hWnd ))
{
z_AttrList.MoveWindow( 0, 0, cx, cy );
z_AttrList.SetColumnWidth(1 , LVSCW_AUTOSIZE_USEHEADER);
}
}



5. 한줄 쭉 선택되게 하기, 그리드 라인 주기
—————————————————
z_AttrList.SetExtendedStyle(LVS_EX_GRIDLINES | LVS_EX_FULLROWSELECT);



6. 선택한 아이템(ROW)를 지우기
—————————————————


CDWordArray m_anDragIndexes; // 선택한 아이템을 기억하는
배열


int CAttrList::fnRemoveItem()
{


m_anDragIndexes.RemoveAll();
POSITION pos = GetFirstSelectedItemPosition();
while (pos)
{
m_anDragIndexes.Add(GetNextSelectedItem(pos));
}


int nSize = m_anDragIndexes.GetSize();
int nRet = -1;
if( nSize )
nRet = m_anDragIndexes[0];


while( nSize– )
DeleteItem( m_anDragIndexes[nSize] );


m_anDragIndexes.RemoveAll();
return nRet;
}



7. 두 아이템을 스왑 하기
—————————————————
void CAttrList::fnSwapItem( int nItem1, int nItem2 )
{
int hi = nItem2;
int lo = nItem1;
CStringArray rowText;


LV_ITEM lvitemlo, lvitemhi;
CHeaderCtrl* pHeaderCtrl = GetHeaderCtrl();
int nColCount =pHeaderCtrl->GetItemCount();


rowText.SetSize( nColCount );
int i;
for( i=0; i<nColCount; i++)
rowText[i] = GetItemText(lo, i);
lvitemlo.mask = LVIF_IMAGE | LVIF_PARAM | LVIF_STATE;
lvitemlo.iItem = lo;
lvitemlo.iSubItem = 0;
lvitemlo.stateMask = LVIS_CUT | LVIS_DROPHILITED |
LVIS_FOCUSED | LVIS_SELECTED |
LVIS_OVERLAYMASK | LVIS_STATEIMAGEMASK;


lvitemhi = lvitemlo;
lvitemhi.iItem = hi;


GetItem( &lvitemlo );
GetItem( &lvitemhi );


for( i=0; i<nColCount; i++)
SetItemText(lo, i, GetItemText(hi, i));


lvitemhi.iItem = lo;
SetItem( &lvitemhi );


for( i=0; i<nColCount; i++)
SetItemText(hi, i, rowText[i]);


lvitemlo.iItem = hi;
SetItem( &lvitemlo );
}


 


8.기존에 선택되어있는 것을 해체하기
———————————–
int nOldItem = GetSelectionMark();
if( nOldItem > 0 )
SetItemState( nOldItem , 0, LVIS_SELECTED);



void SetCurSel(int nIndex, BOOL bIsTrue)
{
 SetItemState(nIndex, bIsTrue ? LVIS_SELECTED | LVIS_FOCUSED : 0, LVIS_SELECTED | LVIS_FOCUSED);
}


9. List Control의 0번째 컬럼 사이즈 변경하지 못 하도록 프로그래밍


———————————————————————-
BOOL OnNotify(WPARAM wParam, LPARAM lParam, LRESULT* pResult)
{


/* 


    //사이즈가 80 이하 안되게 만든다.


    HD_NOTIFY   *pHDN = (HD_NOTIFY*)lParam;


 


    if((pHDN->hdr.code == HDN_ITEMCHANGINGW || pHDN->hdr.code == HDN_ITEMCHANGINGA)


        && pHDN->pitem->cxy < 80)


    {


        *pResult = TRUE;                // disable change


        return TRUE;                    // Processed message


    }*/


 


 


/*  // 컬럼 사이즈 변경 못하게 만든다.


    // 모든 칼럼.


    switch (((NMHDR*)lParam)->code)


    {


        case HDN_BEGINTRACKW:


        case HDN_BEGINTRACKA:


            *pResult = TRUE;                // disable tracking


            return TRUE;                    // Processed message


        default: break;


    }


 


    // 특정 칼럼.


    HD_NOTIFY   *pHDN = (HD_NOTIFY*)lParam;


 


    if((pHDN->hdr.code == HDN_BEGINTRACKW || pHDN->hdr.code == HDN_BEGINTRACKA)


            && pHDN->iItem == 0)            // Prevent only first (col# 0) from resizing


    {


        *pResult = TRUE;                // disable tracking


        return TRUE;                    // Processed message


    }*/


 


    return CListCtrl::OnNotify(wParam, lParam, pResult);


}



 


10. List Control 에 다른 Control 넣기


 ———————————————————————-
1. 요약
 특정 Column에서 다른 Control 을 띄우는 방법 설명. 여기서 사용한 방법은 현재 Cursor가 있는 위치를 파악한후 그 위치에 적당한 크기의 Edit Control를 생성 시킨다.

2. 본문
1) CListCtrl를 상속받는 CMyList라는 Class를 만든다.
2) Member변수로 CEdit m_ctrEdit를 선언한다.
3) Member함수로 OnLButtonDown()과 GetSubItemFrompt(point, nItem, nSubItem, rcClient)를 선언 OnLButtonDown() : Edit Control를 생성/삭제 시키는 역할 GetSubItemFrompt(): 현재 Cursor가 있는 곳의 List정보를 가져온다.
4) 함수 내용을 구성한 후(예제 참조) 사용은 CListCtrl m_ctrList에서 CListCtrl —> CMyList로 바꿔 주면 된다. 3.예제
실제로 클래스를 구성하면 다음과 같다.

class CMyList : public COXGridList

{

// Construction

public:

CMyList();



// Attributes

public:

CEdit m_ctrEdit;



// Operations

public:

void GetSubItemFrompt(Cpoint point, int &nItem,int&nSubItem,CRect&rect);



//Overrides

//ClassWizardgeneratedvirtualfunctionoverrides

//{{AFX_VIRTUAL(CMyList)

//}}AFX_VIRTUAL



//Implementation

public:

virtual~CMyList();



//Generatedmessagemapfunctions

protected:

//{{AFX_MSG(CMyList)

afx_msg
voidOnLButtonDown(UINTnFlags,Cpointpoint);

//}}AFX_MSG



DECLARE_MESSAGE_MAp()

};





CMyList::CMyList()

{

}



CMyList::~CMyList()

{

}





BEGIN_MESSAGE_MAp(CMyList,COXGridList)

//{{AFX_MSG_MAp(CMyList)

ON_WM_LBUTTONDOWN()

//}}AFX_MSG_MAp

END_MESSAGE_MAp()

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

//CMyListmessagehandlers

voidCMyList::OnLButtonDown(UINTnFlags,Cpointpoint)

{

intnItem,nSubItem;

CRectrcClient;



//현재 point의 영역 정보를 가져온다.

GetSubItemFrompt(point, nItem, nSubItem, rcClient);



// 두번째 SubItem일(두번째 Column) 경우에만 나타나게 함.

if (nSubItem == 1)

{

if (m_ctrTimeEdit.m_hWnd == NULL)

{

// Mask Edit Control 생성

m_ctrEdit.Create

(WS_CHILD|WS_VISIBLE|WS_TABSTOp|WS_BORDER|WS_HSCROLL,

CRect(
0, 0, 30, 10), this, 1);



m_ctrEdit.MoveWindow(rcClient);

m_ctrEdit.ShowWindow(SW_SHOW);



}

else

{

m_ctrTimeEdit.MoveWindow(rcClient);

m_ctrTimeEdit.ShowWindow(SW_SHOW);

}

}

else

{

if (m_ctrTimeEdit.m_hWnd != NULL)

{

m_ctrTimeEdit.ShowWindow(SW_HIDE);

}

}



CListCtrl::OnLButtonDown(nFlags, point);

}

void CMyList::GetSubItemFrompt(Cpoint point, int &nItem, int &nSubItem, CRect &rect)

{

LVHITTESTINFO lvhti;



// Clear the subitem text the user clicked on.

lvhti.pt = point;

SubItemHitTest(&lvhti);



nItem = lvhti.iItem;

nSubItem = lvhti.iSubItem;

GetSubItemRect(nItem, nSubItem, LVIR_LABEL, rect);

}

4. 참고 마우스를 더블 클릭하는 순간에 나타나게 하고 싶다면 마우스 더블 클릭 함수에서 구현해 주면 된다. 몇가지 함수만 추가하면 특정 Column에서만 Control이 나타나게 하는 것을 쉽게 구현 할 수 있을 것이다. – 2001.08.06 Smile Seo –




11. List Control 행크기 늘리기


 ———————————————————————-
리스트 콘트롤의 행간 높이를 조절하고자 할때,
원래 윈도우가 날려주는 메세지가 있지만, CListCtrlView 를 이용하는경우 도움이 전혀 안됩니다.
이경우 마지막 방법은 이미지 리스트를 이용하는 것입니다.


CImageList m_image;


….
CListCtrl &m_list=GetListCtrl();
    m_image.Create(1,20,ILC_COLORDDB,1,0);
    list.SetImageList(&m_image,LVSIL_SMALL);
…….


을 써서 Y 크기를 조절해서 크기를 바꿀 수 있습니다.


12. List Control 에서 시스템 아이콘 사용하기


 ———————————————————————-
CImageList m_ImgList;


HIMAGELIST  hSystemSmallImageList;
SHFILEINFO  ssfi;


hSystemSmallImageList =
(HIMAGELIST)SHGetFileInfo((LPCTSTR)_T(“C:\\”), 0, &ssfi, sizeof(SHFILEINFO),
        SHGFI_SYSICONINDEX | SHGFI_SMALLICON);


m_ImgList.Attach(hSystemSmallImageList);
m_listDir.SetImageList(&m_ImgList, LVSIL_SMALL);


// 이부분을 넣지 않으면 여러번 리스트컨트롤이 나타날때 이미지가 사라진다.
HWND hList = m_listDir.GetSafeHwnd();
DWORD dwCurrentStyle=GetWindowLong(hList, GWL_STYLE);
dwCurrentStyle |= LVS_SHAREIMAGELISTS;
SetWindowLong(hList, GWL_STYLE, dwCurrentStyle);



// 나중에 InsertItem으로 아이템 추가시 이미지 번호에 아래 함수를 호출하여 얻은 리턴값을 사용한다.
int CSystemListCtrl::GetIconIndex(const CString& csFileName)  //full path and file name
{              
 SHFILEINFO    sfi;
 
 SHGetFileInfo(
   (LPCTSTR)csFileName,
   0,
   &sfi,
   sizeof(SHFILEINFO),
   SHGFI_SYSICONINDEX | SHGFI_SMALLICON );
 
 return sfi.iIcon;
}

bookmark_borderCListCtrl 정리


  • 1. 컬럼을 추가한다.

  • 2. Item을 추가한다.

  • 3. SubItem을 추가한다.


컬럼을 추가해야, 컬럼에 텍스트를 설정해 넣을 수가 있다. 컬럼 추가는 다음과 같이 한다.

CListCtrl l;
l.InsertColumn(0, “Control…”, LVCFMT_LEFT, 100);
l.InsertColumn(1, “HI…”, LVCFMT_LEFT, 100);


Item을 추가해야, sub item을 추가할 수 있게 된다. Item은 0번부터 시작을 하고, sub item은 1번부터 시작을 한다. 우선 Item은 다음과 같이 추가한다.

l.InsertItem(0, “first”);
l.InsertItem(1, “second”);


subitem은, item의 index를 zero-based로 적고, subitem의 index는 1-based로 한다. 즉, item이 subitem의 index가 0번이라고 가정한다.

l.SetItemText(0,1,”child of first”);


이상을 정리하면 다음과 같다.

+———————+———————+———————-+
| InsertColumn(0, ) | InsertColumn(1, ) | InsertColumn(2, ) |
+———————+———————+———————-+
| InsertItem(0, ) | SetItemText(0,1, ) | SetItemText(0, 2, ) |
+———————+———————+———————-+
| InsertItem(1, ) | SetItemText(1,1, ) | SetItemText(1, 2, ) |
+———————+———————+———————-+
| InsertItem(2, ) | SetItemText(2,1, ) | SetItemText(2, 2, ) |
+———————+———————+———————-+
| InsertItem(3, ) | SetItemText(3,1, ) | SetItemText(3, 2, ) |
+———————+———————+———————-+