2 * Copyright 2003, 2004, 2005 Martin Fuchs
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
25 // Martin Fuchs, 23.07.2003
31 #include "../resource.h"
35 IMG_NONE
=-1, IMG_FILE
=0, IMG_DOCUMENT
, IMG_EXECUTABLE
,
36 IMG_FOLDER
, IMG_OPEN_FOLDER
, IMG_FOLDER_PLUS
,IMG_OPEN_PLUS
, IMG_OPEN_MINUS
,
37 IMG_FOLDER_UP
, IMG_FOLDER_CUR
41 #define IMAGE_WIDTH 16
42 #define IMAGE_HEIGHT 13
45 static const LPTSTR g_pos_names
[COLUMNS
] = {
46 TEXT(""), /* symbol */
60 static const int g_pos_align
[] = {
69 HDF_RIGHT
, /* Links */
70 HDF_CENTER
, /* Attributes */
71 HDF_LEFT
, /* Security */
72 HDF_LEFT
/* Content / Description */
76 Pane::Pane(HWND hparent
, int id
, int id_header
, Entry
* root
, bool treePane
, int visible_cols
)
77 : super(CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD
|WS_VISIBLE
|WS_HSCROLL
|WS_VSCROLL
|
78 LBS_DISABLENOSCROLL
|LBS_NOINTEGRALHEIGHT
|LBS_OWNERDRAWFIXED
|LBS_NOTIFY
,
79 0, 0, 0, 0, hparent
, (HMENU
)id
, g_Globals
._hInstance
, 0)),
81 _visible_cols(visible_cols
),
84 // insert entries into listbox
88 insert_entries(entry
);
92 create_header(hparent
, id_header
);
97 ImageList_Destroy(_himl
);
101 LRESULT
Pane::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
109 FileChildWindow
* child
= (FileChildWindow
*) SendMessage(GetParent(_hwnd
), PM_GET_FILEWND_PTR
, 0, 0);
111 child
->set_focus_pane(this);
112 ListBox_SetSel(_hwnd
, TRUE
, 1);
113 /*@todo check menu items */
117 FileChildWindow
* child
= (FileChildWindow
*) SendMessage(GetParent(_hwnd
), PM_GET_FILEWND_PTR
, 0, 0);
119 if (wparam
== VK_TAB
) {
120 /*@todo SetFocus(g_Globals.hdrivebar) */
121 child
->switch_focus_pane();
126 return super::WndProc(nmsg
, wparam
, lparam
);
130 bool Pane::create_header(HWND hparent
, int id
)
132 HWND hwnd
= CreateWindow(WC_HEADER
, 0, WS_CHILD
|WS_VISIBLE
|HDS_HORZ
/*@todo |HDS_BUTTONS + sort orders*/,
133 0, 0, 0, 0, hparent
, (HMENU
)id
, g_Globals
._hInstance
, 0);
137 SetWindowFont(hwnd
, GetStockFont(DEFAULT_GUI_FONT
), FALSE
);
141 hdi
.mask
= HDI_TEXT
|HDI_WIDTH
|HDI_FORMAT
;
143 for(int idx
=0; idx
<COLUMNS
; idx
++) {
144 hdi
.pszText
= g_pos_names
[idx
];
145 hdi
.fmt
= HDF_STRING
| g_pos_align
[idx
];
146 hdi
.cxy
= _widths
[idx
];
147 Header_InsertItem(hwnd
, idx
, &hdi
);
158 _himl
= ImageList_LoadBitmap(g_Globals
._hInstance
, MAKEINTRESOURCE(IDB_IMAGES
), 16, 0, RGB(0,255,0));
160 SetWindowFont(_hwnd
, _out_wrkr
._hfont
, FALSE
);
162 // read the color for compressed files from registry
163 HKEY hkeyExplorer
= 0;
164 DWORD len
= sizeof(_clrCompressed
);
166 if (RegOpenKey(HKEY_CURRENT_USER
, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer
) ||
167 RegQueryValueEx(hkeyExplorer
, TEXT("AltColor"), 0, NULL
, (LPBYTE
)&_clrCompressed
, &len
) || len
!=sizeof(_clrCompressed
))
168 _clrCompressed
= RGB(0,0,255);
171 RegCloseKey(hkeyExplorer
);
173 // calculate column widths
174 _out_wrkr
.init_output(_hwnd
);
179 // calculate prefered width for all visible columns
181 bool Pane::calc_widths(bool anyway
)
183 int col
, x
, cx
, spc
=3*_out_wrkr
._spaceSize
.cx
;
184 int entries
= ListBox_GetCount(_hwnd
);
185 int orgWidths
[COLUMNS
];
186 int orgPositions
[COLUMNS
+1];
192 memcpy(orgWidths
, _widths
, sizeof(orgWidths
));
193 memcpy(orgPositions
, _positions
, sizeof(orgPositions
));
196 for(col
=0; col
<COLUMNS
; col
++)
200 hfontOld
= SelectFont(hdc
, _out_wrkr
._hfont
);
202 for(cnt
=0; cnt
<entries
; cnt
++) {
203 Entry
* entry
= (Entry
*) ListBox_GetItemData(_hwnd
, cnt
);
212 dis
.hwndItem
= _hwnd
;
216 dis
.rcItem
.right
= 0;
217 dis
.rcItem
.bottom
= 0;
218 /*dis.itemData = 0; */
220 draw_item(&dis
, entry
, COLUMNS
);
223 SelectObject(hdc
, hfontOld
);
224 ReleaseDC(_hwnd
, hdc
);
227 for(col
=0; col
<COLUMNS
; col
++) {
234 if (cx
< IMAGE_WIDTH
)
243 _positions
[COLUMNS
] = x
;
245 ListBox_SetHorizontalExtent(_hwnd
, x
);
248 if (!memcmp(orgWidths
, _widths
, sizeof(orgWidths
)))
251 // don't move, if only collapsing an entry
252 if (!anyway
&& _widths
[0]<orgWidths
[0] &&
253 !memcmp(orgWidths
+1, _widths
+1, sizeof(orgWidths
)-sizeof(int))) {
254 _widths
[0] = orgWidths
[0];
255 memcpy(_positions
, orgPositions
, sizeof(orgPositions
));
260 InvalidateRect(_hwnd
, 0, TRUE
);
266 static void format_date(const FILETIME
* ft
, TCHAR
* buffer
, int visible_cols
)
272 *buffer
= TEXT('\0');
274 if (!ft
->dwLowDateTime
&& !ft
->dwHighDateTime
)
277 if (!FileTimeToLocalFileTime(ft
, &lft
))
278 {err
: lstrcpy(buffer
,TEXT("???")); return;}
280 if (!FileTimeToSystemTime(&lft
, &systime
))
283 if (visible_cols
& COL_DATE
) {
284 len
= GetDateFormat(LOCALE_USER_DEFAULT
, 0, &systime
, 0, buffer
, BUFFER_LEN
);
289 if (visible_cols
& COL_TIME
) {
295 if (!GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &systime
, 0, buffer
+len
, BUFFER_LEN
-len
))
296 buffer
[len
] = TEXT('\0');
301 void Pane::draw_item(LPDRAWITEMSTRUCT dis
, Entry
* entry
, int calcWidthCol
)
303 TCHAR buffer
[BUFFER_LEN
];
305 int visible_cols
= _visible_cols
;
306 COLORREF bkcolor
, textcolor
;
307 RECT focusRect
= dis
->rcItem
;
313 attrs
= entry
->_data
.dwFileAttributes
;
315 if (attrs
& FILE_ATTRIBUTE_DIRECTORY
) {
316 if (entry
->_data
.cFileName
[0]==TEXT('.') && entry
->_data
.cFileName
[1]==TEXT('.')
317 && entry
->_data
.cFileName
[2]==TEXT('\0'))
319 else if (entry
->_data
.cFileName
[0]==TEXT('.') && entry
->_data
.cFileName
[1]==TEXT('\0'))
320 img
= IMG_FOLDER_CUR
;
321 else if ((_treePane
&& (dis
->itemState
&ODS_FOCUS
)))
322 img
= IMG_OPEN_FOLDER
;
326 if (attrs
& ATTRIBUTE_EXECUTABLE
)
327 img
= IMG_EXECUTABLE
;
328 else if (entry
->_type_name
)
340 img_pos
= dis
->rcItem
.left
+ entry
->_level
*(IMAGE_WIDTH
+_out_wrkr
._spaceSize
.cx
);
342 if (calcWidthCol
== -1) {
344 int y
= dis
->rcItem
.top
+ IMAGE_HEIGHT
/2;
347 HRGN hrgn_org
= CreateRectRgn(0, 0, 0, 0);
350 rt_clip
.left
= dis
->rcItem
.left
;
351 rt_clip
.top
= dis
->rcItem
.top
;
352 rt_clip
.right
= dis
->rcItem
.left
+_widths
[col
];
353 rt_clip
.bottom
= dis
->rcItem
.bottom
;
355 hrgn
= CreateRectRgnIndirect(&rt_clip
);
357 if (!GetClipRgn(dis
->hDC
, hrgn_org
)) {
358 DeleteObject(hrgn_org
);
362 //HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN));
363 ExtSelectClipRgn(dis
->hDC
, hrgn
, RGN_AND
);
366 if ((up
=entry
->_up
) != NULL
) {
367 MoveToEx(dis
->hDC
, img_pos
-IMAGE_WIDTH
/2, y
, 0);
368 LineTo(dis
->hDC
, img_pos
-2, y
);
370 x
= img_pos
- IMAGE_WIDTH
/2;
373 x
-= IMAGE_WIDTH
+_out_wrkr
._spaceSize
.cx
;
377 bool following_child
= (up
->_next
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)!=0; // a directory?
379 if (!following_child
)
380 for(Entry
*n
=up
->_next
; n
; n
=n
->_next
)
381 if (n
->_down
) { // any file with NTFS sub-streams?
382 following_child
= true;
389 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
, 0);
390 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
393 } while((up
=up
->_up
) != NULL
);
396 x
= img_pos
- IMAGE_WIDTH
/2;
398 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
, 0);
399 LineTo(dis
->hDC
, x
, y
);
403 bool following_child
= (entry
->_next
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)!=0; // a directory?
405 if (!following_child
)
406 for(Entry
*n
=entry
->_next
; n
; n
=n
->_next
)
407 if (n
->_down
) { // any file with NTFS sub-streams?
408 following_child
= true;
414 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
417 if (entry
->_down
&& entry
->_expanded
) {
418 x
+= IMAGE_WIDTH
+ _out_wrkr
._spaceSize
.cx
;
419 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
+IMAGE_HEIGHT
, 0);
420 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
423 SelectClipRgn(dis
->hDC
, hrgn_org
);
424 if (hrgn_org
) DeleteObject(hrgn_org
);
425 //SelectObject(dis->hDC, holdPen);
426 } else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
) {
427 int right
= img_pos
+ IMAGE_WIDTH
- _out_wrkr
._spaceSize
.cx
;
429 if (right
> _widths
[col
])
430 _widths
[col
] = right
;
433 img_pos
= dis
->rcItem
.left
;
436 img_pos
= dis
->rcItem
.left
;
438 if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
439 _widths
[col
] = IMAGE_WIDTH
;
442 if (calcWidthCol
== -1) {
443 focusRect
.left
= img_pos
-2;
445 if (attrs
& FILE_ATTRIBUTE_COMPRESSED
)
446 textcolor
= _clrCompressed
;
448 textcolor
= RGB(0,0,0);
450 if (dis
->itemState
& ODS_FOCUS
) {
451 textcolor
= GetSysColor(COLOR_HIGHLIGHTTEXT
);
452 bkcolor
= GetSysColor(COLOR_HIGHLIGHT
);
454 bkcolor
= GetSysColor(COLOR_WINDOW
);
457 HBRUSH hbrush
= CreateSolidBrush(bkcolor
);
458 FillRect(dis
->hDC
, &focusRect
, hbrush
);
459 DeleteObject(hbrush
);
461 SetBkMode(dis
->hDC
, TRANSPARENT
);
462 SetTextColor(dis
->hDC
, textcolor
);
466 if (cx
&& img
!=IMG_NONE
) {
467 if (cx
> IMAGE_WIDTH
)
470 if (entry
->_icon_id
> ICID_NONE
)
471 g_Globals
._icon_cache
.get_icon(entry
->_icon_id
).draw(dis
->hDC
, img_pos
, dis
->rcItem
.top
, cx
, GetSystemMetrics(SM_CYSMICON
), bkcolor
, 0);
473 ImageList_DrawEx(_himl
, img
, dis
->hDC
,
474 img_pos
, dis
->rcItem
.top
, cx
,
475 IMAGE_HEIGHT
, bkcolor
, CLR_DEFAULT
, ILD_NORMAL
);
485 if (calcWidthCol
== -1)
486 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_display_name
, 0);
487 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
488 calc_width(dis
, col
, entry
->_display_name
);
491 // output type/class name
492 if (visible_cols
& COL_TYPE
) {
493 if (calcWidthCol
== -1)
494 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_type_name
? entry
->_type_name
: TEXT(""), 0);
495 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
496 calc_width(dis
, col
, entry
->_type_name
? entry
->_type_name
: TEXT(""));
501 if (visible_cols
& COL_SIZE
) {
502 ULONGLONG size
= ((ULONGLONG
)entry
->_data
.nFileSizeHigh
<< 32) | entry
->_data
.nFileSizeLow
;
504 _stprintf(buffer
, TEXT("%") LONGLONGARG
TEXT("d"), size
);
506 if (calcWidthCol
== -1)
507 _out_wrkr
.output_number(dis
, _positions
, col
, buffer
);
508 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
509 calc_width(dis
, col
, buffer
); ///@todo not in every case time enough
514 if (visible_cols
& (COL_DATE
|COL_TIME
)) {
515 format_date(&entry
->_data
.ftCreationTime
, buffer
, visible_cols
);
516 if (calcWidthCol
== -1)
517 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, 0);
518 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
519 calc_width(dis
, col
, buffer
);
522 format_date(&entry
->_data
.ftLastAccessTime
, buffer
, visible_cols
);
523 if (calcWidthCol
== -1)
524 _out_wrkr
.output_text(dis
,_positions
, col
, buffer
, 0);
525 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
526 calc_width(dis
, col
, buffer
);
529 format_date(&entry
->_data
.ftLastWriteTime
, buffer
, visible_cols
);
530 if (calcWidthCol
== -1)
531 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, 0);
532 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
533 calc_width(dis
, col
, buffer
);
538 if (entry
->_bhfi_valid
) {
539 ULONGLONG index
= ((ULONGLONG
)entry
->_bhfi
.nFileIndexHigh
<< 32) | entry
->_bhfi
.nFileIndexLow
;
541 if (visible_cols
& COL_INDEX
) {
542 _stprintf(buffer
, TEXT("%") LONGLONGARG
TEXT("X"), index
);
544 if (calcWidthCol
== -1)
545 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, DT_RIGHT
);
546 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
547 calc_width(dis
, col
, buffer
);
552 if (visible_cols
& COL_LINKS
) {
553 wsprintf(buffer
, TEXT("%d"), entry
->_bhfi
.nNumberOfLinks
);
555 if (calcWidthCol
== -1)
556 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, DT_RIGHT
);
557 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
558 calc_width(dis
, col
, buffer
);
565 // show file attributes
566 if (visible_cols
& COL_ATTRIBUTES
) {
567 lstrcpy(buffer
, TEXT(" \t \t \t \t \t \t \t \t \t \t \t \t \t \t "));
569 if (attrs
& FILE_ATTRIBUTE_NORMAL
) buffer
[ 0] = 'N';
571 if (attrs
& FILE_ATTRIBUTE_READONLY
) buffer
[ 2] = 'R';
572 if (attrs
& FILE_ATTRIBUTE_HIDDEN
) buffer
[ 4] = 'H';
573 if (attrs
& FILE_ATTRIBUTE_SYSTEM
) buffer
[ 6] = 'S';
574 if (attrs
& FILE_ATTRIBUTE_ARCHIVE
) buffer
[ 8] = 'A';
575 if (attrs
& FILE_ATTRIBUTE_COMPRESSED
) buffer
[10] = 'C';
576 if (attrs
& FILE_ATTRIBUTE_DIRECTORY
) buffer
[12] = 'D';
577 if (attrs
& FILE_ATTRIBUTE_ENCRYPTED
) buffer
[14] = 'E';
578 if (attrs
& FILE_ATTRIBUTE_TEMPORARY
) buffer
[16] = 'T';
579 if (attrs
& FILE_ATTRIBUTE_SPARSE_FILE
) buffer
[18] = 'P';
580 if (attrs
& FILE_ATTRIBUTE_REPARSE_POINT
) buffer
[20] = 'Q';
581 if (attrs
& FILE_ATTRIBUTE_OFFLINE
) buffer
[22] = 'O';
582 if (attrs
& FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
) buffer
[24] = 'X';
583 if (attrs
& ATTRIBUTE_EXECUTABLE
) buffer
[26] = 'x';
584 if (attrs
& ATTRIBUTE_SYMBOLIC_LINK
) buffer
[28] = 'L';
587 if (calcWidthCol
== -1)
588 _out_wrkr
.output_tabbed_text(dis
, _positions
, col
, buffer
);
589 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
590 calc_tabbed_width(dis
, col
, buffer
);
595 if (flags.security) {
596 DWORD rights = get_access_mask();
598 tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t "));
600 if (rights & FILE_READ_DATA) buffer[ 0] = 'R';
601 if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W';
602 if (rights & FILE_APPEND_DATA) buffer[ 4] = 'A';
603 if (rights & FILE_READ_EA) {buffer[6] = 'entry'; buffer[ 7] = 'R';}
604 if (rights & FILE_WRITE_EA) {buffer[9] = 'entry'; buffer[10] = 'W';}
605 if (rights & FILE_EXECUTE) buffer[12] = 'X';
606 if (rights & FILE_DELETE_CHILD) buffer[14] = 'D';
607 if (rights & FILE_READ_ATTRIBUTES) {buffer[16] = 'a'; buffer[17] = 'R';}
608 if (rights & FILE_WRITE_ATTRIBUTES) {buffer[19] = 'a'; buffer[20] = 'W';}
609 if (rights & WRITE_DAC) buffer[22] = 'C';
610 if (rights & WRITE_OWNER) buffer[24] = 'O';
611 if (rights & SYNCHRONIZE) buffer[26] = 'S';
613 output_text(dis, col++, buffer, DT_LEFT, 3, psize);
616 if (flags.description) {
617 get_description(buffer);
618 output_text(dis, col++, buffer, 0, psize);
623 // output content / symbolic link target / comment
624 if (visible_cols
& COL_CONTENT
) {
625 if (calcWidthCol
== -1)
626 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_content
? entry
->_content
: TEXT(""), 0);
627 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
628 calc_width(dis
, col
, entry
->_content
? entry
->_content
: TEXT(""));
633 void Pane::calc_width(LPDRAWITEMSTRUCT dis
, int col
, LPCTSTR str
)
635 RECT rt
= {0, 0, 0, 0};
637 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_CALCRECT
|DT_SINGLELINE
|DT_NOPREFIX
);
639 if (rt
.right
> _widths
[col
])
640 _widths
[col
] = rt
.right
;
643 void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis
, int col
, LPCTSTR str
)
645 RECT rt
= {0, 0, 0, 0};
647 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2};
648 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
650 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_CALCRECT
|DT_SINGLELINE
|DT_EXPANDTABS
|DT_TABSTOP
|(2<<8));
653 if (rt
.right
> _widths
[col
])
654 _widths
[col
] = rt
.right
;
658 // insert listbox entries after index idx
660 int Pane::insert_entries(Entry
* dir
, int idx
)
667 for(; entry
; entry
=entry
->_next
) {
670 !(entry
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
) && // not a directory?
671 !entry
->_down
) // not a file with NTFS sub-streams?
675 // don't display entries "." and ".." in the left pane
676 if (_treePane
&& (entry
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)
677 && entry
->_data
.cFileName
[0]==TEXT('.'))
678 if (entry
->_data
.cFileName
[1]==TEXT('\0') ||
679 (entry
->_data
.cFileName
[1]==TEXT('.') && entry
->_data
.cFileName
[2]==TEXT('\0')))
685 ListBox_InsertItemData(_hwnd
, idx
, entry
);
687 if (_treePane
&& entry
->_expanded
)
688 idx
= insert_entries(entry
->_down
, idx
);
695 void Pane::set_header()
698 int scroll_pos
= GetScrollPos(_hwnd
, SB_HORZ
);
701 item
.mask
= HDI_WIDTH
;
704 for(; x
+_widths
[i
]<scroll_pos
&& i
<COLUMNS
; i
++) {
706 Header_SetItem(_hwndHeader
, i
, &item
);
711 item
.cxy
= x
- scroll_pos
;
712 Header_SetItem(_hwndHeader
, i
++, &item
);
714 for(; i
<COLUMNS
; i
++) {
715 item
.cxy
= _widths
[i
];
717 Header_SetItem(_hwndHeader
, i
, &item
);
723 // calculate one prefered column width
725 void Pane::calc_single_width(int col
)
732 int entries
= ListBox_GetCount(_hwnd
);
737 hfontOld
= SelectFont(hdc
, _out_wrkr
._hfont
);
739 for(cnt
=0; cnt
<entries
; cnt
++) {
740 Entry
* entry
= (Entry
*) ListBox_GetItemData(_hwnd
, cnt
);
749 dis
.hwndItem
= _hwnd
;
753 dis
.rcItem
.right
= 0;
754 dis
.rcItem
.bottom
= 0;
755 /*dis.itemData = 0; */
757 draw_item(&dis
, entry
, col
);
760 SelectObject(hdc
, hfontOld
);
761 ReleaseDC(_hwnd
, hdc
);
766 cx
+= 3*_out_wrkr
._spaceSize
.cx
;
768 if (cx
< IMAGE_WIDTH
)
774 x
= _positions
[col
] + cx
;
776 for(; col
<COLUMNS
; ) {
777 _positions
[++col
] = x
;
781 ListBox_SetHorizontalExtent(_hwnd
, x
);
785 int Pane::Notify(int id
, NMHDR
* pnmh
)
790 HD_NOTIFY
* phdn
= (HD_NOTIFY
*) pnmh
;
791 int idx
= phdn
->iItem
;
792 int dx
= phdn
->pitem
->cxy
- _widths
[idx
];
795 ClientRect
clnt(_hwnd
);
797 // move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB)
798 Header_SetItem(_hwndHeader
, idx
, phdn
->pitem
);
802 for(i
=idx
; ++i
<=COLUMNS
; )
806 int scroll_pos
= GetScrollPos(_hwnd
, SB_HORZ
);
810 rt_scr
.left
= _positions
[idx
+1]-scroll_pos
;
812 rt_scr
.right
= clnt
.right
;
813 rt_scr
.bottom
= clnt
.bottom
;
815 rt_clip
.left
= _positions
[idx
]-scroll_pos
;
817 rt_clip
.right
= clnt
.right
;
818 rt_clip
.bottom
= clnt
.bottom
;
820 if (rt_scr
.left
< 0) rt_scr
.left
= 0;
821 if (rt_clip
.left
< 0) rt_clip
.left
= 0;
823 ScrollWindowEx(_hwnd
, dx
, 0, &rt_scr
, &rt_clip
, 0, 0, SW_INVALIDATE
);
825 rt_clip
.right
= _positions
[idx
+1];
826 RedrawWindow(_hwnd
, &rt_clip
, 0, RDW_INVALIDATE
|RDW_UPDATENOW
);
828 if (pnmh
->code
== HDN_ENDTRACK
) {
829 ListBox_SetHorizontalExtent(_hwnd
, _positions
[COLUMNS
]);
831 if (GetScrollPos(_hwnd
, SB_HORZ
) != scroll_pos
)
839 case HDN_DIVIDERDBLCLICK
: {
840 HD_NOTIFY
* phdn
= (HD_NOTIFY
*) pnmh
;
843 calc_single_width(phdn
->iItem
);
844 item
.mask
= HDI_WIDTH
;
845 item
.cxy
= _widths
[phdn
->iItem
];
847 Header_SetItem(_hwndHeader
, phdn
->iItem
, &item
);
848 InvalidateRect(_hwnd
, 0, TRUE
);
852 return super::Notify(id
, pnmh
);
859 OutputWorker::OutputWorker()
861 _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"));
864 void OutputWorker::init_output(HWND hwnd
)
868 WindowCanvas
canvas(hwnd
);
870 if (GetNumberFormat(LOCALE_USER_DEFAULT
, 0, TEXT("1000"), 0, b
, 16) > 4)
873 _num_sep
= TEXT('.');
875 FontSelection
font(canvas
, _hfont
);
876 GetTextExtentPoint32(canvas
, TEXT(" "), 1, &_spaceSize
);
880 void OutputWorker::output_text(LPDRAWITEMSTRUCT dis
, int* positions
, int col
, LPCTSTR str
, DWORD flags
)
882 int x
= dis
->rcItem
.left
;
885 rt
.left
= x
+positions
[col
]+_spaceSize
.cx
;
886 rt
.top
= dis
->rcItem
.top
;
887 rt
.right
= x
+positions
[col
+1]-_spaceSize
.cx
;
888 rt
.bottom
= dis
->rcItem
.bottom
;
890 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_SINGLELINE
|DT_NOPREFIX
|flags
);
893 void OutputWorker::output_tabbed_text(LPDRAWITEMSTRUCT dis
, int* positions
, int col
, LPCTSTR str
)
895 int x
= dis
->rcItem
.left
;
898 rt
.left
= x
+positions
[col
]+_spaceSize
.cx
;
899 rt
.top
= dis
->rcItem
.top
;
900 rt
.right
= x
+positions
[col
+1]-_spaceSize
.cx
;
901 rt
.bottom
= dis
->rcItem
.bottom
;
903 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2};
904 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
906 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_SINGLELINE
|DT_EXPANDTABS
|DT_TABSTOP
|(2<<8));
909 void OutputWorker::output_number(LPDRAWITEMSTRUCT dis
, int* positions
, int col
, LPCTSTR str
)
911 int x
= dis
->rcItem
.left
;
918 rt
.left
= x
+positions
[col
]+_spaceSize
.cx
;
919 rt
.top
= dis
->rcItem
.top
;
920 rt
.right
= x
+positions
[col
+1]-_spaceSize
.cx
;
921 rt
.bottom
= dis
->rcItem
.bottom
;
926 // insert number separator characters
927 pos
= lstrlen(s
) % 3;
937 DrawText(dis
->hDC
, b
, d
-b
, &rt
, DT_RIGHT
|DT_SINGLELINE
|DT_NOPREFIX
|DT_END_ELLIPSIS
);
941 BOOL
Pane::command(UINT cmd
)
949 InvalidateRect(_hwnd
, 0, TRUE
);
950 MenuInfo
* menu_info
= Frame_GetMenuInfo(GetParent(_hwnd
));
952 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_NAME
, MF_BYCOMMAND
|MF_CHECKED
);
953 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_ALL_ATTRIBUTES
, MF_BYCOMMAND
);
954 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_SELECTED_ATTRIBUTES
, MF_BYCOMMAND
);
959 case ID_VIEW_ALL_ATTRIBUTES
:
960 if (_visible_cols
!= COL_ALL
) {
961 _visible_cols
= COL_ALL
;
964 InvalidateRect(_hwnd
, 0, TRUE
);
965 MenuInfo
* menu_info
= Frame_GetMenuInfo(GetParent(_hwnd
));
967 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_NAME
, MF_BYCOMMAND
);
968 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_ALL_ATTRIBUTES
, MF_BYCOMMAND
|MF_CHECKED
);
969 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_SELECTED_ATTRIBUTES
, MF_BYCOMMAND
);
974 case ID_PREFERED_SIZES
: {
977 InvalidateRect(_hwnd
, 0, TRUE
);
980 /*@todo more command ids... */
989 MainFrameBase
* Pane::get_frame()
991 HWND owner
= GetParent(_hwnd
);
993 return (MainFrameBase
*)owner
;