640 likes | 751 Views
11. 공통 컨트롤. 1. 공통 컨트롤의 초기화. 공통 컨트롤은 DLL 에 의해 제공되는 것이기 때문에 이 DLL 이 로드되어 있지 않으면 윈도우 클래스가 정의되지 않으며 컨트롤도 생성할 수 없다 . 1. CommCtrl.h 를 반드시 포함시킨다 . 공통 컨트롤에 대한 윈도우 클래스명 , 스타일 , 메시지 등에 대한 매크로 상수가 정의되어 있다 . 2. 프로그램 선두에 InitCommonControls() 함수를 호출해 주어야 한다 .
E N D
11. 공통 컨트롤
1. 공통 컨트롤의 초기화 • 공통 컨트롤은 DLL에 의해 제공되는 것이기 때문에 이 DLL이 로드되어 있지 않으면 윈도우 클래스가 정의되지 않으며 컨트롤도 생성할 수 없다. • 1. CommCtrl.h를 반드시 포함시킨다. • 공통 컨트롤에 대한 윈도우 클래스명, 스타일, 메시지 등에 대한 매크로 상수가 정의되어 있다. • 2. 프로그램 선두에 InitCommonControls()함수를 호출해 주어야 한다. • 이 함수는 공통 컨트롤을 제공하는 DLL인 COMCTL32.DLL이 제대로 로드되었는지를 체크해 주고 만약 로드 되어 있지 않으면 로드한다. • 3. ComCtl32.lib를 링크 시킨다. • BOOL InitCommonControlsEx( LPINITCOMMONCONTROLSEX lpInitCtrls); typedef struct tagINITCOMMONCONTROLSEX { DWORD dwSize; DWORD dwICC; } INITCOMMONCONTROLSEX, *LPINITCOMMONCONTROLSEX;
2. Progress 컨트롤 • 윈도우 클래스 : PROGRESS_CLASS • 1. PBM_SETRANGE메시지로 범위를 설정한다. • 2. PBM_SETPOS메시지로 위치 값을 설정한다.
BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hProgress; switch (message) { case WM_INITDIALOG : hProgress = GetDlgItem(hDlg,IDC_PROGRESS1); SendMessage(hProgress,PBM_SETRANGE,0,MAKELPARAM(0,100)); SendMessage(hProgress,PBM_SETPOS,0,0); return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_BUTTON1: { for(int i = 0;i <= 100;i++) { SendMessage(hProgress,PBM_SETPOS,i,0); Sleep(50); } } return TRUE; case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; }
사용자가 트랙 바를 조작하면 WM_HSCROLL, WM_VSCROLL 메시지를 부모 윈도우로 보내며 LOWORD(wParam)으로 통지 메시지를 보낸다. 3. 트랙 바
BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hProgress; static HWND hEdit; static HWND hTrackBar; switch (message) { case WM_INITDIALOG : hProgress = GetDlgItem(hDlg,IDC_PROGRESS1); SendMessage(hProgress,PBM_SETRANGE,0,MAKELPARAM(0,100)); SendMessage(hProgress,PBM_SETPOS,0,0); hTrackBar = GetDlgItem(hDlg,IDC_SLIDER1); SendMessage(hTrackBar,TBM_SETRANGE,0,MAKELPARAM(0,100)); SendMessage(hTrackBar,TBM_SETPOS,0,0); hEdit = GetDlgItem(hDlg,IDC_EDIT1); return TRUE ; case WM_HSCROLL: { int iReturnCtrl = GetDlgCtrlID((HWND)lParam); switch (iReturnCtrl) { case IDC_SLIDER1: { int iPos; iPos = SendMessage(hTrackBar,TBM_GETPOS,NULL,NULL); char temp[256]; wsprintf(temp,"%d",iPos); SetWindowText(hEdit,temp); } break; } } return TRUE;
case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_BUTTON1: { for(int i = 0;i <= 100;i++) { SendMessage(hProgress,PBM_SETPOS,i,0); Sleep(50); } } return TRUE; case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; }
BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HWND hProgress; static HWND hEdit,hEdit2; static HWND hTrackBar; static HWND hSpin; switch (message) { case WM_INITDIALOG : { hProgress = GetDlgItem(hDlg,IDC_PROGRESS1); SendMessage(hProgress,PBM_SETRANGE,0,MAKELPARAM(0,100)); SendMessage(hProgress,PBM_SETPOS,0,0); hTrackBar = GetDlgItem(hDlg,IDC_SLIDER1); SendMessage(hTrackBar,TBM_SETRANGE,0,MAKELPARAM(0,100)); SendMessage(hTrackBar,TBM_SETPOS,0,0); hEdit = GetDlgItem(hDlg,IDC_EDIT1); hEdit2 = GetDlgItem(hDlg,IDC_EDIT2); hSpin = GetDlgItem(hDlg,IDC_SPIN1); SendMessage(hSpin,UDM_SETRANGE,0,MAKELPARAM(1000,0)); SendMessage(hSpin,UDM_SETBUDDY,(WPARAM)hEdit2,NULL); static UDACCEL udAccel[3] = {{0,1},{5,10},{8,20}}; SendMessage(hSpin,UDM_SETACCEL,(WPARAM)3,(LPARAM)udAccel); } return TRUE ;
case WM_HSCROLL: { int iReturnCtrl = GetDlgCtrlID((HWND)lParam); switch (iReturnCtrl) { case IDC_SLIDER1: { int iPos; iPos = SendMessage(hTrackBar,TBM_GETPOS,NULL,NULL); char temp[256]; wsprintf(temp,"%d",iPos); SetWindowText(hEdit,temp); } break; } } return TRUE; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_BUTTON1: { for(int i = 0;i <= 100;i++) { SendMessage(hProgress,PBM_SETPOS,i,0); Sleep(50); } } return TRUE; case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; }
5. 애니메이트 • 다음에 맞는 AVI파일만 재생할 수 있다. • 비디오 스트림이 꼭 하나만 있어야 한다. • 사운드 스트림은 없거나 꼭 하나만 있어야 한다. • 압축이 되어 있지 않거나 압축되어 있어도 RLE8포맷이어야 한다.
switch (message) { case WM_INITDIALOG : { hProgress = GetDlgItem(hDlg,IDC_PROGRESS1); SendMessage(hProgress,PBM_SETRANGE,0,MAKELPARAM(0,100)); SendMessage(hProgress,PBM_SETPOS,0,0); hTrackBar = GetDlgItem(hDlg,IDC_SLIDER1); SendMessage(hTrackBar,TBM_SETRANGE,0,MAKELPARAM(0,100)); SendMessage(hTrackBar,TBM_SETPOS,0,0); hEdit = GetDlgItem(hDlg,IDC_EDIT1); hEdit2 = GetDlgItem(hDlg,IDC_EDIT2); hSpin = GetDlgItem(hDlg,IDC_SPIN1); SendMessage(hSpin,UDM_SETRANGE,0,MAKELPARAM(1000,0)); SendMessage(hSpin,UDM_SETBUDDY,(WPARAM)hEdit2,NULL); static UDACCEL udAccel[3] = {{0,1},{5,10},{8,20}}; SendMessage(hSpin,UDM_SETACCEL,(WPARAM)3,(LPARAM)udAccel); HWND hAnimate = GetDlgItem(hDlg,IDC_ANIMATE1); SendMessage(hAnimate,ACM_OPEN,NULL,MAKELPARAM(IDR_AVI1,0)); SendMessage(hAnimate,ACM_PLAY,(WPARAM)-1,MAKELPARAM(0,-1)); } return TRUE ;
핫 키는 운영체제가 지원하는 키보드 입력 방법 중 하나이다. 다른 키 입력에 비해 우선 순위가 높게 매겨져 잇다. 어떤 작업을 하고 있던 중이라도 핫키 입력이 가능하며 보통 작업 중단이나 특별한 신호를 보내기 위해 사용된다. BOOL RegisterHotKey(HWND hWnd, int id, UINT fsModifiers, UINT vk); BOOL UnregisterHotKey( HWND hWnd, int id); id : 핫키의 고유 번호 fsModifiers : MOD_ALT, MOD_CONTROL, MOD_SHIFT vk : 가상 키코드 등록된 핫키가 눌려지면 시스템은 핫키를 등록한 윈도우로 WM_HOTKEY메시지를 보내준다. 6. 핫키 RegisterHotKey(hDlg,1,MOD_ALT|MOD_CONTROL,'X'); } return TRUE ; case WM_HOTKEY: MessageBox(hDlg,"핫키를 눌렀다.","핫키",MB_OK); return TRUE;
6. 핫키 RegisterHotKey(hDlg,1,MOD_ALT|MOD_CONTROL,'X'); } return TRUE ; case WM_HOTKEY: MessageBox(hDlg,"핫키를 눌렀다.","핫키",MB_OK); return TRUE; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_BUTTON1: { for(int i = 0;i <= 100;i++) { SendMessage(hProgress,PBM_SETPOS,i,0); Sleep(50); } } return TRUE; case IDOK : case IDCANCEL : UnregisterHotKey(hDlg,1); EndDialog (hDlg, 0) ; return TRUE ; } break ;
DWORD DateTime_GetSystemtime(HWND hwndDP, LPSYSTEMTIME pSysTime) 사용자가 선택한 날짜를 조사한다. BOOL DateTime_SetSystemtime(HWND hwndDT, DWORD flag, LPSYSTEMTIME lpSysTime); flag : GDT_VALID 7. 날짜 선택 컨트롤 hDTP = GetDlgItem(hDlg,IDC_DATETIMEPICKER1); } return TRUE ; case WM_HOTKEY: { SYSTEMTIME st; DateTime_GetSystemtime(hDTP,&st); char temp[256]; wsprintf(temp,"%d년 %d월 %d일",st.wYear,st.wMonth,st.wDay); MessageBox(hDlg,temp,"선택한 날짜",MB_OK); } return TRUE;
8. 상태란 • HWND CreateStatusWindow(LONG style, LPCTSTR lpszText, HWND hwndParent, UINT wID); • 상태란을 만드는 함수이다. • style : WS_CHILD | WS_VISIBLE • lpszText : 상태란에 나타날 초기 문자열 • hwndParent : 부모 윈도우의 핸들 • wID : 상태란의 ID이다.
hStatus = CreateStatusWindow(WS_CHILD|WS_VISIBLE, "Status Line", hDlg, 0); int PartArray[3] = {100,300,-1}; SendMessage(hStatus,SB_SETPARTS,(WPARAM)3,(LPARAM)PartArray); } return TRUE ; case WM_MOUSEMOVE: { char temp[256]; wsprintf(temp,"x => %d. y => %d",LOWORD(lParam),HIWORD(lParam)); SendMessage(hStatus,SB_SETTEXT,(WPARAM)1,(LPARAM)temp); } return TRUE;
int PropertySheet( LPCPROPSHEETHEADER lppsph ); 프로퍼티 시트를 만든다. 9. 프로퍼티 시트 typedef struct _PROPSHEETPAGE { DWORD dwSize; DWORD dwFlags; HINSTANCE hInstance; union { LPCSTR pszTemplate; LPCDLGTEMPLATE pResource; }; union { HICON hIcon; LPCSTR pszIcon; }; LPCSTR pszTitle; DLGPROC pfnDlgProc; LPARAM lParam; LPFNPSPCALLBACK pfnCallback; UINT * pcRefParent; #if (_WIN32_IE >= 0x0500) LPCTSTR pszHeaderTitle; LPCTSTR pszHeaderSubTitle; #endif #if (_WIN32_WINNT >= 0x0501) HANDLE hActCtx; #endif } PROPSHEETPAGE, *LPPROPSHEETPAGE;
시트 구조체 PROPSHEETPAGE 구조체는 프로퍼티 시트에 포함된 개별 페이지에 대한 구조체이다. 9. 프로퍼티 시트 typedef struct _PROPSHEETHEADER { DWORD dwSize; DWORD dwFlags; HWND hwndParent; HINSTANCE hInstance; union { HICON hIcon; LPCTSTR pszIcon; }; LPCTSTR pszCaption; UINT nPages; union { UINT nStartPage; LPCTSTR pStartPage; }; union { LPCPROPSHEETPAGE ppsp; HPROPSHEETPAGE *phpage; }; PFNPROPSHEETCALLBACK pfnCallback; #if (_WIN32_IE >= 0x0500) union { HBITMAP hbmWatermark; LPCTSTR pszbmWatermark; }; HPALETTE hplWatermark; union { HBITMAP hbmHeader; LPCSTR pszbmHeader; }; #endif } PROPSHEETHEADER, *LPPROPSHEETHEADER;
#include <windows.h> #include "resource.h" #include <commctrl.h> HINSTANCE hInst; BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,PSTR szCmdLine, int iCmdShow) { hInst = hInstance; DialogBox(hInstance,MAKEINTRESOURCE(IDD_DIALOG1),NULL,DlgProc); return 0; } BOOL CALLBACK DialogProc1 (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); BOOL CALLBACK DialogProc2 (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam); BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) { case WM_INITDIALOG : return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDC_BUTTON1: { PROPSHEETPAGE psp[2]; PROPSHEETHEADER psh; psp[0].dwSize = sizeof(PROPSHEETPAGE); psp[0].dwFlags = PSP_DEFAULT; psp[0].hInstance = hInst; psp[0].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG2); psp[0].pfnDlgProc=(DLGPROC)DialogProc1; psp[0].lParam = 0; psp[1].dwSize = sizeof(PROPSHEETPAGE); psp[1].dwFlags = PSP_DEFAULT; psp[1].hInstance = hInst; psp[1].pszTemplate = MAKEINTRESOURCE(IDD_DIALOG3); psp[1].pfnDlgProc=(DLGPROC)DialogProc2; psp[1].lParam = 0;
psh.dwSize = sizeof(PROPSHEETHEADER); psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW; psh.hwndParent = hDlg; psh.pszCaption = "프로퍼티 페이지"; psh.nPages = 2; psh.nStartPage = 0; psh.ppsp = psp; PropertySheet(&psh); } return TRUE; case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; } BOOL CALLBACK DialogProc1 (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { return FALSE ; } BOOL CALLBACK DialogProc2 (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { return FALSE ; }
9. 프로퍼티 시트 • 프로퍼티 시트의 메시지
HIMAGELIST ImageList_LoadBitmap( HINSTANCE hi, LPCSTR lpbmp, int cx, int cGrow, COLORREF crMask); 지정한 비트맵 리소스를 읽어와 이미지 리스트를 만들고 그 핸들을 리턴 해 준다. lpbmp : 비트맵 리소스의 이름 cx : 각 이미지의 폭 cGrow : 이미지 리스트는 이미지가 추가될 때마다 메모리를 재할당하여 추가된 이미지를 저장한다. 한꺼번에 할당할 메모리 양을 지정한다. crMask : 투명색으로 사용할 색상을 지정 HIMAGELIST ImageList_LoadImage( HINSTANCE hi, LPCSTR lpbmp, int cx, int cGrow, COLORREF crMask, UINT uType, UINT uFlags); 이 함수는 비트맵뿐만 아니라 아이콘과 커서까지도 읽을 수 있다. uType : IMAGE_BITMAP, IMAGE_CURSOR, IMAGE_ICON uFlags : ImageList_Destroy() 이미지 리스트를 파괴한다. 10. 이미지 리스트
BOOL ImageList_Draw( HIMAGELIST himl , int i, HDC hdcDst, int y, UINT fStyle); 이미지 리스트의 이미지를 화면에 출력한다. himl : 이미지 리스트의 핸들 i : 이미지 번호 hdcDst : 출력 대상 DC x,y : 좌표 fStyle : IDL_NORMAL : 배경색상으로 이미지를 출력한다. IDL_TRANSPARENT : 마스크를 사용하여 투명한 이미지를 그린다. 10. 이미지 리스트
BOOL ImageList_SetOverlayImage( HIMAGELIST himl, int iImage, int iOverlay); image 번째의 이미지를 iOverlay 번째의 오버레이 이미지로 지정한다. 10. 이미지 리스트 HIMAGELIST IL = ImageList_LoadBitmap(g_hInst, MAKEINTRESOURCE(IDB_BITMAP1), 32, 1, RGB(0,0,255)); ImageList_SetOverlayImage(IL,1,1); ImageList_Draw(IL,0,hdc, 50,50, ILD_NORMAL); ImageList_Draw(IL,0,hdc, 50,50, ILD_NORMAL|INDEXTOOVERLAYMASK(1));
LRESULT CALLBACK WndProc (HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdc; PAINTSTRUCT ps ; RECT rect ; static HINSTANCE hInst; static HIMAGELIST IL; switch (message) { case WM_CREATE: hInst = ((LPCREATESTRUCT)lParam)->hInstance; IL = ImageList_LoadBitmap(hInst,MAKEINTRESOURCE(IDB_BITMAP1),16,1,RGB(192,192,192)); ImageList_SetOverlayImage(IL,1,1); return 0 ; case WM_LBUTTONDOWN: hdc = GetDC(hwnd); ImageList_Draw(IL,0,hdc,50,50,ILD_NORMAL); ImageList_Draw(IL,0,hdc,100,100,ILD_NORMAL|INDEXTOOVERLAYMASK(1)); ReleaseDC(hwnd,hdc); return 0; case WM_PAINT: hdc = BeginPaint (hwnd, &ps) ; GetClientRect (hwnd, &rect) ; DrawText (hdc, "Hello, Windows 98!", -1, &rect,DT_SINGLELINE | DT_CENTER | DT_VCENTER) ; EndPaint (hwnd, &ps) ; return 0 ; case WM_DESTROY: PostQuitMessage (0) ; return 0 ; } return DefWindowProc (hwnd, message, wParam, lParam) ; }
BOOL CALLBACK DlgProc (HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam) { static HIMAGELIST hIL; static HWND hListView; switch (message) { case WM_INITDIALOG : { hIL = ImageList_LoadBitmap(hInst, MAKEINTRESOURCE(IDB_BITMAP1), 16, 1, RGB(192,192,192)); hListView = GetDlgItem(hDlg,IDC_LIST1); SendMessage(hListView,LVM_SETIMAGELIST,(WPARAM)LVSIL_SMALL,(LPARAM)hIL); SendMessage(hListView,LVM_SETIMAGELIST,(WPARAM)LVSIL_NORMAL,(LPARAM)hIL); LVCOLUMN col; col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; col.fmt = LVCFMT_LEFT; col.cx = 100; col.pszText = "이름"; col.iSubItem = 0; SendMessage(hListView,LVM_INSERTCOLUMN,0,(LPARAM)&col); col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; col.fmt = LVCFMT_LEFT; col.cx = 100; col.pszText = "주소"; col.iSubItem = 1; SendMessage(hListView,LVM_INSERTCOLUMN,1,(LPARAM)&col); col.mask = LVCF_FMT | LVCF_WIDTH | LVCF_TEXT | LVCF_SUBITEM; col.fmt = LVCFMT_LEFT; col.cx = 100; col.pszText = "전화번호"; col.iSubItem = 2; SendMessage(hListView,LVM_INSERTCOLUMN,2,(LPARAM)&col); LVITEM li; li.mask = LVIF_TEXT | LVIF_IMAGE; li.state = 0; li.stateMask = 0;
li.iImage = 0; li.iSubItem = 0; li.iItem = 0; li.pszText = "홍길동"; SendMessage(hListView, LVM_INSERTITEM, 0 , (LPARAM)&li); li.iSubItem = 1; li.pszText = "서울"; SendMessage(hListView, LVM_SETITEM, 0 , (LPARAM)&li); li.iSubItem = 2; li.pszText = "123-1234"; SendMessage(hListView, LVM_SETITEM, 0 , (LPARAM)&li); li.iImage = 1; li.iSubItem = 0; li.iItem = 1; li.pszText = "김길동"; SendMessage(hListView, LVM_INSERTITEM, 0 , (LPARAM)&li); li.iSubItem = 1; li.pszText = "강원도"; SendMessage(hListView, LVM_SETITEM, 0 , (LPARAM)&li); li.iSubItem = 2; li.pszText = "234-2345"; SendMessage(hListView, LVM_SETITEM, 0 , (LPARAM)&li); } return TRUE ; case WM_COMMAND : switch (LOWORD (wParam)) { case IDOK : case IDCANCEL : EndDialog (hDlg, 0) ; return TRUE ; } break ; } return FALSE ; }
11. 리스트 뷰 typedef struct _LVCOLUMN { UINT mask; int fmt; int cx; LPTSTR pszText; int cchTextMax; int iSubItem; #if (_WIN32_IE >= 0x0300) int iImage; int iOrder; #endif } LVCOLUMN, *LPLVCOLUMN;
선택 항목 조사 리스트 뷰는 항목에 변경이 발생하기 전에 LVN_ITEMCHANGING 통지 메시지를 보내주고 변경이 발생한 후에 LVN_ITEMCHANGED 통지 메시지를 보내준다. 이 두 메시지의 lPara에는 어떠한 변경이 발생했는지에 대한 정보인 NMLISTVIEW 구조체의 포인터가 전달된다. 11. 리스트 뷰 typedef struct tagNMLISTVIEW { NMHDR hdr; int iItem; int iSubItem; UINT uNewState; UINT uOldState; UINT uChanged; POINT ptAction; LPARAM lParam; } NMLISTVIEW, *LPNMLISTVIEW;
typedef struct tagNMHDR { HWND hwndFrom; UINT idFrom; UINT code; } NMHDR;
case WM_NOTIFY: { LPNMHDR hdr; LPNMLISTVIEW nlv; hdr = (LPNMHDR)lParam; nlv = (LPNMLISTVIEW)lParam; if (hdr->hwndFrom == hListView) { switch(hdr->code) { case LVN_ITEMCHANGED: if(nlv->uChanged == LVIF_STATE && nlv->uNewState == (LVIS_SELECTED|LVIS_FOCUSED)) { char szName[255]; char szAddr[255]; char szTelNo[255]; ListView_GetItemText(hListView, nlv->iItem,0,szName,255); ListView_GetItemText(hListView, nlv->iItem,1,szAddr,255); ListView_GetItemText(hListView, nlv->iItem,2,szTelNo,255); char temp[256]; wsprintf(temp,"이름 : %s,주소 : %s,전화번호 : %s",szName, szAddr,szTelNo); MessageBox(hDlg,temp,"",MB_OK); } } } }
case WM_NOTIFY: { LPNMHDR hdr; LPNMLISTVIEW nlv; hdr = (LPNMHDR)lParam; nlv = (LPNMLISTVIEW)lParam; if (hdr->hwndFrom == hListView) { switch(hdr->code) { case NM_DBLCLK: { LPNMITEMACTIVATE lpnmitem = (LPNMITEMACTIVATE) lParam; if (nlv->iItem != -1) { char temp[256]; ListView_GetItemText(hListView,lpnmitem->iItem,lpnmitem->iSubItem,temp,256); MessageBox(NULL,temp,"",MB_OK); } } } } }
트리 뷰 컨트롤 스타일 TVS_HASBUTTONS 자식 항목을 가진 부모 항목 옆에 +, - 버튼을 보여 준다. TVS_HASLINES 항목간의 계층구조를 좀 더 명확히 보여주기 위해 점선으로 항목간을 연결하여 표시하도록 한다. TVS_LINESATROOT 루트 항목끼리 선으로 연결한다. 단 이 스타일은 TVS_HASLINES속성이 선택되어 있을 때만 효력을 발휘한다. TVS_EDITLABES 사용자가 항목의 텍스트를 직접 수정할 수 있도록 해준다. TVS_DISABLEDRAGDROP 스타일의 이름대로 항목을 드래그하지 못하도록 한다. TVS_SHOWSELALWAYS 트리 뷰가 포커스를 가지지 않은 상태에서 선택된 항목이 반전된 상태로 남아 있도록 한다. TVS_CHECKBOXES 항목 옆에 체크 박스를 보여준다. 12. 트리 뷰
12. 트리 뷰 • 트리 뷰 컨트롤 메시지