Revision: 10016 https://osdn.net/projects/ttssh2/scm/svn/commits/10016 Author: zmatsuo Date: 2022-06-24 23:04:22 +0900 (Fri, 24 Jun 2022) Log Message: ----------- ツリー付きプロパティーに拡張した - TTCPropSheetDlg をツリー付きにできるようにした Modified Paths: -------------- trunk/teraterm/common/tmfc_propdlg.cpp trunk/teraterm/common/tmfc_propdlg.h -------------- next part -------------- Modified: trunk/teraterm/common/tmfc_propdlg.cpp =================================================================== --- trunk/teraterm/common/tmfc_propdlg.cpp 2022-06-24 14:04:10 UTC (rev 10015) +++ trunk/teraterm/common/tmfc_propdlg.cpp 2022-06-24 14:04:22 UTC (rev 10016) @@ -26,6 +26,13 @@ * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <windows.h> +#include <commctrl.h> +#include <wchar.h> +#define _CRTDBG_MAP_ALLOC +#include <stdlib.h> +#include <crtdbg.h> + #include "ttlib.h" #include "dlglib.h" @@ -32,19 +39,140 @@ #include "tmfc_propdlg.h" #define REWRITE_TEMPLATE 1 +#define TREE_WIDTH 200 +#define CONTROL_SPACE 5 + +BOOL TTCPropSheetDlg::m_TreeViewInit = FALSE; + // quick hack :-( -HINSTANCE TTCPropSheetDlg::ghInstance; class TTCPropSheetDlg* TTCPropSheetDlg::gTTCPS; +TTCPropSheetDlg::TTCPropSheetDlg(HINSTANCE hInstance, HWND hParentWnd, const wchar_t *uilangfile) +{ + m_hInst = hInstance; + m_hWnd = 0; + m_hParentWnd = hParentWnd; + m_UiLanguageFile = _wcsdup(uilangfile); + memset(&m_psh, 0, sizeof(m_psh)); + m_psh.dwSize = sizeof(m_psh); + m_psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW | PSH_USECALLBACK; + //m_psh.dwFlags |= PSH_PROPTITLE; // \x81u\x82̃v\x83\x8D\x83p\x83e\x83B\x81[\x81v\x82\xAA\x92lj\xC1\x82\xB3\x82\xEA\x82\xE9? + m_psh.hwndParent = hParentWnd; + m_psh.hInstance = hInstance; + m_psh.pfnCallback = PropSheetProc; + m_Page = NULL; + m_PageCount = 0; + m_TreeView = m_TreeViewInit; +} + +TTCPropSheetDlg::~TTCPropSheetDlg() +{ + free((void*)m_psh.pszCaption); + free(m_UiLanguageFile); + + for (int i = 0; i < m_PageCount; i++) { + free(m_Page[i].path); + m_Page[i].path = NULL; + } + free(m_Page); +} + +void TTCPropSheetDlg::SetTreeViewMode(BOOL enable) +{ + m_TreeViewInit = enable; +} + +void TTCPropSheetDlg::AddPage(HPROPSHEETPAGE hpage, const wchar_t *path) +{ + TTPropSheetPage *p = + (TTPropSheetPage *)realloc(m_Page, sizeof(TTPropSheetPage) * (m_PageCount + 1)); + if (p == NULL) { + return; + } + m_Page = p; + m_Page[m_PageCount].hPsp = hpage; + m_Page[m_PageCount].path = (path == NULL) ? NULL : _wcsdup(path); + m_PageCount++; +} + +void TTCPropSheetDlg::SetCaption(const wchar_t* caption) +{ + free((void*)m_psh.pszCaption); + m_psh.pszCaption = _wcsdup(caption); +} + +INT_PTR TTCPropSheetDlg::DoModal() +{ + INT_PTR result; + int i; + HPROPSHEETPAGE *hPsp = (HPROPSHEETPAGE *)malloc(sizeof(HPROPSHEETPAGE) * m_PageCount); + for(i = 0; i < m_PageCount; i++) { + hPsp[i] = m_Page[i].hPsp; + } + m_psh.nPages = m_PageCount; + m_psh.phpage = hPsp; + gTTCPS = this; + result = PropertySheetW(&m_psh); + free(hPsp); + return result; +} + LRESULT CALLBACK TTCPropSheetDlg::WndProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam) { switch(msg){ case WM_INITDIALOG: case WM_SHOWWINDOW: { + if (m_TreeView) { + AddTreeControl(); + } CenterWindow(dlg, m_hParentWnd); break; } + case WM_NOTIFY: { + NMHDR *nmhdr = (NMHDR *)lParam; + switch(nmhdr->code) { +#if 0 + // TVN_SELCHANGED \x82\xAA\x82\xA0\x82\xEA\x82Εs\x97v\x81A\x82\xBB\x82̂\xA4\x82\xBF\x8F\xC1\x82\xB7 + case TVN_SELCHANGINGW: + case TVN_SELCHANGING: { + NMTREEVIEWW *pnmtv = (LPNMTREEVIEWW)lParam; + TVITEMW item; + item.mask = TVIF_PARAM; + item.hItem = pnmtv->itemNew.hItem; + SendMessageW(m_hWndTV, TVM_GETITEMW, 0, (LPARAM)&item); + WPARAM page_index = item.lParam; + SendMessageW(m_hWnd, PSM_SETCURSEL, page_index, 0); + break; + } +#endif + case TVN_SELCHANGEDW: + case TVN_SELCHANGED: { + // \x83c\x83\x8A\x81[\x83r\x83\x85\x81[\x82\xAA\x91I\x91\xF0\x82\xB3\x82ꂽ\x81A\x83^\x83u\x82\xF0\x90\xE8\x91ւ\xA6\x82\xE9 + NMTREEVIEWW *pnmtv = (LPNMTREEVIEWW)lParam; + TVITEMW item; + item.mask = TVIF_PARAM; + item.hItem = pnmtv->itemNew.hItem; + SendMessageW(m_hWndTV, TVM_GETITEMW, 0, (LPARAM)&item); + WPARAM page_index = item.lParam; + SendMessageW(m_hWnd, PSM_SETCURSEL, page_index, 0); + break; + } + case TCN_SELCHANGE: { + // \x83^\x83u\x82\xAA\x90\xE8\x91ւ\xED\x82\xE9\x82Ƃ\xAB\x82ɔ\xAD\x90\xB6\x81A\x83c\x83\x8A\x81[\x83r\x83\x85\x81[\x82Ɠ\xAF\x8A\xFA + // \x83^\x83u\x82\xF0\x83}\x83E\x83X\x82ŃN\x83\x8A\x83b\x83N\x81A + // \x83^\x83u\x82Ƀt\x83H\x81[\x83J\x83X\x82\xAA\x82\xA0\x82\xE9\x82Ƃ\xAB\x82ɍ\xB6\x89E\x83L\x81[ + // CTRL+PgUp,PgDn \x82\xE2 CTRL+TAB\x82ł͔\xAD\x90\xB6\x82\xB5\x82Ȃ\xA2?? TCN_KEYDOWN\x82ŏ\x88\x97\x9D\x82\xAA\x95K\x97v? + HWND hTab = PropSheet_GetTabControl(dlg); + int cur_sel = TabCtrl_GetCurSel(hTab); + HTREEITEM item = GetTreeItem(cur_sel, TVI_ROOT); + if (TreeView_GetSelection(m_hWndTV) != item) { + TreeView_SelectItem(m_hWndTV, item); + } + break; + } + } } + } SetWindowLongPtrW(dlg, GWLP_WNDPROC, m_OrgProc); SetWindowLongPtrW(dlg, GWLP_USERDATA, m_OrgUserData); LRESULT result = CallWindowProcW((WNDPROC)m_OrgProc, dlg, msg, wParam, lParam); @@ -51,6 +179,23 @@ m_OrgProc = SetWindowLongPtrW(dlg, GWLP_WNDPROC, (LONG_PTR)WndProcStatic); m_OrgUserData = SetWindowLongPtrW(dlg, GWLP_USERDATA, (LONG_PTR)this); +#if 0 + // ?? CTRL+PgUp,PgDn \x82ł͂\xB1\x82̃\x81\x83b\x83Z\x81[\x83W\x82͔\xAD\x90\xB6\x82\xB5\x82Ȃ\xA2 + // \x82\xBB\x82̂\xA4\x82\xBF\x8F\xC1\x82\xB7 + switch(msg){ + case PSM_CHANGED: + case PSM_SETCURSEL: + case PSM_SETCURSELID: { + if (m_TreeView) { + HWND hTab = PropSheet_GetTabControl(dlg); + int cur_sel = TabCtrl_GetCurSel(hTab); + int a = 0; + } + + break; + } + } +#endif return result; } @@ -63,15 +208,16 @@ int CALLBACK TTCPropSheetDlg::PropSheetProc(HWND hWnd, UINT msg, LPARAM lp) { switch (msg) { - case PSCB_PRECREATE: - { + case PSCB_PRECREATE: { #if defined(REWRITE_TEMPLATE) // \x83e\x83\x93\x83v\x83\x8C\x81[\x83g\x82̓\xE0\x97e\x82\xF0\x8F\x91\x82\xAB\x8A\xB7\x82\xA6\x82\xE9 // http://home.att.ne.jp/banana/akatsuki/doc/atlwtl/atlwtl15-01/index.html + TTCPropSheetDlg*self = gTTCPS; + HINSTANCE hInst = self->m_hInst; size_t PrevTemplSize; size_t NewTemplSize; DLGTEMPLATE *NewTempl = - TTGetNewDlgTemplate(ghInstance, (DLGTEMPLATE *)lp, + TTGetNewDlgTemplate(hInst, (DLGTEMPLATE *)lp, &PrevTemplSize, &NewTemplSize); NewTempl->style &= ~DS_CONTEXTHELP; // check DLGTEMPLATEEX memcpy((void *)lp, NewTempl, NewTemplSize); @@ -79,8 +225,7 @@ #endif break; } - case PSCB_INITIALIZED: - { + case PSCB_INITIALIZED: { static const DlgTextInfo TextInfos[] = { { IDOK, "BTN_OK" }, { IDCANCEL, "BTN_CANCEL" }, @@ -97,44 +242,227 @@ return 0; } -void TTCPropSheetDlg::AddPage(HPROPSHEETPAGE page) +static void MoveChildWindows(HWND hWnd, int nDx, int nDy) { - hPsp[m_PageCount] = page; - m_PageCount++; + HWND hChildWnd = GetWindow(hWnd, GW_CHILD); + while (hChildWnd != NULL) { + RECT rect; + GetWindowRect(hChildWnd, &rect); + int x = rect.left + nDx; + int y = rect.top + nDy; + POINT p; + p.x = x; + p.y = y; + ScreenToClient(hWnd, &p); + x = p.x; + y = p.y; + SetWindowPos(hChildWnd, NULL, x, y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + + hChildWnd = GetNextWindow(hChildWnd, GW_HWNDNEXT); + } } -TTCPropSheetDlg::TTCPropSheetDlg(HINSTANCE hInstance, HWND hParentWnd, const wchar_t *uilangfile) +HTREEITEM TTCPropSheetDlg::GetTreeItem(int nPage, HTREEITEM hParent) { - m_hInst = hInstance; - m_hWnd = 0; - m_hParentWnd = hParentWnd; - m_UiLanguageFile = _wcsdup(uilangfile); - memset(&m_psh, 0, sizeof(m_psh)); - m_psh.dwSize = sizeof(m_psh); - m_psh.dwFlags = PSH_DEFAULT | PSH_NOAPPLYNOW | PSH_USECALLBACK; - //m_psh.dwFlags |= PSH_PROPTITLE; // \x81u\x82̃v\x83\x8D\x83p\x83e\x83B\x81[\x81v\x82\xAA\x92lj\xC1\x82\xB3\x82\xEA\x82\xE9? - m_psh.hwndParent = hParentWnd; - m_psh.hInstance = hInstance; - m_psh.pfnCallback = PropSheetProc; - m_PageCount = 0; + HTREEITEM hItem = TreeView_GetChild(m_hWndTV, hParent); + while (hItem) { + TVITEMW item; + item.hItem = hItem; + item.mask = TVIF_PARAM; + TreeView_GetItem(m_hWndTV, &item); + + if (item.lParam == nPage) { + // \x8C\xA9\x82\xA9\x82\xC1\x82\xBD + return hItem; + } + + // \x8Eq + HTREEITEM hItemFound = GetTreeItem(nPage, hItem); + if (hItemFound != NULL) { + // \x8C\xA9\x82\xA9\x82\xC1\x82\xBD + return hItemFound; + } + + // \x8E\x9F + hItem = TreeView_GetNextItem(m_hWndTV, hItem, TVGN_NEXT); + } + + return NULL; } -TTCPropSheetDlg::~TTCPropSheetDlg() + +/** + * \x83p\x83X\x82\xF0\x8D쐬\x82\xB5\x82ĕԂ\xB7 + * \x91\xB6\x8D݂\xB5\x82Ă\xA2\x82\xBD\x82炻\x82\xEA\x82\xF0\x95Ԃ\xB7 + * @param path L"path1/path2/path3" + * @param HTREEITEM \x8CĂяo\x82\xB5\x8C\xB3\x82\xCDTVI_ROOT (\x8DċA\x97p) + * @param page_index \x8D쐬\x82\xB5\x82\xBD\x83p\x83X\x82ɐݒ肷\x82\xE9page_index(0...) + * @return HTREEITEM + */ +HTREEITEM TTCPropSheetDlg::CreatePath(const wchar_t *path, HTREEITEM hParent, int page_index) { - free((void*)m_psh.pszCaption); - free(m_UiLanguageFile); + if (path == NULL || path[0] == 0) { + return hParent; + } + + wchar_t *path_cur = _wcsdup(path); + wchar_t *path_next = NULL; + wchar_t *p = wcschr(path_cur, L'/'); + if (p != NULL) { + path_next = p + 1; + *p = 0; + } + + // \x83p\x83X\x82\xAA\x8A\xF9\x82ɑ\xB6\x8D݂\xB5\x82Ă\xA2\x82邩? + HTREEITEM hItem = TreeView_GetChild(m_hWndTV, hParent); + while (hItem) { + wchar_t text[MAX_PATH]; + TVITEMW item; + item.hItem = hItem; + item.mask = TVIF_TEXT; + item.cchTextMax = _countof(text); + item.pszText = text; + // TreeView_GetItem(m_hWndTV, &item); + SendMessageW(m_hWndTV, TVM_GETITEMW, 0, (LPARAM)&item); + + if (wcscmp(item.pszText, path_cur) ==0) { + // \x91\xB6\x8D݂\xB5\x82Ă\xA2\x82\xE9 + if (path_next != NULL) { + // \x8DċA\x81A\x8E\x9F\x82\xF0\x92T\x82\xB7 + hItem = CreatePath(path_next, hItem, page_index); + } + free(path_cur); + return hItem; + } + + // \x8E\x9F + hItem = TreeView_GetNextItem(m_hWndTV, hItem, TVGN_NEXT); + } + + // \x8C\xA9\x82\xA9\x82\xE7\x82Ȃ\xA2\x81A\x8D\xEC\x82\xE9 + TVINSERTSTRUCTW tvi; + tvi.hParent = hParent; + tvi.hInsertAfter = TVI_LAST; + tvi.item.mask = TVIF_TEXT | TVIF_PARAM; + tvi.item.pszText = (wchar_t *)path_cur; + tvi.item.lParam = (LPARAM)page_index; + //TreeView_InsertItem(m_hWndTV, &tvi); + hItem = (HTREEITEM)SendMessageW(m_hWndTV, TVM_INSERTITEMW, 0, (LPARAM)&tvi); + + if (path_next != NULL) { + // \x8DċA\x82ŒT\x82\xB7(\x8C\xA9\x82\xA9\x82炸\x81A\x8D\xEC\x82邱\x82ƂɂȂ\xE9) + hItem = CreatePath(path_next, hItem, page_index); + } + + free(path_cur); + return hItem; } -void TTCPropSheetDlg::SetCaption(const wchar_t* caption) +void TTCPropSheetDlg::CreateTree(HWND dlg) { - free((void*)m_psh.pszCaption); - m_psh.pszCaption = _wcsdup(caption); + HWND hTab = PropSheet_GetTabControl(dlg); + const int nPageCount = TabCtrl_GetItemCount(hTab); + + // \x83V\x81[\x83g(\x96̗t)\x82\xF0\x92lj\xC1\x82\xB7\x82\xE9 + for (int i = 0; i < nPageCount; i++) { + // \x83y\x81[\x83W\x82̃^\x83C\x83g\x83\x8B\x8E擾 + wchar_t page_title[MAX_PATH]; + TCITEMW ti; + ZeroMemory(&ti, sizeof(ti)); + ti.mask = TCIF_TEXT; + ti.cchTextMax = _countof(page_title); + ti.pszText = page_title; + //TabCtrl_GetItem(hTab, i, &ti); + SendMessageW(hTab, TCM_GETITEMW, (WPARAM)i, (LPARAM)&ti); + + // \x83p\x83X(\x8E})\x82\xF0\x8D\xEC\x82\xE9 + wchar_t *path = m_Page[i].path; + HTREEITEM hItem = CreatePath(path, TVI_ROOT, i); + + // \x83V\x81[\x83g\x82\xF0\x92lj\xC1\x82\xB7\x82\xE9 + TVINSERTSTRUCTW tvi; + tvi.hParent = hItem; + tvi.hInsertAfter = TVI_LAST; + tvi.item.mask = TVIF_TEXT | TVIF_PARAM; + tvi.item.pszText = page_title; + tvi.item.lParam = (LPARAM)i; + //hItem = TreeView_InsertItem(m_hWndTV, &tvi); + hItem = (HTREEITEM)SendMessageW(m_hWndTV, TVM_INSERTITEMW, 0, (LPARAM)&tvi); + } } -INT_PTR TTCPropSheetDlg::DoModal() +void TTCPropSheetDlg::AddTreeControl() { - m_psh.nPages = m_PageCount; - m_psh.phpage = hPsp; - ghInstance = m_hInst; - gTTCPS = this; - return PropertySheetW(&m_psh); + HWND hTab = PropSheet_GetTabControl(m_hWnd); + + // \x83c\x83\x8A\x81[\x82őI\x91\xF0\x82ł\xAB\x82\xE9\x82̂Ń^\x83u\x82\xCD1\x8Ds\x90ݒ\xE8\x82ɂ\xB7\x82\xE9 + SetWindowLongPtr(hTab, GWL_STYLE, GetWindowLongPtr(hTab, GWL_STYLE) & ~TCS_MULTILINE); + +#if 0 + // \x83^\x83u\x82\xF0\x8F\xC1\x82\xB5\x82ė̈\xE6\x82\xF0\x88ړ\xAE\x82\xB5\x82悤\x82Ƃ\xB5\x82\xBD\x82\xAA\x82\xA4\x82܂\xAD\x82\xA2\x82\xA9\x82Ȃ\xA9\x82\xC1\x82\xBD + // \x82\xBB\x82̂\xA4\x82\xBF\x82\xB1\x82̃u\x83\x8D\x83b\x83N\x82͏\xC1\x82\xB7 + const bool m_HideTab = true; + if (m_HideTab) { + // \x83^\x83u\x95\x94\x95\xAA\x82\xF0\x89B\x82\xB7 + ShowWindow(hTab, SW_HIDE); + EnableWindow(hTab, FALSE); + + // \x83^\x83u\x95\x94\x95\xAA\x82̃T\x83C\x83Y(\x8D\x82\x82\xB3) + RECT item_rect; + TabCtrl_GetItemRect(hTab, 0, &item_rect); + const int item_height = item_rect.bottom - item_rect.top; + + // tab control\x82̃^\x83u\x95\xAA\x81A\x83_\x83C\x83A\x83\x8D\x83O\x82\xF0\x8F\xAC\x82\xB3\x82\xAD\x82\xB7\x82\xE9 + RECT dlg_rect; + GetWindowRect(m_hWnd, &dlg_rect); + int w = dlg_rect.right - dlg_rect.left; + int h = dlg_rect.bottom - dlg_rect.top - item_height; + SetWindowPos(m_hWnd, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE); + + // \x83^\x83u\x83R\x83\x93\x83g\x83\x8D\x81[\x83\x8B\x82\xF0\x83^\x83u\x95\xAA\x8F\xE3\x82Ɉړ\xAE\x82\xB7\x82\xE9 + RECT tab_rect; + GetWindowRect(hTab, &tab_rect); + + POINT start; + start.x = tab_rect.left; + start.y = tab_rect.top - item_height; + ScreenToClient(m_hWnd, &start); + SetWindowPos(hTab, NULL, start.x, start.y, 0, 0, SWP_NOZORDER | SWP_NOSIZE); + } +#endif + + // \x83c\x83\x8A\x81[\x83R\x83\x93\x83g\x83\x8D\x81[\x83\x8B\x82̈ʒu\x82\xF0\x8C\x88\x82߂\xE9 + RECT tree_rect; + GetWindowRect(hTab, &tree_rect); + int tree_w = TREE_WIDTH; + int tree_h = tree_rect.bottom - tree_rect.top; + POINT pt; + pt.x = tree_rect.left; + pt.y = tree_rect.top; + ScreenToClient(m_hWnd, &pt); + + // \x83c\x83\x8A\x81[\x83R\x83\x93\x83g\x83\x8D\x81[\x83\x8B\x95\xAA\x83_\x83C\x83A\x83\x8D\x83O\x82̃T\x83C\x83Y\x82\xF0\x91傫\x82\xAD\x82\xB7\x82\xE9 + RECT dlg_rect; + GetWindowRect(m_hWnd, &dlg_rect); + int w = dlg_rect.right - dlg_rect.left + TREE_WIDTH + CONTROL_SPACE; + int h = dlg_rect.bottom - dlg_rect.top; + SetWindowPos(m_hWnd, NULL, 0, 0, w, h, SWP_NOZORDER | SWP_NOMOVE); + + // \x83_\x83C\x83A\x83\x8D\x83O\x82̃T\x83C\x83Y\x82\xF0\x91傫\x82\xAD\x82\xB5\x82\xBD\x95\xAA\x81A\x83R\x83\x93\x83g\x83\x8D\x81[\x83\x8B\x82\xF0\x88ړ\xAE\x82\xB7\x82\xE9 + MoveChildWindows(m_hWnd, TREE_WIDTH + CONTROL_SPACE, 0); + + const DWORD dwTreeStyle = + TVS_SHOWSELALWAYS|TVS_TRACKSELECT|TVS_HASLINES|TVS_LINESATROOT|TVS_HASBUTTONS; + m_hWndTV = CreateWindowExW(0, + WC_TREEVIEWW, + L"Tree View", + WS_VISIBLE | WS_CHILD | WS_BORDER | WS_TABSTOP | dwTreeStyle, + pt.x, + pt.y, + tree_w, + tree_h, + m_hWnd, + NULL, + m_hInst, + NULL); + CreateTree(m_hWnd); } Modified: trunk/teraterm/common/tmfc_propdlg.h =================================================================== --- trunk/teraterm/common/tmfc_propdlg.h 2022-06-24 14:04:10 UTC (rev 10015) +++ trunk/teraterm/common/tmfc_propdlg.h 2022-06-24 14:04:22 UTC (rev 10016) @@ -37,26 +37,39 @@ TTCPropSheetDlg(HINSTANCE hInstance, HWND hParentWnd, const wchar_t *uilangfile); virtual ~TTCPropSheetDlg(); INT_PTR DoModal(); - void AddPage(HPROPSHEETPAGE page); + void AddPage(HPROPSHEETPAGE page, const wchar_t *path = NULL); void SetCaption(const wchar_t *caption); + static void SetTreeViewMode(BOOL enable); private: + HWND m_hWnd; + HWND m_hParentWnd; + HINSTANCE m_hInst; + wchar_t *m_UiLanguageFile; + static int CALLBACK PropSheetProc(HWND hWnd, UINT msg, LPARAM lParam); static LRESULT CALLBACK WndProcStatic(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam); - static HINSTANCE ghInstance; static class TTCPropSheetDlg *gTTCPS; LRESULT CALLBACK WndProc(HWND dlg, UINT msg, WPARAM wParam, LPARAM lParam); + LONG_PTR m_OrgProc; + LONG_PTR m_OrgUserData; PROPSHEETHEADERW m_psh; - HWND m_hWnd; - HWND m_hParentWnd; - HINSTANCE m_hInst; - int m_PageCount; - HPROPSHEETPAGE hPsp[9]; + struct TTPropSheetPage { + HPROPSHEETPAGE hPsp; + wchar_t *path; + }; + TTPropSheetPage *m_Page; - LONG_PTR m_OrgProc; - LONG_PTR m_OrgUserData; + // tree control + BOOL m_TreeView; + HWND m_hWndTV; + void AddTreeControl(); + void CreateTree(HWND dlg); + HTREEITEM CreatePath(const wchar_t *path, HTREEITEM hParent, int data); + HTREEITEM GetTreeItem(int nPage, HTREEITEM hParent); - wchar_t *m_UiLanguageFile; + // \x8F\x89\x8A\xFA\x92l + static BOOL m_TreeViewInit; };