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
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 TCHAR
* 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
= (TCHAR
*)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
)
381 for(Entry
*n
=up
->_next
; n
; n
=n
->_next
)
382 if (n
->_down
) { // any file with NTFS sub-streams?
383 following_child
= true;
390 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
, 0);
391 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
394 } while((up
=up
->_up
) != NULL
);
397 x
= img_pos
- IMAGE_WIDTH
/2;
399 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
, 0);
400 LineTo(dis
->hDC
, x
, y
);
404 bool following_child
= (entry
->_next
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)!=0; // a directory?
406 if (!following_child
)
408 for(Entry
*n
=entry
->_next
; n
; n
=n
->_next
)
409 if (n
->_down
) { // any file with NTFS sub-streams?
410 following_child
= true;
416 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
419 if (entry
->_down
&& entry
->_expanded
) {
420 x
+= IMAGE_WIDTH
+ _out_wrkr
._spaceSize
.cx
;
421 MoveToEx(dis
->hDC
, x
, dis
->rcItem
.top
+IMAGE_HEIGHT
, 0);
422 LineTo(dis
->hDC
, x
, dis
->rcItem
.bottom
);
425 SelectClipRgn(dis
->hDC
, hrgn_org
);
426 if (hrgn_org
) DeleteObject(hrgn_org
);
427 //SelectObject(dis->hDC, holdPen);
428 } else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
) {
429 int right
= img_pos
+ IMAGE_WIDTH
- _out_wrkr
._spaceSize
.cx
;
431 if (right
> _widths
[col
])
432 _widths
[col
] = right
;
435 img_pos
= dis
->rcItem
.left
;
438 img_pos
= dis
->rcItem
.left
;
440 if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
441 _widths
[col
] = IMAGE_WIDTH
;
444 if (calcWidthCol
== -1) {
445 focusRect
.left
= img_pos
-2;
447 if (attrs
& FILE_ATTRIBUTE_COMPRESSED
)
448 textcolor
= _clrCompressed
;
450 textcolor
= RGB(0,0,0);
452 if (dis
->itemState
& ODS_FOCUS
) {
453 textcolor
= GetSysColor(COLOR_HIGHLIGHTTEXT
);
454 bkcolor
= GetSysColor(COLOR_HIGHLIGHT
);
456 bkcolor
= GetSysColor(COLOR_WINDOW
);
459 HBRUSH hbrush
= CreateSolidBrush(bkcolor
);
460 FillRect(dis
->hDC
, &focusRect
, hbrush
);
461 DeleteObject(hbrush
);
463 SetBkMode(dis
->hDC
, TRANSPARENT
);
464 SetTextColor(dis
->hDC
, textcolor
);
468 if (cx
&& img
!=IMG_NONE
) {
469 if (cx
> IMAGE_WIDTH
)
472 if (entry
->_icon_id
> ICID_NONE
)
473 g_Globals
._icon_cache
.get_icon(entry
->_icon_id
).draw(dis
->hDC
, img_pos
, dis
->rcItem
.top
, cx
, GetSystemMetrics(SM_CYSMICON
), bkcolor
, 0);
475 ImageList_DrawEx(_himl
, img
, dis
->hDC
,
476 img_pos
, dis
->rcItem
.top
, cx
,
477 IMAGE_HEIGHT
, bkcolor
, CLR_DEFAULT
, ILD_NORMAL
);
487 if (calcWidthCol
== -1)
488 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_display_name
, 0);
489 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
490 calc_width(dis
, col
, entry
->_display_name
);
493 // output type/class name
494 if (visible_cols
& COL_TYPE
) {
495 if (calcWidthCol
== -1)
496 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_type_name
? entry
->_type_name
: TEXT(""), 0);
497 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
498 calc_width(dis
, col
, entry
->_type_name
? entry
->_type_name
: TEXT(""));
503 if (visible_cols
& COL_SIZE
) {
504 ULONGLONG size
= ((ULONGLONG
)entry
->_data
.nFileSizeHigh
<< 32) | entry
->_data
.nFileSizeLow
;
506 _stprintf(buffer
, TEXT("%") LONGLONGARG
TEXT("d"), size
);
508 if (calcWidthCol
== -1)
509 _out_wrkr
.output_number(dis
, _positions
, col
, buffer
);
510 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
511 calc_width(dis
, col
, buffer
); ///@todo not in every case time enough
516 if (visible_cols
& (COL_DATE
|COL_TIME
)) {
517 format_date(&entry
->_data
.ftCreationTime
, buffer
, visible_cols
);
518 if (calcWidthCol
== -1)
519 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, 0);
520 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
521 calc_width(dis
, col
, buffer
);
524 format_date(&entry
->_data
.ftLastAccessTime
, buffer
, visible_cols
);
525 if (calcWidthCol
== -1)
526 _out_wrkr
.output_text(dis
,_positions
, col
, buffer
, 0);
527 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
528 calc_width(dis
, col
, buffer
);
531 format_date(&entry
->_data
.ftLastWriteTime
, buffer
, visible_cols
);
532 if (calcWidthCol
== -1)
533 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, 0);
534 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
535 calc_width(dis
, col
, buffer
);
540 if (entry
->_bhfi_valid
) {
541 ULONGLONG index
= ((ULONGLONG
)entry
->_bhfi
.nFileIndexHigh
<< 32) | entry
->_bhfi
.nFileIndexLow
;
543 if (visible_cols
& COL_INDEX
) {
544 _stprintf(buffer
, TEXT("%") LONGLONGARG
TEXT("X"), index
);
546 if (calcWidthCol
== -1)
547 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, DT_RIGHT
);
548 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
549 calc_width(dis
, col
, buffer
);
554 if (visible_cols
& COL_LINKS
) {
555 wsprintf(buffer
, TEXT("%d"), entry
->_bhfi
.nNumberOfLinks
);
557 if (calcWidthCol
== -1)
558 _out_wrkr
.output_text(dis
, _positions
, col
, buffer
, DT_RIGHT
);
559 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
560 calc_width(dis
, col
, buffer
);
567 // show file attributes
568 if (visible_cols
& COL_ATTRIBUTES
) {
569 lstrcpy(buffer
, TEXT(" \t \t \t \t \t \t \t \t \t \t \t \t \t \t "));
571 if (attrs
& FILE_ATTRIBUTE_NORMAL
) buffer
[ 0] = 'N';
573 if (attrs
& FILE_ATTRIBUTE_READONLY
) buffer
[ 2] = 'R';
574 if (attrs
& FILE_ATTRIBUTE_HIDDEN
) buffer
[ 4] = 'H';
575 if (attrs
& FILE_ATTRIBUTE_SYSTEM
) buffer
[ 6] = 'S';
576 if (attrs
& FILE_ATTRIBUTE_ARCHIVE
) buffer
[ 8] = 'A';
577 if (attrs
& FILE_ATTRIBUTE_COMPRESSED
) buffer
[10] = 'C';
578 if (attrs
& FILE_ATTRIBUTE_DIRECTORY
) buffer
[12] = 'D';
579 if (attrs
& FILE_ATTRIBUTE_ENCRYPTED
) buffer
[14] = 'E';
580 if (attrs
& FILE_ATTRIBUTE_TEMPORARY
) buffer
[16] = 'T';
581 if (attrs
& FILE_ATTRIBUTE_SPARSE_FILE
) buffer
[18] = 'P';
582 if (attrs
& FILE_ATTRIBUTE_REPARSE_POINT
) buffer
[20] = 'Q';
583 if (attrs
& FILE_ATTRIBUTE_OFFLINE
) buffer
[22] = 'O';
584 if (attrs
& FILE_ATTRIBUTE_NOT_CONTENT_INDEXED
) buffer
[24] = 'X';
585 if (attrs
& ATTRIBUTE_EXECUTABLE
) buffer
[26] = 'x';
586 if (attrs
& ATTRIBUTE_SYMBOLIC_LINK
) buffer
[28] = 'L';
589 if (calcWidthCol
== -1)
590 _out_wrkr
.output_tabbed_text(dis
, _positions
, col
, buffer
);
591 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
592 calc_tabbed_width(dis
, col
, buffer
);
597 if (flags.security) {
598 DWORD rights = get_access_mask();
600 tcscpy(buffer, TEXT(" \t \t \t \t \t \t \t \t \t \t \t "));
602 if (rights & FILE_READ_DATA) buffer[ 0] = 'R';
603 if (rights & FILE_WRITE_DATA) buffer[ 2] = 'W';
604 if (rights & FILE_APPEND_DATA) buffer[ 4] = 'A';
605 if (rights & FILE_READ_EA) {buffer[6] = 'entry'; buffer[ 7] = 'R';}
606 if (rights & FILE_WRITE_EA) {buffer[9] = 'entry'; buffer[10] = 'W';}
607 if (rights & FILE_EXECUTE) buffer[12] = 'X';
608 if (rights & FILE_DELETE_CHILD) buffer[14] = 'D';
609 if (rights & FILE_READ_ATTRIBUTES) {buffer[16] = 'a'; buffer[17] = 'R';}
610 if (rights & FILE_WRITE_ATTRIBUTES) {buffer[19] = 'a'; buffer[20] = 'W';}
611 if (rights & WRITE_DAC) buffer[22] = 'C';
612 if (rights & WRITE_OWNER) buffer[24] = 'O';
613 if (rights & SYNCHRONIZE) buffer[26] = 'S';
615 output_text(dis, col++, buffer, DT_LEFT, 3, psize);
618 if (flags.description) {
619 get_description(buffer);
620 output_text(dis, col++, buffer, 0, psize);
625 // output content / symbolic link target / comment
626 if (visible_cols
& COL_CONTENT
) {
627 if (calcWidthCol
== -1)
628 _out_wrkr
.output_text(dis
, _positions
, col
, entry
->_content
? entry
->_content
: TEXT(""), 0);
629 else if (calcWidthCol
==col
|| calcWidthCol
==COLUMNS
)
630 calc_width(dis
, col
, entry
->_content
? entry
->_content
: TEXT(""));
635 void Pane::calc_width(LPDRAWITEMSTRUCT dis
, int col
, LPCTSTR str
)
637 RECT rt
= {0, 0, 0, 0};
639 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_CALCRECT
|DT_SINGLELINE
|DT_NOPREFIX
);
641 if (rt
.right
> _widths
[col
])
642 _widths
[col
] = rt
.right
;
645 void Pane::calc_tabbed_width(LPDRAWITEMSTRUCT dis
, int col
, LPCTSTR str
)
647 RECT rt
= {0, 0, 0, 0};
649 /* DRAWTEXTPARAMS dtp = {sizeof(DRAWTEXTPARAMS), 2};
650 DrawTextEx(dis->hDC, (LPTSTR)str, -1, &rt, DT_CALCRECT|DT_SINGLELINE|DT_NOPREFIX|DT_EXPANDTABS|DT_TABSTOP, &dtp);*/
652 DrawText(dis
->hDC
, (LPTSTR
)str
, -1, &rt
, DT_CALCRECT
|DT_SINGLELINE
|DT_EXPANDTABS
|DT_TABSTOP
|(2<<8));
654 if (rt
.right
> _widths
[col
])
655 _widths
[col
] = rt
.right
;
659 // insert listbox entries after index idx
661 int Pane::insert_entries(Entry
* dir
, int idx
)
668 for(; entry
; entry
=entry
->_next
) {
671 !(entry
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
) && // not a directory?
672 !entry
->_down
) // not a file with NTFS sub-streams?
676 // don't display entries "." and ".." in the left pane
677 if (_treePane
&& (entry
->_data
.dwFileAttributes
&FILE_ATTRIBUTE_DIRECTORY
)
678 && entry
->_data
.cFileName
[0]==TEXT('.'))
679 if (entry
->_data
.cFileName
[1]==TEXT('\0') ||
680 (entry
->_data
.cFileName
[1]==TEXT('.') && entry
->_data
.cFileName
[2]==TEXT('\0')))
686 ListBox_InsertItemData(_hwnd
, idx
, entry
);
688 if (_treePane
&& entry
->_expanded
)
689 idx
= insert_entries(entry
->_down
, idx
);
696 void Pane::set_header()
699 int scroll_pos
= GetScrollPos(_hwnd
, SB_HORZ
);
702 item
.mask
= HDI_WIDTH
;
705 for(; x
+_widths
[i
]<scroll_pos
&& i
<COLUMNS
; i
++) {
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
;