ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

pane.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 doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.