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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 00017 */ 00018 00019 00020 // 00021 // Explorer clone 00022 // 00023 // quicklaunch.cpp 00024 // 00025 // Martin Fuchs, 22.08.2003 00026 // 00027 00028 00029 #include <precomp.h> 00030 00031 #include "../resource.h" 00032 00033 #include "quicklaunch.h" 00034 00035 00036 QuickLaunchEntry::QuickLaunchEntry() 00037 { 00038 _hbmp = 0; 00039 } 00040 00041 QuickLaunchMap::~QuickLaunchMap() 00042 { 00043 while(!empty()) { 00044 iterator it = begin(); 00045 DeleteBitmap(it->second._hbmp); 00046 erase(it); 00047 } 00048 } 00049 00050 00051 QuickLaunchBar::QuickLaunchBar(HWND hwnd) 00052 : super(hwnd) 00053 { 00054 CONTEXT("QuickLaunchBar::QuickLaunchBar()"); 00055 00056 _dir = NULL; 00057 _next_id = IDC_FIRST_QUICK_ID; 00058 _btn_dist = 20; 00059 _size = 0; 00060 00061 HWND hwndToolTip = (HWND) SendMessage(hwnd, TB_GETTOOLTIPS, 0, 0); 00062 00063 SetWindowStyle(hwndToolTip, GetWindowStyle(hwndToolTip)|TTS_ALWAYSTIP); 00064 00065 // delay refresh to some time later 00066 PostMessage(hwnd, PM_REFRESH, 0, 0); 00067 } 00068 00069 QuickLaunchBar::~QuickLaunchBar() 00070 { 00071 delete _dir; 00072 } 00073 00074 HWND QuickLaunchBar::Create(HWND hwndParent) 00075 { 00076 CONTEXT("QuickLaunchBar::Create()"); 00077 00078 ClientRect clnt(hwndParent); 00079 00080 HWND hwnd = CreateToolbarEx(hwndParent, 00081 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN| 00082 CCS_TOP|CCS_NODIVIDER|CCS_NOPARENTALIGN|CCS_NORESIZE| 00083 TBSTYLE_TOOLTIPS|TBSTYLE_WRAPABLE|TBSTYLE_FLAT, 00084 IDW_QUICKLAUNCHBAR, 0, 0, 0, NULL, 0, 0, 0, 16, 16, sizeof(TBBUTTON)); 00085 00086 if (hwnd) 00087 new QuickLaunchBar(hwnd); 00088 00089 return hwnd; 00090 } 00091 00092 void QuickLaunchBar::AddShortcuts() 00093 { 00094 CONTEXT("QuickLaunchBar::AddShortcuts()"); 00095 00096 WaitCursor wait; 00097 00098 try { 00099 TCHAR path[MAX_PATH]; 00100 00101 SpecialFolderFSPath app_data(CSIDL_APPDATA, _hwnd); ///@todo perhaps also look into CSIDL_COMMON_APPDATA ? 00102 00103 _stprintf(path, TEXT("%s\\")QUICKLAUNCH_FOLDER, (LPCTSTR)app_data); 00104 00105 RecursiveCreateDirectory(path); 00106 _dir = new ShellDirectory(GetDesktopFolder(), path, _hwnd); 00107 00108 _dir->smart_scan(SORT_NAME); 00109 00110 // immediatelly extract the shortcut icons 00111 for(Entry*entry=_dir->_down; entry; entry=entry->_next) 00112 entry->_icon_id = entry->safe_extract_icon(ICF_NORMAL); 00113 } catch(COMException&) { 00114 return; 00115 } 00116 00117 00118 ShellFolder desktop_folder; 00119 WindowCanvas canvas(_hwnd); 00120 00121 COLORREF bk_color = GetSysColor(COLOR_BTNFACE); 00122 HBRUSH bk_brush = GetSysColorBrush(COLOR_BTNFACE); 00123 00124 AddButton(ID_MINIMIZE_ALL, g_Globals._icon_cache.get_icon(ICID_MINIMIZE).create_bitmap(bk_color, bk_brush, canvas), ResString(IDS_MINIMIZE_ALL), NULL); 00125 AddButton(ID_EXPLORE, g_Globals._icon_cache.get_icon(ICID_EXPLORER).create_bitmap(bk_color, bk_brush, canvas), ResString(IDS_TITLE), NULL); 00126 00127 TBBUTTON sep = {0, -1, TBSTATE_ENABLED, BTNS_SEP, {0, 0}, 0, 0}; 00128 SendMessage(_hwnd, TB_INSERTBUTTON, INT_MAX, (LPARAM)&sep); 00129 00130 int cur_desktop = g_Globals._desktops._current_desktop; 00131 ResString desktop_fmt(IDS_DESKTOP_NUM); 00132 00133 HDC hdc = CreateCompatibleDC(canvas); 00134 DWORD size = SendMessage(_hwnd, TB_GETBUTTONSIZE, 0, 0); 00135 int cx = LOWORD(size); 00136 int cy = HIWORD(size); 00137 RECT rect = {0, 0, cx, cy}; 00138 RECT textRect = {0, 0, cx-7, cy-7}; 00139 00140 for(int i=0; i<DESKTOP_COUNT; ++i) { 00141 HBITMAP hbmp = CreateCompatibleBitmap(canvas, cx, cy); 00142 HBITMAP hbmp_old = SelectBitmap(hdc, hbmp); 00143 00144 FmtString num_txt(TEXT("%d"), i+1); 00145 TextColor color(hdc, RGB(64,64,64)); 00146 BkMode mode(hdc, TRANSPARENT); 00147 FillRect(hdc, &rect, GetSysColorBrush(COLOR_BTNFACE)); 00148 DrawText(hdc, num_txt, num_txt.length(), &textRect, DT_CENTER|DT_VCENTER|DT_SINGLELINE); 00149 00150 SelectBitmap(hdc, hbmp_old); 00151 00152 AddButton(ID_SWITCH_DESKTOP_1+i, hbmp, FmtString(desktop_fmt, i+1), NULL, cur_desktop==i?TBSTATE_ENABLED|TBSTATE_CHECKED:TBSTATE_ENABLED); 00153 } 00154 DeleteDC(hdc); 00155 00156 SendMessage(_hwnd, TB_INSERTBUTTON, INT_MAX, (LPARAM)&sep); 00157 00158 for(Entry*entry=_dir->_down; entry; entry=entry->_next) { 00159 // hide files like "desktop.ini" 00160 if (entry->_data.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) 00161 continue; 00162 00163 // hide subfolders 00164 if (!(entry->_data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) { 00165 HBITMAP hbmp = g_Globals._icon_cache.get_icon(entry->_icon_id).create_bitmap(bk_color, bk_brush, canvas); 00166 00167 AddButton(_next_id++, hbmp, entry->_display_name, entry); //entry->_etype==ET_SHELL? desktop_folder.get_name(static_cast<ShellEntry*>(entry)->_pidl): entry->_display_name); 00168 } 00169 } 00170 00171 _btn_dist = LOWORD(SendMessage(_hwnd, TB_GETBUTTONSIZE, 0, 0)); 00172 _size = _entries.size() * _btn_dist; 00173 00174 SendMessage(GetParent(_hwnd), PM_RESIZE_CHILDREN, 0, 0); 00175 } 00176 00177 void QuickLaunchBar::AddButton(int id, HBITMAP hbmp, LPCTSTR name, Entry* entry, int flags) 00178 { 00179 TBADDBITMAP ab = {0, (UINT_PTR)hbmp}; 00180 int bmp_idx = SendMessage(_hwnd, TB_ADDBITMAP, 1, (LPARAM)&ab); 00181 00182 QuickLaunchEntry qle; 00183 00184 qle._hbmp = hbmp; 00185 qle._title = name; 00186 qle._entry = entry; 00187 00188 _entries[id] = qle; 00189 00190 TBBUTTON btn = {0, 0, flags, BTNS_BUTTON|BTNS_NOPREFIX, {0, 0}, 0, 0}; 00191 00192 btn.idCommand = id; 00193 btn.iBitmap = bmp_idx; 00194 00195 SendMessage(_hwnd, TB_INSERTBUTTON, INT_MAX, (LPARAM)&btn); 00196 } 00197 00198 void QuickLaunchBar::UpdateDesktopButtons(int desktop_idx) 00199 { 00200 for(int i=0; i<DESKTOP_COUNT; ++i) { 00201 TBBUTTONINFO tbi = {sizeof(TBBUTTONINFO), TBIF_STATE, 0, 0, desktop_idx==i? TBSTATE_ENABLED|TBSTATE_CHECKED: TBSTATE_ENABLED}; 00202 00203 SendMessage(_hwnd, TB_SETBUTTONINFO, ID_SWITCH_DESKTOP_1+i, (LPARAM)&tbi); 00204 } 00205 } 00206 00207 LRESULT QuickLaunchBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam) 00208 { 00209 switch(nmsg) { 00210 case PM_REFRESH: 00211 AddShortcuts(); 00212 break; 00213 00214 case PM_GET_WIDTH: { 00215 // take line wrapping into account 00216 int btns = SendMessage(_hwnd, TB_BUTTONCOUNT, 0, 0); 00217 int rows = SendMessage(_hwnd, TB_GETROWS, 0, 0); 00218 00219 if (rows<2 || rows==btns) 00220 return _size; 00221 00222 RECT rect; 00223 int max_cx = 0; 00224 00225 for(QuickLaunchMap::const_iterator it=_entries.begin(); it!=_entries.end(); ++it) { 00226 SendMessage(_hwnd, TB_GETRECT, it->first, (LPARAM)&rect); 00227 00228 if (rect.right > max_cx) 00229 max_cx = rect.right; 00230 } 00231 00232 return max_cx;} 00233 00234 case PM_UPDATE_DESKTOP: 00235 UpdateDesktopButtons(wparam); 00236 break; 00237 00238 case WM_CONTEXTMENU: { 00239 TBBUTTON btn; 00240 QuickLaunchMap::iterator it; 00241 Point screen_pt(lparam), clnt_pt=screen_pt; 00242 ScreenToClient(_hwnd, &clnt_pt); 00243 00244 Entry* entry = NULL; 00245 int idx = SendMessage(_hwnd, TB_HITTEST, 0, (LPARAM)&clnt_pt); 00246 00247 if (idx>=0 && 00248 SendMessage(_hwnd, TB_GETBUTTON, idx, (LPARAM)&btn)!=-1 && 00249 (it=_entries.find(btn.idCommand))!=_entries.end()) { 00250 entry = it->second._entry; 00251 } 00252 00253 if (entry) { // entry is NULL for desktop switch buttons 00254 HRESULT hr = entry->do_context_menu(_hwnd, screen_pt, _cm_ifs); 00255 00256 if (SUCCEEDED(hr)) 00257 AddShortcuts(); //refresh(); 00258 else 00259 CHECKERROR(hr); 00260 } else 00261 goto def; 00262 break;} 00263 00264 default: def: 00265 return super::WndProc(nmsg, wparam, lparam); 00266 } 00267 00268 return 0; 00269 } 00270 00271 int QuickLaunchBar::Command(int id, int code) 00272 { 00273 CONTEXT("QuickLaunchBar::Command()"); 00274 00275 if ((id&~0xFF) == IDC_FIRST_QUICK_ID) { 00276 QuickLaunchEntry& qle = _entries[id]; 00277 00278 if (qle._entry) { 00279 qle._entry->launch_entry(_hwnd); 00280 return 0; 00281 } 00282 } 00283 00284 return 0; // Don't return 1 to avoid recursion with DesktopBar::Command() 00285 } 00286 00287 int QuickLaunchBar::Notify(int id, NMHDR* pnmh) 00288 { 00289 switch(pnmh->code) { 00290 case TTN_GETDISPINFO: { 00291 NMTTDISPINFO* ttdi = (NMTTDISPINFO*) pnmh; 00292 00293 int id = ttdi->hdr.idFrom; 00294 ttdi->lpszText = _entries[id]._title.str(); 00295 #ifdef TTF_DI_SETITEM 00296 ttdi->uFlags |= TTF_DI_SETITEM; 00297 #endif 00298 00299 // enable multiline tooltips (break at CR/LF and for very long one-line strings) 00300 SendMessage(pnmh->hwndFrom, TTM_SETMAXTIPWIDTH, 0, 400); 00301 00302 break;} 00303 00304 return super::Notify(id, pnmh); 00305 } 00306 00307 return 0; 00308 }
ROS Explorer Source Code Documentation
generated on 02.01.2013 by ![]() |