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, 22.08.2003
31 #include "../resource.h"
33 #include "quicklaunch.h"
36 QuickLaunchEntry::QuickLaunchEntry()
41 QuickLaunchMap::~QuickLaunchMap()
44 iterator it
= begin();
45 DeleteBitmap(it
->second
._hbmp
);
51 QuickLaunchBar::QuickLaunchBar(HWND hwnd
)
54 CONTEXT("QuickLaunchBar::QuickLaunchBar()");
57 _next_id
= IDC_FIRST_QUICK_ID
;
61 HWND hwndToolTip
= (HWND
) SendMessage(hwnd
, TB_GETTOOLTIPS
, 0, 0);
63 SetWindowStyle(hwndToolTip
, GetWindowStyle(hwndToolTip
)|TTS_ALWAYSTIP
);
65 // delay refresh to some time later
66 PostMessage(hwnd
, PM_REFRESH
, 0, 0);
69 QuickLaunchBar::~QuickLaunchBar()
74 HWND
QuickLaunchBar::Create(HWND hwndParent
)
76 CONTEXT("QuickLaunchBar::Create()");
78 ClientRect
clnt(hwndParent
);
80 HWND hwnd
= CreateToolbarEx(hwndParent
,
81 WS_CHILD
|WS_VISIBLE
|WS_CLIPSIBLINGS
|WS_CLIPCHILDREN
|
82 CCS_TOP
|CCS_NODIVIDER
|CCS_NOPARENTALIGN
|CCS_NORESIZE
|
83 TBSTYLE_TOOLTIPS
|TBSTYLE_WRAPABLE
|TBSTYLE_FLAT
,
84 IDW_QUICKLAUNCHBAR
, 0, 0, 0, NULL
, 0, 0, 0, 16, 16, sizeof(TBBUTTON
));
87 new QuickLaunchBar(hwnd
);
92 void QuickLaunchBar::AddShortcuts()
94 CONTEXT("QuickLaunchBar::AddShortcuts()");
101 SpecialFolderFSPath
app_data(CSIDL_APPDATA
, _hwnd
); ///@todo perhaps also look into CSIDL_COMMON_APPDATA ?
103 _stprintf(path
, TEXT("%s\\")QUICKLAUNCH_FOLDER
, (LPCTSTR
)app_data
);
105 RecursiveCreateDirectory(path
);
106 _dir
= new ShellDirectory(GetDesktopFolder(), path
, _hwnd
);
108 _dir
->smart_scan(SORT_NAME
);
110 // immediatelly extract the shortcut icons
111 for(Entry
*entry
=_dir
->_down
; entry
; entry
=entry
->_next
)
112 entry
->_icon_id
= entry
->safe_extract_icon(ICF_NORMAL
);
113 } catch(COMException
&) {
118 ShellFolder desktop_folder
;
119 WindowCanvas
canvas(_hwnd
);
121 COLORREF bk_color
= GetSysColor(COLOR_BTNFACE
);
122 HBRUSH bk_brush
= GetSysColorBrush(COLOR_BTNFACE
);
124 AddButton(ID_MINIMIZE_ALL
, g_Globals
._icon_cache
.get_icon(ICID_MINIMIZE
).create_bitmap(bk_color
, bk_brush
, canvas
), ResString(IDS_MINIMIZE_ALL
), NULL
);
125 AddButton(ID_EXPLORE
, g_Globals
._icon_cache
.get_icon(ICID_EXPLORER
).create_bitmap(bk_color
, bk_brush
, canvas
), ResString(IDS_TITLE
), NULL
);
127 TBBUTTON sep
= {0, -1, TBSTATE_ENABLED
, BTNS_SEP
, {0, 0}, 0, 0};
128 SendMessage(_hwnd
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&sep
);
130 int cur_desktop
= g_Globals
._desktops
._current_desktop
;
131 ResString
desktop_fmt(IDS_DESKTOP_NUM
);
133 HDC hdc
= CreateCompatibleDC(canvas
);
134 DWORD size
= SendMessage(_hwnd
, TB_GETBUTTONSIZE
, 0, 0);
135 int cx
= LOWORD(size
);
136 int cy
= HIWORD(size
);
137 RECT rect
= {0, 0, cx
, cy
};
138 RECT textRect
= {0, 0, cx
-7, cy
-7};
140 for(int i
=0; i
<DESKTOP_COUNT
; ++i
) {
141 HBITMAP hbmp
= CreateCompatibleBitmap(canvas
, cx
, cy
);
142 HBITMAP hbmp_old
= SelectBitmap(hdc
, hbmp
);
144 FmtString
num_txt(TEXT("%d"), i
+1);
145 TextColor
color(hdc
, RGB(64,64,64));
146 BkMode
mode(hdc
, TRANSPARENT
);
147 FillRect(hdc
, &rect
, GetSysColorBrush(COLOR_BTNFACE
));
148 DrawText(hdc
, num_txt
, num_txt
.length(), &textRect
, DT_CENTER
|DT_VCENTER
|DT_SINGLELINE
);
150 SelectBitmap(hdc
, hbmp_old
);
152 AddButton(ID_SWITCH_DESKTOP_1
+i
, hbmp
, FmtString(desktop_fmt
, i
+1), NULL
, cur_desktop
==i
?TBSTATE_ENABLED
|TBSTATE_CHECKED
:TBSTATE_ENABLED
);
156 SendMessage(_hwnd
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&sep
);
158 for(Entry
*entry
=_dir
->_down
; entry
; entry
=entry
->_next
) {
159 // hide files like "desktop.ini"
160 if (entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_HIDDEN
)
164 if (!(entry
->_data
.dwFileAttributes
& FILE_ATTRIBUTE_DIRECTORY
)) {
165 HBITMAP hbmp
= g_Globals
._icon_cache
.get_icon(entry
->_icon_id
).create_bitmap(bk_color
, bk_brush
, canvas
);
167 AddButton(_next_id
++, hbmp
, entry
->_display_name
, entry
); //entry->_etype==ET_SHELL? desktop_folder.get_name(static_cast<ShellEntry*>(entry)->_pidl): entry->_display_name);
171 _btn_dist
= LOWORD(SendMessage(_hwnd
, TB_GETBUTTONSIZE
, 0, 0));
172 _size
= _entries
.size() * _btn_dist
;
174 SendMessage(GetParent(_hwnd
), PM_RESIZE_CHILDREN
, 0, 0);
177 void QuickLaunchBar::AddButton(int id
, HBITMAP hbmp
, LPCTSTR name
, Entry
* entry
, int flags
)
179 TBADDBITMAP ab
= {0, (UINT_PTR
)hbmp
};
180 int bmp_idx
= SendMessage(_hwnd
, TB_ADDBITMAP
, 1, (LPARAM
)&ab
);
182 QuickLaunchEntry qle
;
190 TBBUTTON btn
= {0, 0, flags
, BTNS_BUTTON
|BTNS_NOPREFIX
, {0, 0}, 0, 0};
193 btn
.iBitmap
= bmp_idx
;
195 SendMessage(_hwnd
, TB_INSERTBUTTON
, INT_MAX
, (LPARAM
)&btn
);
198 void QuickLaunchBar::UpdateDesktopButtons(int desktop_idx
)
200 for(int i
=0; i
<DESKTOP_COUNT
; ++i
) {
201 TBBUTTONINFO tbi
= {sizeof(TBBUTTONINFO
), TBIF_STATE
, 0, 0, desktop_idx
==i
? TBSTATE_ENABLED
|TBSTATE_CHECKED
: TBSTATE_ENABLED
};
203 SendMessage(_hwnd
, TB_SETBUTTONINFO
, ID_SWITCH_DESKTOP_1
+i
, (LPARAM
)&tbi
);
207 LRESULT
QuickLaunchBar::WndProc(UINT nmsg
, WPARAM wparam
, LPARAM lparam
)
215 // take line wrapping into account
216 int btns
= SendMessage(_hwnd
, TB_BUTTONCOUNT
, 0, 0);
217 int rows
= SendMessage(_hwnd
, TB_GETROWS
, 0, 0);
219 if (rows
<2 || rows
==btns
)
225 for(QuickLaunchMap::const_iterator it
=_entries
.begin(); it
!=_entries
.end(); ++it
) {
226 SendMessage(_hwnd
, TB_GETRECT
, it
->first
, (LPARAM
)&rect
);
228 if (rect
.right
> max_cx
)
234 case PM_UPDATE_DESKTOP
:
235 UpdateDesktopButtons(wparam
);
238 case WM_CONTEXTMENU
: {
240 QuickLaunchMap::iterator it
;
241 Point
screen_pt(lparam
), clnt_pt
=screen_pt
;
242 ScreenToClient(_hwnd
, &clnt_pt
);
245 int idx
= SendMessage(_hwnd
, TB_HITTEST
, 0, (LPARAM
)&clnt_pt
);
248 SendMessage(_hwnd
, TB_GETBUTTON
, idx
, (LPARAM
)&btn
)!=-1 &&
249 (it
=_entries
.find(btn
.idCommand
))!=_entries
.end()) {
250 entry
= it
->second
._entry
;
253 if (entry
) // entry is NULL for desktop switch buttons
254 CHECKERROR(entry
->do_context_menu(_hwnd
, screen_pt
, _cm_ifs
));
260 return super::WndProc(nmsg
, wparam
, lparam
);
266 int QuickLaunchBar::Command(int id
, int code
)
268 CONTEXT("QuickLaunchBar::Command()");
270 if ((id
&~0xFF) == IDC_FIRST_QUICK_ID
) {
271 QuickLaunchEntry
& qle
= _entries
[id
];
274 qle
._entry
->launch_entry(_hwnd
);
279 return 0; // Don't return 1 to avoid recursion with DesktopBar::Command()
282 int QuickLaunchBar::Notify(int id
, NMHDR
* pnmh
)
285 case TTN_GETDISPINFO
: {
286 NMTTDISPINFO
* ttdi
= (NMTTDISPINFO
*) pnmh
;
288 int id
= ttdi
->hdr
.idFrom
;
289 ttdi
->lpszText
= _entries
[id
]._title
.str();
290 #ifdef TTF_DI_SETITEM
291 ttdi
->uFlags
|= TTF_DI_SETITEM
;
294 // enable multiline tooltips (break at CR/LF and for very long one-line strings)
295 SendMessage(pnmh
->hwndFrom
, TTM_SETMAXTIPWIDTH
, 0, 400);
299 return super::Notify(id
, pnmh
);