00001 /* 00002 * Copyright 2003, 2004, 2005 Martin Fuchs 00003 * 00004 * This library is free software; you can redistribute it and/or 00005 * modify it under the terms of the GNU Lesser General Public 00006 * License as published by the Free Software Foundation; either 00007 * version 2.1 of the License, or (at your option) any later version. 00008 * 00009 * This library is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00012 * Lesser General Public License for more details. 00013 * 00014 * You should have received a copy of the GNU Lesser General Public 00015 * License along with this library; if not, write to the Free Software 00016 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 00020 // 00021 // Explorer clone 00022 // 00023 // pane.cpp 00024 // 00025 // Martin Fuchs, 23.07.2003 00026 // 00027 00028 00029 #include <precomp.h> 00030 00031 #include "../resource.h" 00032 00033 00034 enum IMAGE { 00035 IMG_NONE=-1, IMG_FILE=0, IMG_DOCUMENT, IMG_EXECUTABLE, 00036 IMG_FOLDER, IMG_OPEN_FOLDER, IMG_FOLDER_PLUS,IMG_OPEN_PLUS, IMG_OPEN_MINUS, 00037 IMG_FOLDER_UP, IMG_FOLDER_CUR 00038 }; 00039 00040 00041 #define IMAGE_WIDTH 16 00042 #define IMAGE_HEIGHT 13 00043 00044 00045 static const LPTSTR g_pos_names[COLUMNS] = { 00046 TEXT(""), /* symbol */ 00047 TEXT("Name"), 00048 TEXT("Type"), 00049 TEXT("Size"), 00050 TEXT("CDate"), 00051 TEXT("ADate"), 00052 TEXT("MDate"), 00053 TEXT("Index/Inode"), 00054 TEXT("Links"), 00055 TEXT("Attributes"), 00056 TEXT("Security"), 00057 TEXT("Content") 00058 }; 00059 00060 static const int g_pos_align[] = { 00061 0, 00062 HDF_LEFT, /* Name */ 00063 HDF_LEFT, /* Type */ 00064 HDF_RIGHT, /* Size */ 00065 HDF_LEFT, /* CDate */ 00066 HDF_LEFT, /* ADate */ 00067 HDF_LEFT, /* MDate */ 00068 HDF_LEFT, /* Index */ 00069 HDF_RIGHT, /* Links */ 00070 HDF_CENTER, /* Attributes */ 00071 HDF_LEFT, /* Security */ 00072 HDF_LEFT /* Content / Description */ 00073 }; 00074 00075 00076 Pane::Pane(HWND hparent, int id, int id_header, Entry* root, bool treePane, int visible_cols) 00077 : super(CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD|WS_VISIBLE|WS_HSCROLL|WS_VSCROLL| 00078 LBS_DISABLENOSCROLL|LBS_NOINTEGRALHEIGHT|LBS_OWNERDRAWFIXED|LBS_NOTIFY, 00079 0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0)), 00080 _root(root), 00081 _visible_cols(visible_cols), 00082 _treePane(treePane) 00083 { 00084 // insert entries into listbox 00085 Entry* entry = _root; 00086 00087 if (entry) 00088 insert_entries(entry); 00089 00090 init(); 00091 00092 create_header(hparent, id_header); 00093 } 00094 00095 Pane::~Pane() 00096 { 00097 ImageList_Destroy(_himl); 00098 } 00099 00100 00101 LRESULT Pane::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00102 { 00103 switch(nmsg) { 00104 case WM_HSCROLL: 00105 set_header(); 00106 break; 00107 00108 case WM_SETFOCUS: { 00109 FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0); 00110 00111 child->set_focus_pane(this); 00112 ListBox_SetSel(_hwnd, TRUE, 1); 00113 /*@todo check menu items */ 00114 break;} 00115 00116 case WM_KEYDOWN: { 00117 FileChildWindow* child = (FileChildWindow*) SendMessage(GetParent(_hwnd), PM_GET_FILEWND_PTR, 0, 0); 00118 00119 if (wparam == VK_TAB) { 00120 /*@todo SetFocus(g_Globals.hdrivebar) */ 00121 child->switch_focus_pane(); 00122 } 00123 break;} 00124 } 00125 00126 return super::WndProc(nmsg, wparam, lparam); 00127 } 00128 00129 00130 bool Pane::create_header(HWND hparent, int id) 00131 { 00132 HWND hwnd = CreateWindow(WC_HEADER, 0, WS_CHILD|WS_VISIBLE|HDS_HORZ/*@todo |HDS_BUTTONS + sort orders*/, 00133 0, 0, 0, 0, hparent, (HMENU)id, g_Globals._hInstance, 0); 00134 if (!hwnd) 00135 return false; 00136 00137 SetWindowFont(hwnd, GetStockFont(DEFAULT_GUI_FONT), FALSE); 00138 00139 HD_ITEM hdi; 00140 00141 hdi.mask = HDI_TEXT|HDI_WIDTH|HDI_FORMAT; 00142 00143 for(int idx=0; idx<COLUMNS; idx++) { 00144 hdi.pszText = g_pos_names[idx]; 00145 hdi.fmt = HDF_STRING | g_pos_align[idx]; 00146 hdi.cxy = _widths[idx]; 00147 Header_InsertItem(hwnd, idx, &hdi); 00148 } 00149 00150 _hwndHeader = hwnd; 00151 00152 return true; 00153 } 00154 00155 00156 void Pane::init() 00157 { 00158 _himl = ImageList_LoadBitmap(g_Globals._hInstance, MAKEINTRESOURCE(IDB_IMAGES), 16, 0, RGB(0,255,0)); 00159 00160 SetWindowFont(_hwnd, _out_wrkr._hfont, FALSE); 00161 00162 // read the color for compressed files from registry 00163 HKEY hkeyExplorer = 0; 00164 DWORD len = sizeof(_clrCompressed); 00165 00166 if (RegOpenKey(HKEY_CURRENT_USER, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer) || 00167 RegQueryValueEx(hkeyExplorer, TEXT("AltColor"), 0, NULL, (LPBYTE)&_clrCompressed, &len) || len!=sizeof(_clrCompressed)) 00168 _clrCompressed = RGB(0,0,255); 00169 00170 if (hkeyExplorer) 00171 RegCloseKey(hkeyExplorer); 00172 00173 // calculate column widths 00174 _out_wrkr.init_output(_hwnd); 00175 calc_widths(true); 00176 } 00177 00178 00179 // calculate prefered width for all visible columns 00180 00181 bool Pane::calc_widths(bool anyway) 00182 { 00183 int col, x, cx, spc=3*_out_wrkr._spaceSize.cx; 00184 int entries = ListBox_GetCount(_hwnd); 00185 int orgWidths[COLUMNS]; 00186 int orgPositions[COLUMNS+1]; 00187 HFONT hfontOld; 00188 HDC hdc; 00189 int cnt; 00190 00191 if (!anyway) { 00192 memcpy(orgWidths, _widths, sizeof(orgWidths)); 00193 memcpy(orgPositions, _positions, sizeof(orgPositions)); 00194 } 00195 00196 for(col=0; col<COLUMNS; col++) 00197 _widths[col] = 0; 00198 00199 hdc = GetDC(_hwnd); 00200 hfontOld = SelectFont(hdc, _out_wrkr._hfont); 00201 00202 for(cnt=0; cnt<entries; cnt++) { 00203 Entry* entry = (Entry*) ListBox_GetItemData(_hwnd, cnt); 00204 00205 DRAWITEMSTRUCT dis; 00206 00207 dis.CtlType = 0; 00208 dis.CtlID = 0; 00209 dis.itemID = 0; 00210 dis.itemAction = 0; 00211 dis.itemState = 0; 00212 dis.hwndItem = _hwnd; 00213 dis.hDC = hdc; 00214 dis.rcItem.left = 0; 00215 dis.rcItem.top = 0; 00216 dis.rcItem.right = 0; 00217 dis.rcItem.bottom = 0; 00218 /*dis.itemData = 0; */ 00219 00220 draw_item(&dis, entry, COLUMNS); 00221 } 00222 00223 SelectObject(hdc, hfontOld); 00224 ReleaseDC(_hwnd, hdc); 00225 00226 x = 0; 00227 for(col=0; col<COLUMNS; col++) { 00228 _positions[col] = x; 00229 cx = _widths[col]; 00230 00231 if (cx) { 00232 cx += spc; 00233 00234 if (cx < IMAGE_WIDTH) 00235 cx = IMAGE_WIDTH; 00236 00237 _widths[col] = cx; 00238 } 00239 00240 x += cx; 00241 } 00242 00243 _positions[COLUMNS] = x; 00244 00245 ListBox_SetHorizontalExtent(_hwnd, x); 00246 00247 // no change? 00248 if (!memcmp(orgWidths, _widths, sizeof(orgWidths))) 00249 return FALSE; 00250 00251 // don't move, if only collapsing an entry 00252 if (!anyway && _widths[0]<orgWidths[0] && 00253 !memcmp(orgWidths+1, _widths+1, sizeof(orgWidths)-sizeof(int))) { 00254 _widths[0] = orgWidths[0]; 00255 memcpy(_positions, orgPositions, sizeof(orgPositions)); 00256 00257 return FALSE; 00258 } 00259 00260 InvalidateRect(_hwnd, 0, TRUE); 00261 00262 return TRUE; 00263 } 00264 00265 00266 static void format_date(const FILETIME* ft, TCHAR* buffer, int visible_cols) 00267 { 00268 SYSTEMTIME systime; 00269 FILETIME lft; 00270 int len = 0; 00271 00272 *buffer = TEXT('\0'); 00273 00274 if (!ft->dwLowDateTime && !ft->dwHighDateTime) 00275 return; 00276 00277 if (!FileTimeToLocalFileTime(ft, &lft)) 00278 {err: lstrcpy(buffer,TEXT("???")); return;} 00279 00280 if (!FileTimeToSystemTime(&lft, &systime)) 00281 goto err; 00282 00283 if (visible_cols & COL_DATE) { 00284 len = GetDateFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer, BUFFER_LEN); 00285 if (!len) 00286 goto err; 00287 } 00288 00289 if (visible_cols & COL_TIME) { 00290 if (len) 00291 buffer[len-1] = ' '; 00292 00293 buffer[len++] = ' '; 00294 00295 if (!GetTimeFormat(LOCALE_USER_DEFAULT, 0, &systime, 0, buffer+len, BUFFER_LEN-len)) 00296 buffer[len] = TEXT('\0'); 00297 } 00298 } 00299 00300 00301 void Pane::draw_item(LPDRAWITEMSTRUCT dis, Entry* entry, int calcWidthCol) 00302 { 00303 TCHAR buffer[BUFFER_LEN]; 00304 DWORD attrs; 00305 int visible_cols = _visible_cols; 00306 COLORREF bkcolor, textcolor; 00307 RECT focusRect = dis->rcItem; 00308 enum IMAGE img; 00309 int img_pos, cx; 00310 int col = 0; 00311 00312 if (entry) { 00313 attrs = entry->_data.dwFileAttributes; 00314 00315 if (attrs & FILE_ATTRIBUTE_DIRECTORY) { 00316 if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('.') 00317 && entry->_data.cFileName[2]==TEXT('\0')) 00318 img = IMG_FOLDER_UP; 00319 else if (entry->_data.cFileName[0]==TEXT('.') && entry->_data.cFileName[1]==TEXT('\0')) 00320 img = IMG_FOLDER_CUR; 00321 else if ((_treePane && (dis->itemState&ODS_FOCUS))) 00322 img = IMG_OPEN_FOLDER; 00323 else 00324 img = IMG_FOLDER; 00325 } else { 00326 if (attrs & ATTRIBUTE_EXECUTABLE) 00327 img = IMG_EXECUTABLE; 00328 else if (entry->_type_name) 00329 img = IMG_DOCUMENT; 00330 else 00331 img = IMG_FILE; 00332 } 00333 } else { 00334 attrs = 0; 00335 img = IMG_NONE; 00336 } 00337 00338 if (_treePane) { 00339 if (entry) { 00340 img_pos = dis->rcItem.left + entry->_level*(IMAGE_WIDTH+_out_wrkr._spaceSize.cx); 00341 00342 if (calcWidthCol == -1) { 00343 int x; 00344 int y = dis->rcItem.top + IMAGE_HEIGHT/2; 00345 Entry* up; 00346 RECT rt_clip; 00347 HRGN hrgn_org = CreateRectRgn(0, 0, 0, 0); 00348 HRGN hrgn; 00349 00350 rt_clip.left = dis->rcItem.left; 00351 rt_clip.top = dis->rcItem.top; 00352 rt_clip.right = dis->rcItem.left+_widths[col]; 00353 rt_clip.bottom = dis->rcItem.bottom; 00354 00355 hrgn = CreateRectRgnIndirect(&rt_clip); 00356 00357 if (!GetClipRgn(dis->hDC, hrgn_org)) { 00358 DeleteObject(hrgn_org); 00359 hrgn_org = 0; 00360 } 00361 00362 //HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN)); 00363 ExtSelectClipRgn(dis->hDC, hrgn, RGN_AND); 00364 DeleteObject(hrgn); 00365 00366 if ((up=entry->_up) != NULL) { 00367 MoveToEx(dis->hDC, img_pos-IMAGE_WIDTH/2, y, 0); 00368 LineTo(dis->hDC, img_pos-2, y); 00369 00370 x = img_pos - IMAGE_WIDTH/2; 00371 00372 do { 00373 x -= IMAGE_WIDTH+_out_wrkr._spaceSize.cx; 00374 00375 if (up->_next) { 00376 #ifndef _LEFT_FILES 00377 bool following_child = (up->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0; // a directory? 00378 00379 if (!following_child) { 00380 for(Entry*n=up->_next; n; n=n->_next) 00381 if (n->_down) { // any file with NTFS sub-streams? 00382 following_child = true; 00383 break; 00384 } 00385 } 00386 00387 if (following_child) 00388 #endif 00389 { 00390 MoveToEx(dis->hDC, x, dis->rcItem.top, 0); 00391 LineTo(dis->hDC, x, dis->rcItem.bottom); 00392 } 00393 } 00394 } while((up=up->_up) != NULL); 00395 } 00396 00397 x = img_pos - IMAGE_WIDTH/2; 00398 00399 MoveToEx(dis->hDC, x, dis->rcItem.top, 0); 00400 LineTo(dis->hDC, x, y); 00401 00402 if (entry->_next) { 00403 #ifndef _LEFT_FILES 00404 bool following_child = (entry->_next->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY)!=0; // a directory? 00405 00406 if (!following_child) { 00407 for(Entry*n=entry->_next; n; n=n->_next) 00408 if (n->_down) { // any file with NTFS sub-streams? 00409 following_child = true; 00410 break; 00411 } 00412 } 00413 00414 if (following_child) 00415 #endif 00416 LineTo(dis->hDC, x, dis->rcItem.bottom); 00417 } 00418 00419 if (entry->_down && entry->_expanded) { 00420 x += IMAGE_WIDTH + _out_wrkr._spaceSize.cx; 00421 MoveToEx(dis->hDC, x, dis->rcItem.top+IMAGE_HEIGHT, 0); 00422 LineTo(dis->hDC, x, dis->rcItem.bottom); 00423 } 00424 00425 SelectClipRgn(dis->hDC, hrgn_org); 00426 if (hrgn_org) DeleteObject(hrgn_org); 00427 //SelectObject(dis->hDC, holdPen); 00428 } else if (calcWidthCol==col || calcWidthCol==COLUMNS) { 00429 int right = img_pos + IMAGE_WIDTH - _out_wrkr._spaceSize.cx; 00430 00431 if (right > _widths[col]) 00432 _widths[col] = right; 00433 } 00434 } else { 00435 img_pos = dis->rcItem.left; 00436 } 00437 } else { 00438 img_pos = dis->rcItem.left; 00439 00440 if (calcWidthCol==col || calcWidthCol==COLUMNS) 00441 _widths[col] = IMAGE_WIDTH; 00442 } 00443 00444 if (calcWidthCol == -1) { 00445 focusRect.left = img_pos -2; 00446 00447 if (attrs & FILE_ATTRIBUTE_COMPRESSED) 00448 textcolor = _clrCompressed; 00449 else 00450 textcolor = RGB(0,0,0); 00451 00452 if (dis->itemState & ODS_FOCUS) { 00453 textcolor = GetSysColor(COLOR_HIGHLIGHTTEXT); 00454 bkcolor = GetSysColor(COLOR_HIGHLIGHT); 00455 } else { 00456 bkcolor = GetSysColor(COLOR_WINDOW); 00457 } 00458 00459 HBRUSH hbrush = CreateSolidBrush(bkcolor); 00460 FillRect(dis->hDC, &focusRect, hbrush); 00461 DeleteObject(hbrush); 00462 00463 SetBkMode(dis->hDC, TRANSPARENT); 00464 SetTextColor(dis->hDC, textcolor); 00465 00466 cx = _widths[col]; 00467 00468 if (cx && img!=IMG_NONE) { 00469 if (cx > IMAGE_WIDTH) 00470 cx = IMAGE_WIDTH; 00471 00472 if (entry->_icon_id > ICID_NONE) 00473 g_Globals._icon_cache.get_icon(entry->_icon_id).draw(dis->hDC, img_pos, dis->rcItem.top, cx, GetSystemMetrics(SM_CYSMICON), bkcolor, 0); 00474 else 00475 ImageList_DrawEx(_himl, img, dis->hDC, 00476 img_pos, dis->rcItem.top, cx, 00477 IMAGE_HEIGHT, bkcolor, CLR_DEFAULT, ILD_NORMAL); 00478 } 00479 } 00480 00481 if (!entry) 00482 return; 00483 00484 ++col; 00485 00486 // output file name 00487 if (calcWidthCol == -1) 00488 _out_wrkr.output_text(dis, _positions, col, entry->_display_name, 0); 00489 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00490 calc_width(dis, col, entry->_display_name); 00491 ++col; 00492 00493 // output type/class name 00494 if (visible_cols & COL_TYPE) { 00495 if (calcWidthCol == -1) 00496 _out_wrkr.output_text(dis, _positions, col, entry->_type_name? entry->_type_name: TEXT(""), 0); 00497 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00498 calc_width(dis, col, entry->_type_name? entry->_type_name: TEXT("")); 00499 } 00500 ++col; 00501 00502 // display file size 00503 if (visible_cols & COL_SIZE) { 00504 ULONGLONG size = ((ULONGLONG)entry->_data.nFileSizeHigh << 32) | entry->_data.nFileSizeLow; 00505 00506 _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("d"), size); 00507 00508 if (calcWidthCol == -1) 00509 _out_wrkr.output_number(dis, _positions, col, buffer); 00510 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00511 calc_width(dis, col, buffer); ///@todo not in every case time enough 00512 } 00513 ++col; 00514 00515 // display file date 00516 if (visible_cols & (COL_DATE|COL_TIME)) { 00517 format_date(&entry->_data.ftCreationTime, buffer, visible_cols); 00518 if (calcWidthCol == -1) 00519 _out_wrkr.output_text(dis, _positions, col, buffer, 0); 00520 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00521 calc_width(dis, col, buffer); 00522 ++col; 00523 00524 format_date(&entry->_data.ftLastAccessTime, buffer, visible_cols); 00525 if (calcWidthCol == -1) 00526 _out_wrkr.output_text(dis,_positions, col, buffer, 0); 00527 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00528 calc_width(dis, col, buffer); 00529 ++col; 00530 00531 format_date(&entry->_data.ftLastWriteTime, buffer, visible_cols); 00532 if (calcWidthCol == -1) 00533 _out_wrkr.output_text(dis, _positions, col, buffer, 0); 00534 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00535 calc_width(dis, col, buffer); 00536 ++col; 00537 } else 00538 col += 3; 00539 00540 if (entry->_bhfi_valid) { 00541 ULONGLONG index = ((ULONGLONG)entry->_bhfi.nFileIndexHigh << 32) | entry->_bhfi.nFileIndexLow; 00542 00543 if (visible_cols & COL_INDEX) { 00544 _stprintf(buffer, TEXT("%") LONGLONGARG TEXT("X"), index); 00545 00546 if (calcWidthCol == -1) 00547 _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT); 00548 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00549 calc_width(dis, col, buffer); 00550 00551 ++col; 00552 } 00553 00554 if (visible_cols & COL_LINKS) { 00555 wsprintf(buffer, TEXT("%d"), entry->_bhfi.nNumberOfLinks); 00556 00557 if (calcWidthCol == -1) 00558 _out_wrkr.output_text(dis, _positions, col, buffer, DT_RIGHT); 00559 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00560 calc_width(dis, col, buffer); 00561 00562 ++col; 00563 } 00564 } else 00565 col += 2; 00566 00567 // show file attributes 00568 if (visible_cols & COL_ATTRIBUTES) { 00569 lstrcpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t \t \t \t ")); 00570 00571 if (attrs & FILE_ATTRIBUTE_NORMAL) buffer[ 0] = 'N'; 00572 else { 00573 if (attrs & FILE_ATTRIBUTE_READONLY) buffer[ 2] = 'R'; 00574 if (attrs & FILE_ATTRIBUTE_HIDDEN) buffer[ 4] = 'H'; 00575 if (attrs & FILE_ATTRIBUTE_SYSTEM) buffer[ 6] = 'S'; 00576 if (attrs & FILE_ATTRIBUTE_ARCHIVE) buffer[ 8] = 'A'; 00577 if (attrs & FILE_ATTRIBUTE_COMPRESSED) buffer[10] = 'C'; 00578 if (attrs & FILE_ATTRIBUTE_DIRECTORY) buffer[12] = 'D'; 00579 if (attrs & FILE_ATTRIBUTE_ENCRYPTED) buffer[14] = 'E'; 00580 if (attrs & FILE_ATTRIBUTE_TEMPORARY) buffer[16] = 'T'; 00581 if (attrs & FILE_ATTRIBUTE_SPARSE_FILE) buffer[18] = 'P'; 00582 if (attrs & FILE_ATTRIBUTE_REPARSE_POINT) buffer[20] = 'Q'; 00583 if (attrs & FILE_ATTRIBUTE_OFFLINE) buffer[22] = 'O'; 00584 if (attrs & FILE_ATTRIBUTE_NOT_CONTENT_INDEXED) buffer[24] = 'X'; 00585 if (attrs & ATTRIBUTE_EXECUTABLE) buffer[26] = 'x'; 00586 if (attrs & ATTRIBUTE_SYMBOLIC_LINK) buffer[28] = 'L'; 00587 } 00588 00589 if (calcWidthCol == -1) 00590 _out_wrkr.output_tabbed_text(dis, _positions, col, buffer); 00591 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00592 calc_tabbed_width(dis, col, buffer); 00593 } 00594 ++col; 00595 00596 /*TODO 00597 if (flags.security) { 00598 DWORD rights = get_access_mask(); 00599 00600 tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t ")); 00601 00602 if (rights & FILE_READ_DATA) buffer[ 0] = 'R'; 00603 if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W'; 00604 if (rights & FILE_APPEND_DATA) buffer[ 4] = 'A'; 00605 if (rights & FILE_READ_EA) {buffer[6] = 'entry'; buffer[ 7] = 'R';} 00606 if (rights & FILE_WRITE_EA) {buffer[9] = 'entry'; buffer[10] = 'W';} 00607 if (rights & FILE_EXECUTE) buffer[12] = 'X'; 00608 if (rights & FILE_DELETE_CHILD) buffer[14] = 'D'; 00609 if (rights & FILE_READ_ATTRIBUTES) {buffer[16] = 'a'; buffer[17] = 'R';} 00610 if (rights & FILE_WRITE_ATTRIBUTES) {buffer[19] = 'a'; buffer[20] = 'W';} 00611 if (rights & WRITE_DAC) buffer[22] = 'C'; 00612 if (rights & WRITE_OWNER) buffer[24] = 'O'; 00613 if (rights & SYNCHRONIZE) buffer[26] = 'S'; 00614 00615 output_text(dis, col++, buffer, DT_LEFT, 3, psize); 00616 } 00617 00618 if (flags.description) { 00619 get_description(buffer); 00620 output_text(dis, col++, buffer, 0, psize); 00621 } 00622 */ 00623 ++col; 00624 00625 // output content / symbolic link target / comment 00626 if (visible_cols & COL_CONTENT) { 00627 if (calcWidthCol == -1) 00628 _out_wrkr.output_text(dis, _positions, col, entry->_content? entry->_content: TEXT(""), 0); 00629 else if (calcWidthCol==col || calcWidthCol==COLUMNS) 00630 calc_width(dis, col, entry->_content? entry->_content: TEXT("")); 00631 } 00632 } 00633 00634 00635 void Pane::calc_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) 00636 { 00637 RECT rt = {0, 0, 0, 0}; 00638 00639 DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX); 00640 00641 if (rt.right > _widths[col]) 00642 _widths[col] = rt.right; 00643 } 00644 00645 void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis, int col, LPCTSTR str) 00646 { 00647 RECT rt = {0, 0, 0, 0}; 00648 00649 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; 00650 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/ 00651 00652 DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8)); 00653 00654 if (rt.right > _widths[col]) 00655 _widths[col] = rt.right; 00656 } 00657 00658 00659 // insert listbox entries after index idx 00660 00661 int Pane::insert_entries(Entry* dir, int idx) 00662 { 00663 Entry* entry = dir; 00664 00665 if (!entry) 00666 return idx; 00667 00668 for(; entry; entry=entry->_next) { 00669 #ifndef _LEFT_FILES 00670 if (_treePane && 00671 !(entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) && // not a directory? 00672 !entry->_down) // not a file with NTFS sub-streams? 00673 continue; 00674 #endif 00675 00676 // don't display entries "." and ".." in the left pane 00677 if (_treePane && (entry->_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) 00678 && entry->_data.cFileName[0]==TEXT('.')) 00679 if (entry->_data.cFileName[1]==TEXT('\0') || 00680 (entry->_data.cFileName[1]==TEXT('.') && entry->_data.cFileName[2]==TEXT('\0'))) 00681 continue; 00682 00683 if (idx != -1) 00684 ++idx; 00685 00686 ListBox_InsertItemData(_hwnd, idx, entry); 00687 00688 if (_treePane && entry->_expanded) 00689 idx = insert_entries(entry->_down, idx); 00690 } 00691 00692 return idx; 00693 } 00694 00695 00696 void Pane::set_header() 00697 { 00698 HD_ITEM item; 00699 int scroll_pos = GetScrollPos(_hwnd, SB_HORZ); 00700 int i=0, x=0; 00701 00702 item.mask = HDI_WIDTH; 00703 item.cxy = 0; 00704 00705 for(; x+_widths[i]<scroll_pos && i<COLUMNS; i++) { 00706 x += _widths[i]; 00707 Header_SetItem(_hwndHeader, i, &item); 00708 } 00709 00710 if (i < COLUMNS) { 00711 x += _widths[i]; 00712 item.cxy = x - scroll_pos; 00713 Header_SetItem(_hwndHeader, i++, &item); 00714 00715 for(; i<COLUMNS; i++) { 00716 item.cxy = _widths[i]; 00717 x += _widths[i]; 00718 Header_SetItem(_hwndHeader, i, &item); 00719 } 00720 } 00721 } 00722 00723 00724 // calculate one prefered column width 00725 00726 void Pane::calc_single_width(int col) 00727 { 00728 HFONT hfontOld; 00729 int x, cx; 00730 int cnt; 00731 HDC hdc; 00732 00733 int entries = ListBox_GetCount(_hwnd); 00734 00735 _widths[col] = 0; 00736 00737 hdc = GetDC(_hwnd); 00738 hfontOld = SelectFont(hdc, _out_wrkr._hfont); 00739 00740 for(cnt=0; cnt<entries; cnt++) { 00741 Entry* entry = (Entry*) ListBox_GetItemData(_hwnd, cnt); 00742 00743 DRAWITEMSTRUCT dis; 00744 00745 dis.CtlType = 0; 00746 dis.CtlID = 0; 00747 dis.itemID = 0; 00748 dis.itemAction = 0; 00749 dis.itemState = 0; 00750 dis.hwndItem = _hwnd; 00751 dis.hDC = hdc; 00752 dis.rcItem.left = 0; 00753 dis.rcItem.top = 0; 00754 dis.rcItem.right = 0; 00755 dis.rcItem.bottom = 0; 00756 /*dis.itemData = 0; */ 00757 00758 draw_item(&dis, entry, col); 00759 } 00760 00761 SelectObject(hdc, hfontOld); 00762 ReleaseDC(_hwnd, hdc); 00763 00764 cx = _widths[col]; 00765 00766 if (cx) { 00767 cx += 3*_out_wrkr._spaceSize.cx; 00768 00769 if (cx < IMAGE_WIDTH) 00770 cx = IMAGE_WIDTH; 00771 } 00772 00773 _widths[col] = cx; 00774 00775 x = _positions[col] + cx; 00776 00777 for(; col<COLUMNS; ) { 00778 _positions[++col] = x; 00779 x += _widths[col]; 00780 } 00781 00782 ListBox_SetHorizontalExtent(_hwnd, x); 00783 } 00784 00785 00786 int Pane::Notify(int id, NMHDR* pnmh) 00787 { 00788 switch(pnmh->code) { 00789 case HDN_TRACK: 00790 case HDN_ENDTRACK: { 00791 HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; 00792 int idx = phdn->iItem; 00793 int dx = phdn->pitem->cxy - _widths[idx]; 00794 int i; 00795 00796 ClientRect clnt(_hwnd); 00797 00798 // move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB) 00799 Header_SetItem(_hwndHeader, idx, phdn->pitem); 00800 00801 _widths[idx] += dx; 00802 00803 for(i=idx; ++i<=COLUMNS; ) 00804 _positions[i] += dx; 00805 00806 { 00807 int scroll_pos = GetScrollPos(_hwnd, SB_HORZ); 00808 RECT rt_scr; 00809 RECT rt_clip; 00810 00811 rt_scr.left = _positions[idx+1]-scroll_pos; 00812 rt_scr.top = 0; 00813 rt_scr.right = clnt.right; 00814 rt_scr.bottom = clnt.bottom; 00815 00816 rt_clip.left = _positions[idx]-scroll_pos; 00817 rt_clip.top = 0; 00818 rt_clip.right = clnt.right; 00819 rt_clip.bottom = clnt.bottom; 00820 00821 if (rt_scr.left < 0) rt_scr.left = 0; 00822 if (rt_clip.left < 0) rt_clip.left = 0; 00823 00824 ScrollWindowEx(_hwnd, dx, 0, &rt_scr, &rt_clip, 0, 0, SW_INVALIDATE); 00825 00826 rt_clip.right = _positions[idx+1]; 00827 RedrawWindow(_hwnd, &rt_clip, 0, RDW_INVALIDATE|RDW_UPDATENOW); 00828 00829 if (pnmh->code == HDN_ENDTRACK) { 00830 ListBox_SetHorizontalExtent(_hwnd, _positions[COLUMNS]); 00831 00832 if (GetScrollPos(_hwnd, SB_HORZ) != scroll_pos) 00833 set_header(); 00834 } 00835 } 00836 00837 return 0; 00838 } 00839 00840 case HDN_DIVIDERDBLCLICK: { 00841 HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; 00842 HD_ITEM item; 00843 00844 calc_single_width(phdn->iItem); 00845 item.mask = HDI_WIDTH; 00846 item.cxy = _widths[phdn->iItem]; 00847 00848 Header_SetItem(_hwndHeader, phdn->iItem, &item); 00849 InvalidateRect(_hwnd, 0, TRUE); 00850 break;} 00851 00852 default: 00853 return super::Notify(id, pnmh); 00854 } 00855 00856 return 0; 00857 } 00858 00859 00860 OutputWorker::OutputWorker() 00861 { 00862 _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")); 00863 } 00864 00865 void OutputWorker::init_output(HWND hwnd) 00866 { 00867 TCHAR b[16]; 00868 00869 WindowCanvas canvas(hwnd); 00870 00871 if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, TEXT("1000"), 0, b, 16) > 4) 00872 _num_sep = b[1]; 00873 else 00874 _num_sep = TEXT('.'); 00875 00876 FontSelection font(canvas, _hfont); 00877 GetTextExtentPoint32(canvas, TEXT(" "), 1, &_spaceSize); 00878 } 00879 00880 00881 void OutputWorker::output_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str, DWORD flags) 00882 { 00883 int x = dis->rcItem.left; 00884 RECT rt; 00885 00886 rt.left = x+positions[col]+_spaceSize.cx; 00887 rt.top = dis->rcItem.top; 00888 rt.right = x+positions[col+1]-_spaceSize.cx; 00889 rt.bottom = dis->rcItem.bottom; 00890 00891 DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|flags); 00892 } 00893 00894 void OutputWorker::output_tabbed_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str) 00895 { 00896 int x = dis->rcItem.left; 00897 RECT rt; 00898 00899 rt.left = x+positions[col]+_spaceSize.cx; 00900 rt.top = dis->rcItem.top; 00901 rt.right = x+positions[col+1]-_spaceSize.cx; 00902 rt.bottom = dis->rcItem.bottom; 00903 00904 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; 00905 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/ 00906 00907 DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8)); 00908 } 00909 00910 void OutputWorker::output_number(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str) 00911 { 00912 int x = dis->rcItem.left; 00913 RECT rt; 00914 LPCTSTR s = str; 00915 TCHAR b[128]; 00916 LPTSTR d = b; 00917 int pos; 00918 00919 rt.left = x+positions[col]+_spaceSize.cx; 00920 rt.top = dis->rcItem.top; 00921 rt.right = x+positions[col+1]-_spaceSize.cx; 00922 rt.bottom = dis->rcItem.bottom; 00923 00924 if (*s) 00925 *d++ = *s++; 00926 00927 // insert number separator characters 00928 pos = lstrlen(s) % 3; 00929 00930 while(*s) 00931 if (pos--) 00932 *d++ = *s++; 00933 else { 00934 *d++ = _num_sep; 00935 pos = 3; 00936 } 00937 00938 DrawText(dis->hDC, b, d-b, &rt, DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS); 00939 } 00940 00941 00942 BOOL Pane::command(UINT cmd) 00943 { 00944 switch(cmd) { 00945 case ID_VIEW_NAME: 00946 if (_visible_cols) { 00947 _visible_cols = 0; 00948 calc_widths(true); 00949 set_header(); 00950 InvalidateRect(_hwnd, 0, TRUE); 00951 MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); 00952 if (menu_info) { 00953 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND|MF_CHECKED); 00954 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND); 00955 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); 00956 } 00957 } 00958 break; 00959 00960 case ID_VIEW_ALL_ATTRIBUTES: 00961 if (_visible_cols != COL_ALL) { 00962 _visible_cols = COL_ALL; 00963 calc_widths(true); 00964 set_header(); 00965 InvalidateRect(_hwnd, 0, TRUE); 00966 MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); 00967 if (menu_info) { 00968 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND); 00969 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND|MF_CHECKED); 00970 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); 00971 } 00972 } 00973 break; 00974 00975 case ID_PREFERED_SIZES: { 00976 calc_widths(true); 00977 set_header(); 00978 InvalidateRect(_hwnd, 0, TRUE); 00979 break;} 00980 00981 /*@todo more command ids... */ 00982 00983 default: 00984 return FALSE; 00985 } 00986 00987 return TRUE; 00988 } 00989 00990 MainFrameBase* Pane::get_frame() 00991 { 00992 HWND owner = GetParent(_hwnd); 00993 00994 return (MainFrameBase*)owner; 00995 }
ROS Explorer Source Code Documentation
generated on 02.01.2013 by ![]() |