Something went wrong. Try again.
Reactos
Something went wrong. Try again.
25 kB · 995 lines
C++
at listview
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996/* * Copyright 2003, 2004, 2005 Martin Fuchs * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */
// // Explorer clone // // pane.cpp // // Martin Fuchs, 23.07.2003 //
#include <precomp.h>
enum IMAGE { IMG_NONE=-1, IMG_FILE=0, IMG_DOCUMENT, IMG_EXECUTABLE, IMG_FOLDER, IMG_OPEN_FOLDER, IMG_FOLDER_PLUS,IMG_OPEN_PLUS, IMG_OPEN_MINUS, IMG_FOLDER_UP, IMG_FOLDER_CUR};
#define IMAGE_WIDTH 16#define IMAGE_HEIGHT 13
static const TCHAR* g_pos_names[COLUMNS] = { TEXT(""), /* symbol */ TEXT("Name"), TEXT("Type"), TEXT("Size"), TEXT("CDate"), TEXT("ADate"), TEXT("MDate"), TEXT("Index/Inode"), TEXT("Links"), TEXT("Attributes"), TEXT("Security"), TEXT("Content")};
static const int g_pos_align[] = { 0, HDF_LEFT, /* Name */ HDF_LEFT, /* Type */ HDF_RIGHT, /* Size */ HDF_LEFT, /* CDate */ HDF_LEFT, /* ADate */ HDF_LEFT, /* MDate */ HDF_LEFT, /* Index */ HDF_RIGHT, /* Links */ HDF_CENTER, /* Attributes */ HDF_LEFT, /* Security */ HDF_LEFT /* Content / Description */};
Pane::Pane(HWND hparent, int id, int id_header, Entry* root, bool treePane, int visible_cols) : super(CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL| LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY, 0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0)), _root(root), _visible_cols(visible_cols), _treePane(treePane){ // insert entries into listbox Entry* entry = _root;
if (entry) insert_entries(entry);
init();
create_header(hparent, id_header);}
Pane::~Pane(){ ImageList_Destroy(_himl);}
LRESULT Pane::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam){ switch(nmsg) { case WM_HSCROLL: set_header(); break;
case WM_SETFOCUS: { FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0);
child->set_focus_pane(this); ListBox_SetSel(_hwnd, TRUE, 1); /*@todo check menu items */ break;}
case WM_KEYDOWN: { FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0);
if (wparam == VK_TAB) { /*@todo SetFocus(g_Globals.hdrivebar) */ child->switch_focus_pane(); } break;} }
return super::WndProc(nmsg, wparam, lparam);}
bool Pane::create_header(HWND hparent, int id){ HWND hwnd = CreateWindow(WC_HEADER, 0, WS_CHILD|WS_VISIBLE|HDS_HORZ/*@todo |HDS_BUTTONS + sort orders*/, 0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0); if (!hwnd) return false;
SetWindowFont(hwnd, GetStockFont(DEFAULT_GUI_FONT), FALSE);
HD_ITEM hdi;
hdi.mask = HDI_TEXT|HDI_WIDTH|HDI_FORMAT;
for(int idx=0; idx<COLUMNS; idx++) { hdi.pszText = (TCHAR*)g_pos_names[idx]; hdi.fmt = HDF_STRING | g_pos_align[idx]; hdi.cxy = _widths[idx]; Header_InsertItem(hwnd, idx, &hdi); }
_hwndHeader = hwnd;
return true;}
void Pane::init(){ _himl = ImageList_LoadBitmap(g_Globals._hInstance, MAKEINTRESOURCE(IDB_IMAGES), 16, 0, RGB(0,255,0));
SetWindowFont(_hwnd, _out_wrkr._hfont, FALSE);
// read the color for compressed files from registry HKEY hkeyExplorer = 0; DWORD len = sizeof(_clrCompressed);
if (RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer) || RegQueryValueEx(hkeyExplorer, TEXT("AltColor"), 0, NULL, (LPBYTE)&_clrCompressed, &len) || len!=sizeof(_clrCompressed)) _clrCompressed = RGB(0,0,255);
if (hkeyExplorer) RegCloseKey(hkeyExplorer);
// calculate column widths _out_wrkr.init_output(_hwnd); calc_widths(true);}
// calculate prefered width for all visible columns
bool Pane::calc_widths(bool anyway){ int col, x, cx, spc=3*_out_wrkr._spaceSize.cx; int entries = ListBox_GetCount(_hwnd); int orgWidths[COLUMNS]; int orgPositions[COLUMNS+1]; HFONT hfontOld; HDC hdc; int cnt;
if (!anyway) { memcpy(orgWidths, _widths, sizeof(orgWidths)); memcpy(orgPositions, _positions, sizeof(orgPositions)); }
for(col=0; col<COLUMNS; col++) _widths[col] = 0;
hdc = GetDC(_hwnd); hfontOld = SelectFont(hdc, _out_wrkr._hfont);
for(cnt=0; cnt<entries; cnt++) { Entry* entry = (Entry*) ListBox_GetItemData(_hwnd, cnt);
DRAWITEMSTRUCT dis;
dis.CtlType = 0; dis.CtlID = 0; dis.itemID = 0; dis.itemAction = 0; dis.itemState = 0; dis.hwndItem = _hwnd; dis.hDC = hdc; dis.rcItem.left = 0; dis.rcItem.top = 0; dis.rcItem.right = 0; dis.rcItem.bottom = 0; /*dis.itemData = 0; */
draw_item(&dis, entry, COLUMNS); }
SelectObject(hdc, hfontOld); ReleaseDC(_hwnd, hdc);
x = 0; for(col=0; col<COLUMNS; col++) { _positions[col] = x; cx = _widths[col];
if (cx) { cx += spc;
if (cx < IMAGE_WIDTH) cx = IMAGE_WIDTH;
_widths[col] = cx; }
x += cx; }
_positions[COLUMNS] = x;
ListBox_SetHorizontalExtent(_hwnd, x);
// no change? if (!memcmp(orgWidths, _widths, sizeof(orgWidths))) return FALSE;
// don't move, if only collapsing an entry if (!anyway && _widths[0]<orgWidths[0] && !memcmp(orgWidths+1, _widths+1, sizeof(orgWidths)-sizeof(int))) { _widths[0] = orgWidths[0]; memcpy(_positions, orgPositions, sizeof(orgPositions));
return FALSE; }
InvalidateRect(_hwnd, 0, TRUE);
return TRUE;}
static void format_date(const FILETIME* ft, TCHAR* buffer, int visible_cols){ SYSTEMTIME systime; FILETIME lft; int len = 0;
*buffer = TEXT('\0');
if (!ft->dwLowDateTime && !ft->dwHighDateTime) return;
if (!FileTimeToLocalFileTime(ft, &lft)) {err: lstrcpy(buffer,TEXT("???")); return;}
if (!FileTimeToSystemTime(&lft, &systime)) goto err;
if (visible_cols & COL_DATE) { len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer, BUFFER_LEN); if (!len) goto err; }
if (visible_cols & COL_TIME) { if (len) buffer[len-1] = ' ';
buffer[len++] = ' ';
if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer+len, BUFFER_LEN-len)) buffer[len] = TEXT('\0'); }}
void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol){ TCHAR buffer[BUFFER_LEN]; DWORD attrs; int visible_cols = _visible_cols; COLORREF bkcolor, textcolor; RECT focusRect = dis->rcItem; enum IMAGE img; int img_pos, cx; int col = 0;
if (entry) { attrs = entry->_data.dwFileAttributes;
if (attrs & FILE_ATTRIBUTE_DIRECTORY) { if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0')) img = IMG_FOLDER_UP; else if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('\0')) img = IMG_FOLDER_CUR; else if ((_treePane && (dis->itemState&ODS_FOCUS))) img = IMG_OPEN_FOLDER; else img = IMG_FOLDER; } else { if (attrs & ATTRIBUTE_EXECUTABLE) img = IMG_EXECUTABLE; else if (entry->_type_name) img = IMG_DOCUMENT; else img = IMG_FILE; } } else { attrs = 0; img = IMG_NONE; }
if (_treePane) { if (entry) { img_pos = dis->rcItem.left + entry->_level*(IMAGE_WIDTH+_out_wrkr._spaceSize.cx);
if (calcWidthCol == -1) { int x; int y = dis->rcItem.top + IMAGE_HEIGHT/2; Entry* up; RECT rt_clip; HRGN hrgn_org = CreateRectRgn(0, 0, 0, 0); HRGN hrgn;
rt_clip.left = dis->rcItem.left; rt_clip.top = dis->rcItem.top; rt_clip.right = dis->rcItem.left+_widths[col]; rt_clip.bottom = dis->rcItem.bottom;
hrgn = CreateRectRgnIndirect(&rt_clip);
if (!GetClipRgn(dis->hDC, hrgn_org)) { DeleteObject(hrgn_org); hrgn_org = 0; }
//HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN)); ExtSelectClipRgn(dis->hDC, hrgn, RGN_AND); DeleteObject(hrgn);
if ((up=entry->_up) != NULL) { MoveToEx(dis->hDC, img_pos-IMAGE_WIDTH/2, y, 0); LineTo(dis->hDC, img_pos-2, y);
x = img_pos - IMAGE_WIDTH/2;
do { x -= IMAGE_WIDTH+_out_wrkr._spaceSize.cx;
if (up->_next) {#ifndef _LEFT_FILES bool following_child = (up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0; // a directory?
if (!following_child) { for(Entry*n=up->_next; n; n=n->_next) if (n->_down) { // any file with NTFS sub-streams? following_child = true; break; } } if (following_child)#endif { MoveToEx(dis->hDC, x, dis->rcItem.top, 0); LineTo(dis->hDC, x, dis->rcItem.bottom); } } } while((up=up->_up) != NULL); }
x = img_pos - IMAGE_WIDTH/2;
MoveToEx(dis->hDC, x, dis->rcItem.top, 0); LineTo(dis->hDC, x, y);
if (entry->_next) {#ifndef _LEFT_FILES bool following_child = (entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0; // a directory?
if (!following_child) { for(Entry*n=entry->_next; n; n=n->_next) if (n->_down) { // any file with NTFS sub-streams? following_child = true; break; } } if (following_child)#endif LineTo(dis->hDC, x, dis->rcItem.bottom); }
if (entry->_down && entry->_expanded) { x += IMAGE_WIDTH + _out_wrkr._spaceSize.cx; MoveToEx(dis->hDC, x, dis->rcItem.top+IMAGE_HEIGHT, 0); LineTo(dis->hDC, x, dis->rcItem.bottom); }
SelectClipRgn(dis->hDC, hrgn_org); if (hrgn_org) DeleteObject(hrgn_org); //SelectObject(dis->hDC, holdPen); } else if (calcWidthCol==col || calcWidthCol==COLUMNS) { int right = img_pos + IMAGE_WIDTH - _out_wrkr._spaceSize.cx;
if (right > _widths[col]) _widths[col] = right; } } else { img_pos = dis->rcItem.left; } } else { img_pos = dis->rcItem.left;
if (calcWidthCol==col || calcWidthCol==COLUMNS) _widths[col] = IMAGE_WIDTH; }
if (calcWidthCol == -1) { focusRect.left = img_pos -2;
if (attrs & FILE_ATTRIBUTE_COMPRESSED) textcolor = _clrCompressed; else textcolor = RGB(0,0,0);
if (dis->itemState & ODS_FOCUS) { textcolor = GetSysColor(COLOR_HIGHLIGHTTEXT); bkcolor = GetSysColor(COLOR_HIGHLIGHT); } else { bkcolor = GetSysColor(COLOR_WINDOW); }
HBRUSH hbrush = CreateSolidBrush(bkcolor); FillRect(dis->hDC, &focusRect, hbrush); DeleteObject(hbrush);
SetBkMode(dis->hDC, TRANSPARENT); SetTextColor(dis->hDC, textcolor);
cx = _widths[col];
if (cx && img!=IMG_NONE) { if (cx > IMAGE_WIDTH) cx = IMAGE_WIDTH;
if (entry->_icon_id > ICID_NONE) g_Globals._icon_cache.get_icon(entry->_icon_id).draw(dis->hDC, img_pos, dis->rcItem.top, cx, GetSystemMetrics(SM_CYSMICON), bkcolor, 0); else ImageList_DrawEx(_himl, img, dis->hDC, img_pos, dis->rcItem.top, cx, IMAGE_HEIGHT, bkcolor, CLR_DEFAULT, ILD_NORMAL); } }
if (!entry) return;
++col;
// output file name if (calcWidthCol == -1) _out_wrkr.output_text(dis, _positions, col, entry->_display_name, 0); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, entry->_display_name); ++col;
// output type/class name if (visible_cols & COL_TYPE) { if (calcWidthCol == -1) _out_wrkr.output_text(dis, _positions, col, entry->_type_name? entry->_type_name: TEXT(""), 0); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, entry->_type_name? entry->_type_name: TEXT("")); } ++col;
// display file size if (visible_cols & COL_SIZE) { ULONGLONG size = ((ULONGLONG)entry->_data.nFileSizeHigh << 32) | entry->_data.nFileSizeLow;
_stprintf(buffer, TEXT("%") LONGLONGARG TEXT("d"), size);
if (calcWidthCol == -1) _out_wrkr.output_number(dis, _positions, col, buffer); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, buffer); ///@todo not in every case time enough } ++col;
// display file date if (visible_cols & (COL_DATE|COL_TIME)) { format_date(&entry->_data.ftCreationTime, buffer, visible_cols); if (calcWidthCol == -1) _out_wrkr.output_text(dis, _positions, col, buffer, 0); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, buffer); ++col;
format_date(&entry->_data.ftLastAccessTime, buffer, visible_cols); if (calcWidthCol == -1) _out_wrkr.output_text(dis,_positions, col, buffer, 0); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, buffer); ++col;
format_date(&entry->_data.ftLastWriteTime, buffer, visible_cols); if (calcWidthCol == -1) _out_wrkr.output_text(dis, _positions, col, buffer, 0); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, buffer); ++col; } else col += 3;
if (entry->_bhfi_valid) { ULONGLONG index = ((ULONGLONG)entry->_bhfi.nFileIndexHigh << 32) | entry->_bhfi.nFileIndexLow;
if (visible_cols & COL_INDEX) { _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("X"), index);
if (calcWidthCol == -1) _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, buffer);
++col; }
if (visible_cols & COL_LINKS) { wsprintf(buffer, TEXT("%d"), entry->_bhfi.nNumberOfLinks);
if (calcWidthCol == -1) _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, buffer);
++col; } } else col += 2;
// show file attributes if (visible_cols & COL_ATTRIBUTES) { lstrcpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t \t \t \t "));
if (attrs & FILE_ATTRIBUTE_NORMAL) buffer[ 0] = 'N'; else { if (attrs & FILE_ATTRIBUTE_READONLY) buffer[ 2] = 'R'; if (attrs & FILE_ATTRIBUTE_HIDDEN) buffer[ 4] = 'H'; if (attrs & FILE_ATTRIBUTE_SYSTEM) buffer[ 6] = 'S'; if (attrs & FILE_ATTRIBUTE_ARCHIVE) buffer[ 8] = 'A'; if (attrs & FILE_ATTRIBUTE_COMPRESSED) buffer[10] = 'C'; if (attrs & FILE_ATTRIBUTE_DIRECTORY) buffer[12] = 'D'; if (attrs & FILE_ATTRIBUTE_ENCRYPTED) buffer[14] = 'E'; if (attrs & FILE_ATTRIBUTE_TEMPORARY) buffer[16] = 'T'; if (attrs & FILE_ATTRIBUTE_SPARSE_FILE) buffer[18] = 'P'; if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) buffer[20] = 'Q'; if (attrs & FILE_ATTRIBUTE_OFFLINE) buffer[22] = 'O'; if (attrs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) buffer[24] = 'X'; if (attrs & ATTRIBUTE_EXECUTABLE) buffer[26] = 'x'; if (attrs & ATTRIBUTE_SYMBOLIC_LINK) buffer[28] = 'L'; }
if (calcWidthCol == -1) _out_wrkr.output_tabbed_text(dis, _positions, col, buffer); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_tabbed_width(dis, col, buffer); } ++col;
/*TODO if (flags.security) { DWORD rights = get_access_mask();
tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t "));
if (rights & FILE_READ_DATA) buffer[ 0] = 'R'; if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W'; if (rights & FILE_APPEND_DATA) buffer[ 4] = 'A'; if (rights & FILE_READ_EA) {buffer[6] = 'entry'; buffer[ 7] = 'R';} if (rights & FILE_WRITE_EA) {buffer[9] = 'entry'; buffer[10] = 'W';} if (rights & FILE_EXECUTE) buffer[12] = 'X'; if (rights & FILE_DELETE_CHILD) buffer[14] = 'D'; if (rights & FILE_READ_ATTRIBUTES) {buffer[16] = 'a'; buffer[17] = 'R';} if (rights & FILE_WRITE_ATTRIBUTES) {buffer[19] = 'a'; buffer[20] = 'W';} if (rights & WRITE_DAC) buffer[22] = 'C'; if (rights & WRITE_OWNER) buffer[24] = 'O'; if (rights & SYNCHRONIZE) buffer[26] = 'S';
output_text(dis, col++, buffer, DT_LEFT, 3, psize); }
if (flags.description) { get_description(buffer); output_text(dis, col++, buffer, 0, psize); }*/ ++col;
// output content / symbolic link target / comment if (visible_cols & COL_CONTENT) { if (calcWidthCol == -1) _out_wrkr.output_text(dis, _positions, col, entry->_content? entry->_content: TEXT(""), 0); else if (calcWidthCol==col || calcWidthCol==COLUMNS) calc_width(dis, col, entry->_content? entry->_content: TEXT("")); }}
void Pane::calc_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str){ RECT rt = {0, 0, 0, 0};
DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX);
if (rt.right > _widths[col]) _widths[col] = rt.right;}
void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str){ RECT rt = {0, 0, 0, 0};
/* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8));
if (rt.right > _widths[col]) _widths[col] = rt.right;}
// insert listbox entries after index idx
int Pane::insert_entries(Entry* dir, int idx){ Entry* entry = dir;
if (!entry) return idx;
for(; entry; entry=entry->_next) {#ifndef _LEFT_FILES if (_treePane && !(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && // not a directory? !entry->_down) // not a file with NTFS sub-streams? continue;#endif
// don't display entries "." and ".." in the left pane if (_treePane && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && entry->_data.cFileName[0]==TEXT('.')) if (entry->_data.cFileName[1]==TEXT('\0') || (entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0'))) continue;
if (idx != -1) ++idx;
ListBox_InsertItemData(_hwnd, idx, entry);
if (_treePane && entry->_expanded) idx = insert_entries(entry->_down, idx); }
return idx;}
void Pane::set_header(){ HD_ITEM item; int scroll_pos = GetScrollPos(_hwnd, SB_HORZ); int i=0, x=0;
item.mask = HDI_WIDTH; item.cxy = 0;
for(; i<COLUMNS; i++) { if (x + _widths[i] >= scroll_pos) break;
x += _widths[i]; Header_SetItem(_hwndHeader, i, &item); }
if (i < COLUMNS) { x += _widths[i]; item.cxy = x - scroll_pos; Header_SetItem(_hwndHeader, i++, &item);
for(; i<COLUMNS; i++) { item.cxy = _widths[i]; x += _widths[i]; Header_SetItem(_hwndHeader, i, &item); } }}
// calculate one prefered column width
void Pane::calc_single_width(int col){ HFONT hfontOld; int x, cx; int cnt; HDC hdc;
int entries = ListBox_GetCount(_hwnd);
_widths[col] = 0;
hdc = GetDC(_hwnd); hfontOld = SelectFont(hdc, _out_wrkr._hfont);
for(cnt=0; cnt<entries; cnt++) { Entry* entry = (Entry*) ListBox_GetItemData(_hwnd, cnt);
DRAWITEMSTRUCT dis;
dis.CtlType = 0; dis.CtlID = 0; dis.itemID = 0; dis.itemAction = 0; dis.itemState = 0; dis.hwndItem = _hwnd; dis.hDC = hdc; dis.rcItem.left = 0; dis.rcItem.top = 0; dis.rcItem.right = 0; dis.rcItem.bottom = 0; /*dis.itemData = 0; */
draw_item(&dis, entry, col); }
SelectObject(hdc, hfontOld); ReleaseDC(_hwnd, hdc);
cx = _widths[col];
if (cx) { cx += 3*_out_wrkr._spaceSize.cx;
if (cx < IMAGE_WIDTH) cx = IMAGE_WIDTH; }
_widths[col] = cx;
x = _positions[col] + cx;
for(; col<COLUMNS; col++) { _positions[col+1] = x; x += _widths[col]; }
ListBox_SetHorizontalExtent(_hwnd, x);}
int Pane::Notify(int id, NMHDR* pnmh){ switch(pnmh->code) { case HDN_TRACK: case HDN_ENDTRACK: { HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; int idx = phdn->iItem; int dx = phdn->pitem->cxy - _widths[idx]; int i;
ClientRect clnt(_hwnd);
// move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB) Header_SetItem(_hwndHeader, idx, phdn->pitem);
_widths[idx] += dx;
for(i=idx; ++i<=COLUMNS; ) _positions[i] += dx;
{ int scroll_pos = GetScrollPos(_hwnd, SB_HORZ); RECT rt_scr; RECT rt_clip;
rt_scr.left = _positions[idx+1]-scroll_pos; rt_scr.top = 0; rt_scr.right = clnt.right; rt_scr.bottom = clnt.bottom;
rt_clip.left = _positions[idx]-scroll_pos; rt_clip.top = 0; rt_clip.right = clnt.right; rt_clip.bottom = clnt.bottom;
if (rt_scr.left < 0) rt_scr.left = 0; if (rt_clip.left < 0) rt_clip.left = 0;
ScrollWindowEx(_hwnd, dx, 0, &rt_scr, &rt_clip, 0, 0, SW_INVALIDATE);
rt_clip.right = _positions[idx+1]; RedrawWindow(_hwnd, &rt_clip, 0, RDW_INVALIDATE|RDW_UPDATENOW);
if (pnmh->code == HDN_ENDTRACK) { ListBox_SetHorizontalExtent(_hwnd, _positions[COLUMNS]);
if (GetScrollPos(_hwnd, SB_HORZ) != scroll_pos) set_header(); } }
return 0; }
case HDN_DIVIDERDBLCLICK: { HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; HD_ITEM item;
calc_single_width(phdn->iItem); item.mask = HDI_WIDTH; item.cxy = _widths[phdn->iItem];
Header_SetItem(_hwndHeader, phdn->iItem, &item); InvalidateRect(_hwnd, 0, TRUE); break;}
default: return super::Notify(id, pnmh); }
return 0;}
OutputWorker::OutputWorker(){ _hfont = CreateFont(-MulDiv(8,GetDeviceCaps(WindowCanvas(0),LOGPIXELSY),72), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, TEXT("MS Sans Serif"));}
void OutputWorker::init_output(HWND hwnd){ TCHAR b[16];
WindowCanvas canvas(hwnd);
if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, TEXT("1000"), 0, b, 16) > 4) _num_sep = b[1]; else _num_sep = TEXT('.');
FontSelection font(canvas, _hfont); GetTextExtentPoint32(canvas, TEXT(" "), 1, &_spaceSize);}
void OutputWorker::output_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str, DWORD flags){ int x = dis->rcItem.left; RECT rt;
rt.left = x+positions[col]+_spaceSize.cx; rt.top = dis->rcItem.top; rt.right = x+positions[col+1]-_spaceSize.cx; rt.bottom = dis->rcItem.bottom;
DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|flags);}
void OutputWorker::output_tabbed_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str){ int x = dis->rcItem.left; RECT rt;
rt.left = x+positions[col]+_spaceSize.cx; rt.top = dis->rcItem.top; rt.right = x+positions[col+1]-_spaceSize.cx; rt.bottom = dis->rcItem.bottom;
/* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8));}
void OutputWorker::output_number(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str){ int x = dis->rcItem.left; RECT rt; LPCTSTR s = str; TCHAR b[128]; LPTSTR d = b; int pos;
rt.left = x+positions[col]+_spaceSize.cx; rt.top = dis->rcItem.top; rt.right = x+positions[col+1]-_spaceSize.cx; rt.bottom = dis->rcItem.bottom;
if (*s) *d++ = *s++;
// insert number separator characters pos = lstrlen(s) % 3;
while(*s) if (pos--) *d++ = *s++; else { *d++ = _num_sep; pos = 3; }
DrawText(dis->hDC, b, d-b, &rt, DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS);}
BOOL Pane::command(UINT cmd){ switch(cmd) { case ID_VIEW_NAME: if (_visible_cols) { _visible_cols = 0; calc_widths(true); set_header(); InvalidateRect(_hwnd, 0, TRUE); MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); if (menu_info) { CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND|MF_CHECKED); CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND); CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); } } break;
case ID_VIEW_ALL_ATTRIBUTES: if (_visible_cols != COL_ALL) { _visible_cols = COL_ALL; calc_widths(true); set_header(); InvalidateRect(_hwnd, 0, TRUE); MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); if (menu_info) { CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND); CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND|MF_CHECKED); CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); } } break;
case ID_PREFERED_SIZES: { calc_widths(true); set_header(); InvalidateRect(_hwnd, 0, TRUE); break;}
/*@todo more command ids... */
default: return FALSE; }
return TRUE;}
MainFrameBase* Pane::get_frame(){ HWND owner = GetParent(_hwnd);
return (MainFrameBase*)owner;}