Win32 API with 나우캠퍼스

Win32 API 10강. 컨트롤3 리스트 컨트롤

코다람쥐 2022. 8. 19. 15:36

목차


1. 리스트 컨트롤

2. 컬럼 다루기

2. 정리

 

1. List Control

개요


▩ 리스트 박스 vs 리스트 컨트롤

리스트 컨트롤

▩  다양한 뷰 스타일 제공

▩  기능 up, 코드 up

▩  다양한 매크로 함수 제공

msdn 문서 참조

뷰 스타일


속성 => View(보기)에서 설정 가능

Icon

 

Small Icon
List
Report

이 중에서 Report 스타일이 많이 쓰임.

 

Report List 컨트롤 구조


▩ 구조

모든 요소의 시작 인덱스는 0이다.

 

포함 헤더


▩ Commctrl.h

Windowsx.h

 

 

컬럼 생성과 문자열 등록


▩ 매크로 함수

int ListView_InsertColumn( HWND hwnd, int iCol, const LPLVCOLUMN pcol)

hwnd : 윈도우 핸들( GetDlgItem() 사용 )

iCol : 컬럼 인덱스

pcol : LVCOLUMN의 메모리 주소

 

▩ LVCOLUMN 구조체

typedef struct tagLVCOLUMNW {
  UINT   mask;
  int    fmt;
  int    cx;
  LPWSTR pszText;
  int    cchTextMax;
  int    iSubItem;
  int    iImage;
  int    iOrder;
  int    cxMin;
  int    cxDefault;
  int    cxIdeal;
} LVCOLUMNW, *LPLVCOLUMNW;

mask, fmt, cx, psztTxt, iSubItem 정도만 알아도 됨.

 

mask


▩ 역할

- 컬럼에 적용할 속성을 결정 .fmt, .cs, .pszText, .iSubItem

 

  설정 방법 (OR 연산)

- LVCF_FMT : fmt의 컬럼과 서브 아이템 정렬

- LVCF_WIDTH : 길이 적용

- LVCF_TEXT : 문자열 적용

- LVCF_SUBITEM : 서브 아이템 적용

 

▩ mask의 일반적인 형태

LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM

 

fmt


 

▩ 역할

- 컬럼과 서브 아이템의 데이터 정렬 형식 지정(왼쪽 정렬, 가운데 정렬, 오른쪽 정렬)

 

▩ 정렬 방식

- LVCFMT_LEFT

- LVCFMT_RIGHT

_ LVCFMT_CENTER

 

▩ 0 인덱스의 컬럼과 서브아이템 정렬 => 항상 왼쪽 정렬

 

 

cx, pszText, iSubItem


▩ 역할

cx : 가로길이

pszText : 문자열 지정

iSubItem : 서브 아이템 인덱스

 

 

사용예시.

    static HWND hList;
    char* strMenu[] = { "항목1", "항목2", "항목3", "항목4"};
    LVCOLUMN lvColumn;

    int wmid = LOWORD(wParam);;
    static char string[100];
    

    switch (message)
    {
    case WM_CLOSE:
        EndDialog(hDlg, 0);
        return (INT_PTR)TRUE;
    case WM_INITDIALOG:
        hList = GetDlgItem(hDlg, IDC_LIST1);
        lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
        lvColumn.fmt = LVCFMT_CENTER;
        for (int i = 0; i < 4; i++)
        {
            lvColumn.cx = strlen(strMenu[i]) * 10;
            lvColumn.pszText = strMenu[i];
            ListView_InsertColumn(hList, i, &lvColumn);
        }
        break;

 

아이템 개수 조사


▩ 매크로 함수

int ListView_GetItemCount(
   HWND hwnd
);

 

 

▩ 용도

- 아이템 개수 조사

- 아이템 생성 및 추가 등

 

아이템 생성 및 삽입


int ListView_InsertItem( HWND hwnd, const LPLVITEM plvItem)

 

▩ LVITEM 구조체

typedef struct tagLVITEMA {
  UINT   mask;
  int    iItem;
  int    iSubItem;
  UINT   state;
  UINT   stateMask;
  LPSTR  pszText;
  int    cchTextMax;
  int    iImage;
  LPARAM lParam;
  int    iIndent;
  int    iGroupId;
  UINT   cColumns;
  PUINT  puColumns;
  int    *piColFmt;
  int    iGroup;
} LVITEMA, *LPLVITEMA;

mask : 아이템에 적용할 속성 지정(LVIF_TEXT)

iItem : 추가할 인덱스 번호 지정(ListView_GetItemCount())

iSubItem : 0(고정)

pszText : 문자열 지정

 

사용예시.

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    UNREFERENCED_PARAMETER(lParam);
    static HWND hList;
    char* strMenu[] = { "항목1", "항목2", "항목3", "항목4"};
    LVCOLUMN lvColumn;
    LVITEM lvItem;
    int wmid = LOWORD(wParam);;
    static char string[100];

    switch (message)
    {
    case WM_CLOSE:
        EndDialog(hDlg, 0);
        return (INT_PTR)TRUE;
    case WM_INITDIALOG:
        hList = GetDlgItem(hDlg, IDC_LIST1);
        lvColumn.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM;
        lvColumn.fmt = LVCFMT_CENTER;
        for (int i = 0; i < 4; i++)
        {
            lvColumn.cx = strlen(strMenu[i]) * 10;
            lvColumn.pszText = strMenu[i];
            ListView_InsertColumn(hList, i, &lvColumn);
        }
        break;
    case WM_COMMAND:
        switch (wmid)
        {
        case IDC_BUTTON4:
            lvItem.iItem = ListView_GetItemCount(hList);
            lvItem.iSubItem = 0;
            lvItem.mask = LVIF_TEXT;
            sprintf_s(string, "%d", lvItem.iItem);
            lvItem.pszText = string;
            ListView_InsertItem(hList, &lvItem);
            return(INT_PTR)TRUE;
        }
        break;
    }
    
    return (INT_PTR)FALSE;
}

 

서브 아이템에 데이터 저장


▩ 매크로 함수

void ListView_SetItemText(
   HWND hwnd,
   int i,
   int iSubItem_,
   LPCTSTR pszText_
);

hwnd : 윈도우 핸들

i : 인덱스 번호

iSubItem : 해당되는 서브아이템 항목 지정

pszText : 문자열 지정

 

서브 아이템 데이터 가져오기


▩ 매크로 함수

void ListView_GetItemText(
   HWND hwnd,
   int i,
   int iSubItem_,
   LPTSTR pszText_,
   int cchTextMax_
);

pszText : 문자열을 저장할 배열

cchTextMax : 문자열의 최대 길이

 

1단계

▩ 아이템 선택에 대한 메시지 알아내기

▩ 발생 메시지

- WM_NOTIFY

- lParam

통지 코드, 컨트롤 핸들, 아이디가 저자오딘 메모리 주소

 

▩ lParam 다루는 방법

- NMHDR 구조체 사용

 

▩ NMHDR 구조체

typedef struct _nmhdr {
  HWND hwndFrom; // 윈도우 핸들
  UINT idFrom; // 컨트롤 아이디
  UINT code; // 통지 코드
} NMHDR;

통지 코드 : NM_CLICK

 

1단계 기본구조.

INT_PTR CALLBACK DlgProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
    switch (message)
    {
    case WM_NOTIFY:
        switch (((LPNMHDR)lParam)->code)
        {
        case NM_CLICK:
            return TRUE;
        }
        break;
        ...

 

2단계

▩ 아이템 인덱스 알아내기

▩ 매크로 함수

int ListView_GetNextItem(
   HWND hwnd,
   int i, // 임의의 인덱스, -1
   UINT flags // LVNI_SELECTED
);

선택이 없을 때 : -1 리턴

 

▩ 리스트 컨트롤 뷰 설정 매크로 함수

void ListView_SetExtendedListViewStyle(
   HWND hwndLV, 윈도우 핸들
   DWORD dwExStyle
);

 

▩ dwExStyle

LVS_EX_FULLROWSELECT | LVS_EX_GRIDLINES

자세한 내용은 msdn문서 참조

 

아이템 수정


▩ ListView_GetItemText()

▩ ListView_SetItemText()

 

아이템 삽입과 순번 정렬


▩ ListView_InsertItemText()

▩ ListView_SetItemText()

 

아이템 삭제


▩ ListView_DeleteItem()

▩ ListView_DeleteAllItem()