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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 // Martin Fuchs, 23.07.2003
32 IMG_NONE
=-1, IMG_FILE
=0, IMG_DOCUMENT
, IMG_EXECUTABLE
,
33 IMG_FOLDER
, IMG_OPEN_FOLDER
, IMG_FOLDER_PLUS
,IMG_OPEN_PLUS
, IMG_OPEN_MINUS
,
34 IMG_FOLDER_UP
, IMG_FOLDER_CUR
38 #define IMAGE_WIDTH 16
39 #define IMAGE_HEIGHT 13
42 static const TCHAR
* g_pos_names
[COLUMNS
] = {
43 TEXT(""), /* symbol */
57 static const int g_pos_align
[] = {
66 HDF_RIGHT
, /* Links */
67 HDF_CENTER
, /* Attributes */
68 HDF_LEFT
, /* Security */
69 HDF_LEFT
/* Content / Description */
73 Pane::Pane(HWND hparent
, int id
, int id_header
, Entry
* root
, bool treePane
, int visible_cols
)
74 : super(CreateWindow(TEXT("ListBox"), TEXT(""), WS_CHILD
|WS_VISIBLE
|WS_HSCROLL
|WS_VSCROLL
|
75 LBS_DISABLENOSCROLL
|LBS_NOINTEGRALHEIGHT
|LBS_OWNERDRAWFIXED
|LBS_NOTIFY
,
76 0, 0, 0, 0, hparent
, (HMENU
)id
, g_Globals
._hInstance
, 0)),
78 _visible_cols(visible_cols
),
81 // insert entries into listbox
85 insert_entries(entry
);
89 create_header(hparent
, id_header
);
94 ImageList_Destroy(_himl
);
98 LRESULT
Pane::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
106 FileChildWindow
* child
= (FileChildWindow
*) SendMessage(GetParent(_hwnd
), PM_GET_FILEWND_PTR
, 0, 0);
108 child
->set_focus_pane(this);
109 ListBox_SetSel(_hwnd
, TRUE
, 1);
110 /*@todo check menu items */
114 FileChildWindow
* child
= (FileChildWindow
*) SendMessage(GetParent(_hwnd
), PM_GET_FILEWND_PTR
, 0, 0);
116 if (wparam
== VK_TAB
) {
117 /*@todo SetFocus(g_Globals.hdrivebar) */
118 child
->switch_focus_pane();
123 return super::WndProc(nmsg
, wparam
, lparam
);
127 bool Pane::create_header(HWND hparent
, int id
)
129 HWND hwnd
= CreateWindow(WC_HEADER
, 0, WS_CHILD
|WS_VISIBLE
|HDS_HORZ
/*@todo |HDS_BUTTONS + sort orders*/,
130 0, 0, 0, 0, hparent
, (HMENU
)id
, g_Globals
._hInstance
, 0);
134 SetWindowFont(hwnd
, GetStockFont(DEFAULT_GUI_FONT
), FALSE
);
138 hdi
.mask
= HDI_TEXT
|HDI_WIDTH
|HDI_FORMAT
;
140 for(int idx
=0; idx
<COLUMNS
; idx
++) {
141 hdi
.pszText
= (TCHAR
*)g_pos_names
[idx
];
142 hdi
.fmt
= HDF_STRING
| g_pos_align
[idx
];
143 hdi
.cxy
= _widths
[idx
];
144 Header_InsertItem(hwnd
, idx
, &hdi
);
155 _himl
= ImageList_LoadBitmap(g_Globals
._hInstance
, MAKEINTRESOURCE(IDB_IMAGES
), 16, 0, RGB(0,255,0));
157 SetWindowFont(_hwnd
, _out_wrkr
._hfont
, FALSE
);
159 // read the color for compressed files from registry
160 HKEY hkeyExplorer
= 0;
161 DWORD len
= sizeof(_clrCompressed
);
163 if (RegOpenKey(HKEY_CURRENT_USER
, TEXT("SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer"), &hkeyExplorer
) ||
164 RegQueryValueEx(hkeyExplorer
, TEXT("AltColor"), 0, NULL
, (LPBYTE
)&_clrCompressed
, &len
) || len
!=sizeof(_clrCompressed
))
165 _clrCompressed
= RGB(0,0,255);
168 RegCloseKey(hkeyExplorer
);
170 // calculate column widths
171 _out_wrkr
.init_output(_hwnd
);
176 // calculate prefered width for all visible columns
178 bool Pane::calc_widths(bool anyway
)
180 int col
, x
, cx
, spc
=3*_out_wrkr
._spaceSize
.cx
;
181 int entries
= ListBox_GetCount(_hwnd
);
182 int orgWidths
[COLUMNS
];
183 int orgPositions
[COLUMNS
+1];
189 memcpy(orgWidths
, _widths
, sizeof(orgWidths
));
190 memcpy(orgPositions
, _positions
, sizeof(orgPositions
));
193 for(col
=0; col
<COLUMNS
; col
++)
197 hfontOld
= SelectFont(hdc
, _out_wrkr
._hfont
);
199 for(cnt
=0; cnt
<entries
; cnt
++) {
200 Entry
* entry
= (Entry
*) ListBox_GetItemData(_hwnd
, cnt
);
209 dis
.hwndItem
= _hwnd
;
213 dis
.rcItem
.right
= 0;
214 dis
.rcItem
.bottom
= 0;
215 /*dis.itemData = 0; */
217 draw_item(&dis
, entry
, COLUMNS
);
220 SelectObject(hdc
, hfontOld
);
221 ReleaseDC(_hwnd
, hdc
);
224 for(col
=0; col
<COLUMNS
; col
++) {
231 if (cx
< IMAGE_WIDTH
)
240 _positions
[COLUMNS
] = x
;
242 ListBox_SetHorizontalExtent(_hwnd
, x
);
245 if (!memcmp(orgWidths
, _widths
, sizeof(orgWidths
)))
248 // don't move, if only collapsing an entry
249 if (!anyway
&& _widths
[0]<orgWidths
[0] &&
250 !memcmp(orgWidths
+1, _widths
+1, sizeof(orgWidths
)-sizeof(int))) {
251 _widths
[0] = orgWidths
[0];
252 memcpy(_positions
, orgPositions
, sizeof(orgPositions
));
257 InvalidateRect(_hwnd
, 0, TRUE
);
263 static void format_date(const FILETIME
* ft
, TCHAR
* buffer
, int visible_cols
)
269 *buffer
= TEXT('\0');
271 if (!ft
->dwLowDateTime
&& !ft
->dwHighDateTime
)
274 if (!FileTimeToLocalFileTime(ft
, &lft
))
275 {err
: lstrcpy(buffer
,TEXT("???")); return;}
277 if (!FileTimeToSystemTime(&lft
, &systime
))
280 if (visible_cols
& COL_DATE
) {
281 len
= GetDateFormat(LOCALE_USER_DEFAULT
, 0, &systime
, 0, buffer
, BUFFER_LEN
);
286 if (visible_cols
& COL_TIME
) {
292 if (!GetTimeFormat(LOCALE_USER_DEFAULT
, 0, &systime
, 0, buffer
+len
, BUFFER_LEN
-len
))
293 buffer
[len
] = TEXT('\0');
298 void Pane::draw_item(LPDRAWITEMSTRUCT dis
, Entry
* entry
, int calcWidthCol
)
300 TCHAR buffer
[BUFFER_LEN
];
302 int visible_cols
= _visible_cols
;
303 COLORREF bkcolor
, textcolor
;
304 RECT focusRect
= dis
->rcItem
;
310 attrs
= entry
->_data
.dwFileAttributes
;
312 if (attrs
& FILE_ATTRIBUTE_DIRECTORY
) {
313 if (entry
->_data
.cFileName
[0]==TEXT('.') && entry
->_data
.cFileName
[1]==TEXT('.')
314 && entry
->_data
.cFileName
[2]==TEXT('\0'))
316 else if (entry
->_data
.cFileName
[0]==TEXT('.') && entry
->_data
.cFileName
[1]==TEXT('\0'))
317 img
= IMG_FOLDER_CUR
;
318 else if ((_treePane
&& (dis
->itemState
&ODS_FOCUS
)))
319 img
= IMG_OPEN_FOLDER
;
323 if (attrs
& ATTRIBUTE_EXECUTABLE
)
324 img
= IMG_EXECUTABLE
;
325 else if (entry
->_type_name
)
337 img_pos
= dis
->rcItem
.left
+ entry
->_level
*(IMAGE_WIDTH
+_out_wrkr
._spaceSize
.cx
);
339 if (calcWidthCol
== -1) {
341 int y
= dis
->rcItem
.top
+ IMAGE_HEIGHT
/2;
344 HRGN hrgn_org
= CreateRectRgn(0, 0, 0, 0);
347 rt_clip
.left
= dis
->rcItem
.left
;
348 rt_clip
.top
= dis
->rcItem
.top
;
349 rt_clip
.right
= dis
->rcItem
.left
+_widths
[col
];
350 rt_clip
.bottom
= dis
->rcItem
.bottom
;
352 hrgn
= CreateRectRgnIndirect(&rt_clip
);
354 if (!GetClipRgn(dis
->hDC
, hrgn_org
)) {
355 DeleteObject(hrgn_org
);
359 //HGDIOBJ holdPen = SelectObject(dis->hDC, GetStockObject(BLACK_PEN));
360 ExtSelectClipRgn(dis
->hDC
, hrgn
, RGN_AND
);
363 if ((up
=entry
->_up
) != NULL
) {
364 MoveToEx(dis
->hDC
, img_pos
-IMAGE_WIDTH
/2, y
, 0);
365 LineTo(dis
->hDC
, img_pos
-2, y
);
367 x
= img_pos
- IMAGE_WIDTH
/2;
370 x
-= IMAGE_WIDTH
+_out_wrkr
._spaceSize
.cx
;
374 bool following_child
= (up
->_next
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)!=0; // a directory?
376 if (!following_child
)
378 for(Entry
*n
=up
->_next
; n
; n
=n
->_next
)
379 if (n
->_down
) { // any file with NTFS sub-streams?
380 following_child
= true;
387 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
, 0);
388 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
391 } while((up
=up
->_up
) != NULL
);
394 x
= img_pos
- IMAGE_WIDTH
/2;
396 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
, 0);
397 LineTo(dis
->hDC
, x
, y
);
401 bool following_child
= (entry
->_next
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)!=0; // a directory?
403 if (!following_child
)
405 for(Entry
*n
=entry
->_next
; n
; n
=n
->_next
)
406 if (n
->_down
) { // any file with NTFS sub-streams?
407 following_child
= true;
413 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
416 if (entry
->_down
&& entry
->_expanded
) {
417 x
+= IMAGE_WIDTH
+ _out_wrkr
._spaceSize
.cx
;
418 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
+IMAGE_HEIGHT
, 0);
419 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
422 SelectClipRgn(dis
->hDC
, hrgn_org
);
423 if (hrgn_org
) DeleteObject(hrgn_org
);
424 //SelectObject(dis->hDC, holdPen);
425 } else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
) {
426 int right
= img_pos
+ IMAGE_WIDTH
- _out_wrkr
._spaceSize
.cx
;
428 if (right
> _widths
[col
])
429 _widths
[col
] = right
;
432 img_pos
= dis
->rcItem
.left
;
435 img_pos
= dis
->rcItem
.left
;
437 if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
438 _widths
[col
] = IMAGE_WIDTH
;
441 if (calcWidthCol
== -1) {
442 focusRect
.left
= img_pos
-2;
444 if (attrs
& FILE_ATTRIBUTE_COMPRESSED
)
445 textcolor
= _clrCompressed
;
447 textcolor
= RGB(0,0,0);
449 if (dis
->itemState
& ODS_FOCUS
) {
450 textcolor
= GetSysColor(COLOR_HIGHLIGHTTEXT
);
451 bkcolor
= GetSysColor(COLOR_HIGHLIGHT
);
453 bkcolor
= GetSysColor(COLOR_WINDOW
);
456 HBRUSH hbrush
= CreateSolidBrush(bkcolor
);
457 FillRect(dis
->hDC
, &focusRect
, hbrush
);
458 DeleteObject(hbrush
);
460 SetBkMode(dis
->hDC
, TRANSPARENT
);
461 SetTextColor(dis
->hDC
, textcolor
);
465 if (cx
&& img
!=IMG_NONE
) {
466 if (cx
> IMAGE_WIDTH
)
469 if (entry
->_icon_id
> ICID_NONE
)
470 g_Globals
._icon_cache
.get_icon(entry
->_icon_id
).draw(dis
->hDC
, img_pos
, dis
->rcItem
.top
, cx
, GetSystemMetrics(SM_CYSMICON
), bkcolor
, 0);
472 ImageList_DrawEx(_himl
, img
, dis
->hDC
,
473 img_pos
, dis
->rcItem
.top
, cx
,
474 IMAGE_HEIGHT
, bkcolor
, CLR_DEFAULT
, ILD_NORMAL
);
484 if (calcWidthCol
== -1)
485 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_display_name
, 0);
486 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
487 calc_width(dis
, col
, entry
->_display_name
);
490 // output type/class name
491 if (visible_cols
& COL_TYPE
) {
492 if (calcWidthCol
== -1)
493 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_type_name
? entry
->_type_name
: TEXT(""), 0);
494 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
495 calc_width(dis
, col
, entry
->_type_name
? entry
->_type_name
: TEXT(""));
500 if (visible_cols
& COL_SIZE
) {
501 ULONGLONG size
= ((ULONGLONG
)entry
->_data
.nFileSizeHigh
<< 32) | entry
->_data
.nFileSizeLow
;
503 _stprintf(buffer
, TEXT("%") LONGLONGARG
TEXT("d"), size
);
505 if (calcWidthCol
== -1)
506 _out_wrkr
.output_number(dis
, _positions
, col
, buffer
);
507 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
508 calc_width(dis
, col
, buffer
); ///@todo not in every case time enough
513 if (visible_cols
& (COL_DATE
|COL_TIME
)) {
514 format_date(&entry
->_data
.ftCreationTime
, buffer
, visible_cols
);
515 if (calcWidthCol
== -1)
516 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, 0);
517 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
518 calc_width(dis
, col
, buffer
);
521 format_date(&entry
->_data
.ftLastAccessTime
, buffer
, visible_cols
);
522 if (calcWidthCol
== -1)
523 _out_wrkr
.output_text(dis
,_positions
, col
, buffer
, 0);
524 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
525 calc_width(dis
, col
, buffer
);
528 format_date(&entry
->_data
.ftLastWriteTime
, buffer
, visible_cols
);
529 if (calcWidthCol
== -1)
530 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, 0);
531 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
532 calc_width(dis
, col
, buffer
);
537 if (entry
->_bhfi_valid
) {
538 ULONGLONG index
= ((ULONGLONG
)entry
->_bhfi
.nFileIndexHigh
<< 32) | entry
->_bhfi
.nFileIndexLow
;
540 if (visible_cols
& COL_INDEX
) {
541 _stprintf(buffer
, TEXT("%") LONGLONGARG
TEXT("X"), index
);
543 if (calcWidthCol
== -1)
544 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, DT_RIGHT
);
545 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
546 calc_width(dis
, col
, buffer
);
551 if (visible_cols
& COL_LINKS
) {
552 wsprintf(buffer
, TEXT("%d"), entry
->_bhfi
.nNumberOfLinks
);
554 if (calcWidthCol
== -1)
555 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, DT_RIGHT
);
556 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
557 calc_width(dis
, col
, buffer
);
564 // show file attributes
565 if (visible_cols
& COL_ATTRIBUTES
) {
566 lstrcpy(buffer
, TEXT(" \t \t \t \t \t \t \t \t \t \t \t \t \t \t "));
568 if (attrs
& FILE_ATTRIBUTE_NORMAL
) buffer
[ 0] = 'N';
570 if (attrs
& FILE_ATTRIBUTE_READONLY
) buffer
[ 2] = 'R';
571 if (attrs
& FILE_ATTRIBUTE_HIDDEN
) buffer
[ 4] = 'H';
572 if (attrs
& FILE_ATTRIBUTE_SYSTEM
) buffer
[ 6] = 'S';
573 if (attrs
& FILE_ATTRIBUTE_ARCHIVE
) buffer
[ 8] = 'A';
574 if (attrs
& FILE_ATTRIBUTE_COMPRESSED
) buffer
[10] = 'C';
575 if (attrs
& FILE_ATTRIBUTE_DIRECTORY
) buffer
[12] = 'D';
576 if (attrs
& FILE_ATTRIBUTE_ENCRYPTED
) buffer
[14] = 'E';
577 if (attrs
& FILE_ATTRIBUTE_TEMPORARY
) buffer
[16] = 'T';
578 if (attrs
& FILE_ATTRIBUTE_SPARSE_FILE
) buffer
[18] = 'P';
579 if (attrs
& FILE_ATTRIBUTE_REPARSE_POINT
) buffer
[20] = 'Q';
580 if (attrs
& FILE_ATTRIBUTE_OFFLINE
) buffer
[22] = 'O';
581 if (attrs
& FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
) buffer
[24] = 'X';
582 if (attrs
& ATTRIBUTE_EXECUTABLE
) buffer
[26] = 'x';
583 if (attrs
& ATTRIBUTE_SYMBOLIC_LINK
) buffer
[28] = 'L';
586 if (calcWidthCol
== -1)
587 _out_wrkr
.output_tabbed_text(dis
, _positions
, col
, buffer
);
588 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
589 calc_tabbed_width(dis
, col
, buffer
);
594 if (flags.security) {
595 DWORD rights = get_access_mask();
597 tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t "));
599 if (rights & FILE_READ_DATA) buffer[ 0] = 'R';
600 if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W';
601 if (rights & FILE_APPEND_DATA) buffer[ 4] = 'A';
602 if (rights & FILE_READ_EA) {buffer[6] = 'entry'; buffer[ 7] = 'R';}
603 if (rights & FILE_WRITE_EA) {buffer[9] = 'entry'; buffer[10] = 'W';}
604 if (rights & FILE_EXECUTE) buffer[12] = 'X';
605 if (rights & FILE_DELETE_CHILD) buffer[14] = 'D';
606 if (rights & FILE_READ_ATTRIBUTES) {buffer[16] = 'a'; buffer[17] = 'R';}
607 if (rights & FILE_WRITE_ATTRIBUTES) {buffer[19] = 'a'; buffer[20] = 'W';}
608 if (rights & WRITE_DAC) buffer[22] = 'C';
609 if (rights & WRITE_OWNER) buffer[24] = 'O';
610 if (rights & SYNCHRONIZE) buffer[26] = 'S';
612 output_text(dis, col++, buffer, DT_LEFT, 3, psize);
615 if (flags.description) {
616 get_description(buffer);
617 output_text(dis, col++, buffer, 0, psize);
622 // output content / symbolic link target / comment
623 if (visible_cols
& COL_CONTENT
) {
624 if (calcWidthCol
== -1)
625 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_content
? entry
->_content
: TEXT(""), 0);
626 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
627 calc_width(dis
, col
, entry
->_content
? entry
->_content
: TEXT(""));
632 void Pane::calc_width(LPDRAWITEMSTRUCT dis
, int col
, LPCTSTR str
)
634 RECT rt
= {0, 0, 0, 0};
636 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_CALCRECT
|DT_SINGLELINE
|DT_NOPREFIX
);
638 if (rt
.right
> _widths
[col
])
639 _widths
[col
] = rt
.right
;
642 void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis
, int col
, LPCTSTR str
)
644 RECT rt
= {0, 0, 0, 0};
646 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2};
647 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
649 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_CALCRECT
|DT_SINGLELINE
|DT_EXPANDTABS
|DT_TABSTOP
|(2<<8));
651 if (rt
.right
> _widths
[col
])
652 _widths
[col
] = rt
.right
;
656 // insert listbox entries after index idx
658 int Pane::insert_entries(Entry
* dir
, int idx
)
665 for(; entry
; entry
=entry
->_next
) {
668 !(entry
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
) && // not a directory?
669 !entry
->_down
) // not a file with NTFS sub-streams?
673 // don't display entries "." and ".." in the left pane
674 if (_treePane
&& (entry
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)
675 && entry
->_data
.cFileName
[0]==TEXT('.'))
676 if (entry
->_data
.cFileName
[1]==TEXT('\0') ||
677 (entry
->_data
.cFileName
[1]==TEXT('.') && entry
->_data
.cFileName
[2]==TEXT('\0')))
683 ListBox_InsertItemData(_hwnd
, idx
, entry
);
685 if (_treePane
&& entry
->_expanded
)
686 idx
= insert_entries(entry
->_down
, idx
);
693 void Pane::set_header()
696 int scroll_pos
= GetScrollPos(_hwnd
, SB_HORZ
);
699 item
.mask
= HDI_WIDTH
;
702 for(; i
<COLUMNS
; i
++) {
703 if (x
+ _widths
[i
] >= scroll_pos
)
707 Header_SetItem(_hwndHeader
, i
, &item
);
712 item
.cxy
= x
- scroll_pos
;
713 Header_SetItem(_hwndHeader
, i
++, &item
);
715 for(; i
<COLUMNS
; i
++) {
716 item
.cxy
= _widths
[i
];
718 Header_SetItem(_hwndHeader
, i
, &item
);
724 // calculate one prefered column width
726 void Pane::calc_single_width(int col
)
733 int entries
= ListBox_GetCount(_hwnd
);
738 hfontOld
= SelectFont(hdc
, _out_wrkr
._hfont
);
740 for(cnt
=0; cnt
<entries
; cnt
++) {
741 Entry
* entry
= (Entry
*) ListBox_GetItemData(_hwnd
, cnt
);
750 dis
.hwndItem
= _hwnd
;
754 dis
.rcItem
.right
= 0;
755 dis
.rcItem
.bottom
= 0;
756 /*dis.itemData = 0; */
758 draw_item(&dis
, entry
, col
);
761 SelectObject(hdc
, hfontOld
);
762 ReleaseDC(_hwnd
, hdc
);
767 cx
+= 3*_out_wrkr
._spaceSize
.cx
;
769 if (cx
< IMAGE_WIDTH
)
775 x
= _positions
[col
] + cx
;
777 for(; col
<COLUMNS
; col
++) {
778 _positions
[col
+1] = x
;
782 ListBox_SetHorizontalExtent(_hwnd
, x
);
786 int Pane::Notify(int id
, NMHDR
* pnmh
)
791 HD_NOTIFY
* phdn
= (HD_NOTIFY
*) pnmh
;
792 int idx
= phdn
->iItem
;
793 int dx
= phdn
->pitem
->cxy
- _widths
[idx
];
796 ClientRect
clnt(_hwnd
);
798 // move immediate to simulate HDS_FULLDRAG (for now [04/2000] not realy needed with WINELIB)
799 Header_SetItem(_hwndHeader
, idx
, phdn
->pitem
);
803 for(i
=idx
; ++i
<=COLUMNS
; )
807 int scroll_pos
= GetScrollPos(_hwnd
, SB_HORZ
);
811 rt_scr
.left
= _positions
[idx
+1]-scroll_pos
;
813 rt_scr
.right
= clnt
.right
;
814 rt_scr
.bottom
= clnt
.bottom
;
816 rt_clip
.left
= _positions
[idx
]-scroll_pos
;
818 rt_clip
.right
= clnt
.right
;
819 rt_clip
.bottom
= clnt
.bottom
;
821 if (rt_scr
.left
< 0) rt_scr
.left
= 0;
822 if (rt_clip
.left
< 0) rt_clip
.left
= 0;
824 ScrollWindowEx(_hwnd
, dx
, 0, &rt_scr
, &rt_clip
, 0, 0, SW_INVALIDATE
);
826 rt_clip
.right
= _positions
[idx
+1];
827 RedrawWindow(_hwnd
, &rt_clip
, 0, RDW_INVALIDATE
|RDW_UPDATENOW
);
829 if (pnmh
->code
== HDN_ENDTRACK
) {
830 ListBox_SetHorizontalExtent(_hwnd
, _positions
[COLUMNS
]);
832 if (GetScrollPos(_hwnd
, SB_HORZ
) != scroll_pos
)
840 case HDN_DIVIDERDBLCLICK
: {
841 HD_NOTIFY
* phdn
= (HD_NOTIFY
*) pnmh
;
844 calc_single_width(phdn
->iItem
);
845 item
.mask
= HDI_WIDTH
;
846 item
.cxy
= _widths
[phdn
->iItem
];
848 Header_SetItem(_hwndHeader
, phdn
->iItem
, &item
);
849 InvalidateRect(_hwnd
, 0, TRUE
);
853 return super::Notify(id
, pnmh
);
860 OutputWorker::OutputWorker()
862 _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"));
865 void OutputWorker::init_output(HWND hwnd
)
869 WindowCanvas
canvas(hwnd
);
871 if (GetNumberFormat(LOCALE_USER_DEFAULT
, 0, TEXT("1000"), 0, b
, 16) > 4)
874 _num_sep
= TEXT('.');
876 FontSelection
font(canvas
, _hfont
);
877 GetTextExtentPoint32(canvas
, TEXT(" "), 1, &_spaceSize
);
881 void OutputWorker::output_text(LPDRAWITEMSTRUCT dis
, int* positions
, int col
, LPCTSTR str
, DWORD flags
)
883 int x
= dis
->rcItem
.left
;
886 rt
.left
= x
+positions
[col
]+_spaceSize
.cx
;
887 rt
.top
= dis
->rcItem
.top
;
888 rt
.right
= x
+positions
[col
+1]-_spaceSize
.cx
;
889 rt
.bottom
= dis
->rcItem
.bottom
;
891 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_SINGLELINE
|DT_NOPREFIX
|flags
);
894 void OutputWorker::output_tabbed_text(LPDRAWITEMSTRUCT dis
, int* positions
, int col
, LPCTSTR str
)
896 int x
= dis
->rcItem
.left
;
899 rt
.left
= x
+positions
[col
]+_spaceSize
.cx
;
900 rt
.top
= dis
->rcItem
.top
;
901 rt
.right
= x
+positions
[col
+1]-_spaceSize
.cx
;
902 rt
.bottom
= dis
->rcItem
.bottom
;
904 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2};
905 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
907 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_SINGLELINE
|DT_EXPANDTABS
|DT_TABSTOP
|(2<<8));
910 void OutputWorker::output_number(LPDRAWITEMSTRUCT dis
, int* positions
, int col
, LPCTSTR str
)
912 int x
= dis
->rcItem
.left
;
919 rt
.left
= x
+positions
[col
]+_spaceSize
.cx
;
920 rt
.top
= dis
->rcItem
.top
;
921 rt
.right
= x
+positions
[col
+1]-_spaceSize
.cx
;
922 rt
.bottom
= dis
->rcItem
.bottom
;
927 // insert number separator characters
928 pos
= lstrlen(s
) % 3;
938 DrawText(dis
->hDC
, b
, d
-b
, &rt
, DT_RIGHT
|DT_SINGLELINE
|DT_NOPREFIX
|DT_END_ELLIPSIS
);
942 BOOL
Pane::command(UINT cmd
)
950 InvalidateRect(_hwnd
, 0, TRUE
);
951 MenuInfo
* menu_info
= Frame_GetMenuInfo(GetParent(_hwnd
));
953 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_NAME
, MF_BYCOMMAND
|MF_CHECKED
);
954 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_ALL_ATTRIBUTES
, MF_BYCOMMAND
);
955 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_SELECTED_ATTRIBUTES
, MF_BYCOMMAND
);
960 case ID_VIEW_ALL_ATTRIBUTES
:
961 if (_visible_cols
!= COL_ALL
) {
962 _visible_cols
= COL_ALL
;
965 InvalidateRect(_hwnd
, 0, TRUE
);
966 MenuInfo
* menu_info
= Frame_GetMenuInfo(GetParent(_hwnd
));
968 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_NAME
, MF_BYCOMMAND
);
969 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_ALL_ATTRIBUTES
, MF_BYCOMMAND
|MF_CHECKED
);
970 CheckMenuItem(menu_info
->_hMenuView
, ID_VIEW_SELECTED_ATTRIBUTES
, MF_BYCOMMAND
);
975 case ID_PREFERED_SIZES
: {
978 InvalidateRect(_hwnd
, 0, TRUE
);
981 /*@todo more command ids... */
990 MainFrameBase
* Pane::get_frame()
992 HWND owner
= GetParent(_hwnd
);
994 return (MainFrameBase
*)owner
;