Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpane.cpp
Go to the documentation of this file.
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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 TCHAR* 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 = (TCHAR*)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 { 00381 for(Entry*n=up->_next; n; n=n->_next) 00382 if (n->_down) { // any file with NTFS sub-streams? 00383 following_child = true; 00384 break; 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 { 00408 for(Entry*n=entry->_next; n; n=n->_next) 00409 if (n->_down) { // any file with NTFS sub-streams? 00410 following_child = true; 00411 break; 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); 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(; i<COLUMNS; i++) { 00706 if (x + _widths[i] >= scroll_pos) 00707 break; 00708 00709 x += _widths[i]; 00710 Header_SetItem(_hwndHeader, i, &item); 00711 } 00712 00713 if (i < COLUMNS) { 00714 x += _widths[i]; 00715 item.cxy = x - scroll_pos; 00716 Header_SetItem(_hwndHeader, i++, &item); 00717 00718 for(; i<COLUMNS; i++) { 00719 item.cxy = _widths[i]; 00720 x += _widths[i]; 00721 Header_SetItem(_hwndHeader, i, &item); 00722 } 00723 } 00724 } 00725 00726 00727 // calculate one prefered column width 00728 00729 void Pane::calc_single_width(int col) 00730 { 00731 HFONT hfontOld; 00732 int x, cx; 00733 int cnt; 00734 HDC hdc; 00735 00736 int entries = ListBox_GetCount(_hwnd); 00737 00738 _widths[col] = 0; 00739 00740 hdc = GetDC(_hwnd); 00741 hfontOld = SelectFont(hdc, _out_wrkr._hfont); 00742 00743 for(cnt=0; cnt<entries; cnt++) { 00744 Entry* entry = (Entry*) ListBox_GetItemData(_hwnd, cnt); 00745 00746 DRAWITEMSTRUCT dis; 00747 00748 dis.CtlType = 0; 00749 dis.CtlID = 0; 00750 dis.itemID = 0; 00751 dis.itemAction = 0; 00752 dis.itemState = 0; 00753 dis.hwndItem = _hwnd; 00754 dis.hDC = hdc; 00755 dis.rcItem.left = 0; 00756 dis.rcItem.top = 0; 00757 dis.rcItem.right = 0; 00758 dis.rcItem.bottom = 0; 00759 /*dis.itemData = 0; */ 00760 00761 draw_item(&dis, entry, col); 00762 } 00763 00764 SelectObject(hdc, hfontOld); 00765 ReleaseDC(_hwnd, hdc); 00766 00767 cx = _widths[col]; 00768 00769 if (cx) { 00770 cx += 3*_out_wrkr._spaceSize.cx; 00771 00772 if (cx < IMAGE_WIDTH) 00773 cx = IMAGE_WIDTH; 00774 } 00775 00776 _widths[col] = cx; 00777 00778 x = _positions[col] + cx; 00779 00780 for(; col<COLUMNS; col++) { 00781 _positions[col+1] = x; 00782 x += _widths[col]; 00783 } 00784 00785 ListBox_SetHorizontalExtent(_hwnd, x); 00786 } 00787 00788 00789 int Pane::Notify(int id, NMHDR* pnmh) 00790 { 00791 switch(pnmh->code) { 00792 case HDN_TRACK: 00793 case HDN_ENDTRACK: { 00794 HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; 00795 int idx = phdn->iItem; 00796 int dx = phdn->pitem->cxy - _widths[idx]; 00797 int i; 00798 00799 ClientRect clnt(_hwnd); 00800 00801 // move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB) 00802 Header_SetItem(_hwndHeader, idx, phdn->pitem); 00803 00804 _widths[idx] += dx; 00805 00806 for(i=idx; ++i<=COLUMNS; ) 00807 _positions[i] += dx; 00808 00809 { 00810 int scroll_pos = GetScrollPos(_hwnd, SB_HORZ); 00811 RECT rt_scr; 00812 RECT rt_clip; 00813 00814 rt_scr.left = _positions[idx+1]-scroll_pos; 00815 rt_scr.top = 0; 00816 rt_scr.right = clnt.right; 00817 rt_scr.bottom = clnt.bottom; 00818 00819 rt_clip.left = _positions[idx]-scroll_pos; 00820 rt_clip.top = 0; 00821 rt_clip.right = clnt.right; 00822 rt_clip.bottom = clnt.bottom; 00823 00824 if (rt_scr.left < 0) rt_scr.left = 0; 00825 if (rt_clip.left < 0) rt_clip.left = 0; 00826 00827 ScrollWindowEx(_hwnd, dx, 0, &rt_scr, &rt_clip, 0, 0, SW_INVALIDATE); 00828 00829 rt_clip.right = _positions[idx+1]; 00830 RedrawWindow(_hwnd, &rt_clip, 0, RDW_INVALIDATE|RDW_UPDATENOW); 00831 00832 if (pnmh->code == HDN_ENDTRACK) { 00833 ListBox_SetHorizontalExtent(_hwnd, _positions[COLUMNS]); 00834 00835 if (GetScrollPos(_hwnd, SB_HORZ) != scroll_pos) 00836 set_header(); 00837 } 00838 } 00839 00840 return 0; 00841 } 00842 00843 case HDN_DIVIDERDBLCLICK: { 00844 HD_NOTIFY* phdn = (HD_NOTIFY*) pnmh; 00845 HD_ITEM item; 00846 00847 calc_single_width(phdn->iItem); 00848 item.mask = HDI_WIDTH; 00849 item.cxy = _widths[phdn->iItem]; 00850 00851 Header_SetItem(_hwndHeader, phdn->iItem, &item); 00852 InvalidateRect(_hwnd, 0, TRUE); 00853 break;} 00854 00855 default: 00856 return super::Notify(id, pnmh); 00857 } 00858 00859 return 0; 00860 } 00861 00862 00863 OutputWorker::OutputWorker() 00864 { 00865 _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")); 00866 } 00867 00868 void OutputWorker::init_output(HWND hwnd) 00869 { 00870 TCHAR b[16]; 00871 00872 WindowCanvas canvas(hwnd); 00873 00874 if (GetNumberFormat(LOCALE_USER_DEFAULT, 0, TEXT("1000"), 0, b, 16) > 4) 00875 _num_sep = b[1]; 00876 else 00877 _num_sep = TEXT('.'); 00878 00879 FontSelection font(canvas, _hfont); 00880 GetTextExtentPoint32(canvas, TEXT(" "), 1, &_spaceSize); 00881 } 00882 00883 00884 void OutputWorker::output_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str, DWORD flags) 00885 { 00886 int x = dis->rcItem.left; 00887 RECT rt; 00888 00889 rt.left = x+positions[col]+_spaceSize.cx; 00890 rt.top = dis->rcItem.top; 00891 rt.right = x+positions[col+1]-_spaceSize.cx; 00892 rt.bottom = dis->rcItem.bottom; 00893 00894 DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|flags); 00895 } 00896 00897 void OutputWorker::output_tabbed_text(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str) 00898 { 00899 int x = dis->rcItem.left; 00900 RECT rt; 00901 00902 rt.left = x+positions[col]+_spaceSize.cx; 00903 rt.top = dis->rcItem.top; 00904 rt.right = x+positions[col+1]-_spaceSize.cx; 00905 rt.bottom = dis->rcItem.bottom; 00906 00907 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2}; 00908 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/ 00909 00910 DrawText(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_EXPANDTABS|DT_TABSTOP|(2<<8)); 00911 } 00912 00913 void OutputWorker::output_number(LPDRAWITEMSTRUCT dis, int* positions, int col, LPCTSTR str) 00914 { 00915 int x = dis->rcItem.left; 00916 RECT rt; 00917 LPCTSTR s = str; 00918 TCHAR b[128]; 00919 LPTSTR d = b; 00920 int pos; 00921 00922 rt.left = x+positions[col]+_spaceSize.cx; 00923 rt.top = dis->rcItem.top; 00924 rt.right = x+positions[col+1]-_spaceSize.cx; 00925 rt.bottom = dis->rcItem.bottom; 00926 00927 if (*s) 00928 *d++ = *s++; 00929 00930 // insert number separator characters 00931 pos = lstrlen(s) % 3; 00932 00933 while(*s) 00934 if (pos--) 00935 *d++ = *s++; 00936 else { 00937 *d++ = _num_sep; 00938 pos = 3; 00939 } 00940 00941 DrawText(dis->hDC, b, d-b, &rt, DT_RIGHT|DT_SINGLELINE|DT_NOPREFIX|DT_END_ELLIPSIS); 00942 } 00943 00944 00945 BOOL Pane::command(UINT cmd) 00946 { 00947 switch(cmd) { 00948 case ID_VIEW_NAME: 00949 if (_visible_cols) { 00950 _visible_cols = 0; 00951 calc_widths(true); 00952 set_header(); 00953 InvalidateRect(_hwnd, 0, TRUE); 00954 MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); 00955 if (menu_info) { 00956 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND|MF_CHECKED); 00957 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND); 00958 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); 00959 } 00960 } 00961 break; 00962 00963 case ID_VIEW_ALL_ATTRIBUTES: 00964 if (_visible_cols != COL_ALL) { 00965 _visible_cols = COL_ALL; 00966 calc_widths(true); 00967 set_header(); 00968 InvalidateRect(_hwnd, 0, TRUE); 00969 MenuInfo* menu_info = Frame_GetMenuInfo(GetParent(_hwnd)); 00970 if (menu_info) { 00971 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_NAME, MF_BYCOMMAND); 00972 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_ALL_ATTRIBUTES, MF_BYCOMMAND|MF_CHECKED); 00973 CheckMenuItem(menu_info->_hMenuView, ID_VIEW_SELECTED_ATTRIBUTES, MF_BYCOMMAND); 00974 } 00975 } 00976 break; 00977 00978 case ID_PREFERED_SIZES: { 00979 calc_widths(true); 00980 set_header(); 00981 InvalidateRect(_hwnd, 0, TRUE); 00982 break;} 00983 00984 /*@todo more command ids... */ 00985 00986 default: 00987 return FALSE; 00988 } 00989 00990 return TRUE; 00991 } 00992 00993 MainFrameBase* Pane::get_frame() 00994 { 00995 HWND owner = GetParent(_hwnd); 00996 00997 return (MainFrameBase*)owner; 00998 } Generated on Sat May 26 2012 04:17:31 for ReactOS by
1.7.6.1
|