taskbar.cpp

Go to the documentation of this file.
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  // taskbar.cpp
00024  //
00025  // Martin Fuchs, 16.08.2003
00026  //
00027 
00028 
00029 #include <precomp.h>
00030 
00031 #include "taskbar.h"
00032 #include "traynotify.h" // for NOTIFYAREA_WIDTH_DEF
00033 
00034 
00035 DynamicFct<BOOL (WINAPI*)(HWND hwnd)> g_SetTaskmanWindow(TEXT("user32"), "SetTaskmanWindow");
00036 DynamicFct<BOOL (WINAPI*)(HWND hwnd)> g_RegisterShellHookWindow(TEXT("user32"), "RegisterShellHookWindow");
00037 DynamicFct<BOOL (WINAPI*)(HWND hwnd)> g_DeregisterShellHookWindow(TEXT("user32"), "DeregisterShellHookWindow");
00038 
00039 /*
00040 DynamicFct<BOOL (WINAPI*)(HWND hWnd, DWORD dwType)> g_RegisterShellHook(TEXT("shell32"), (LPCSTR)0xb5);
00041 
00042  // constants for RegisterShellHook()
00043 #define RSH_UNREGISTER          0
00044 #define RSH_REGISTER            1
00045 #define RSH_REGISTER_PROGMAN    2
00046 #define RSH_REGISTER_TASKMAN    3
00047 */
00048 
00049 
00050 TaskBarEntry::TaskBarEntry()
00051 {
00052     _id = 0;
00053     _hbmp = 0;
00054     _bmp_idx = 0;
00055     _used = 0;
00056     _btn_idx = 0;
00057     _fsState = 0;
00058 }
00059 
00060 TaskBarMap::~TaskBarMap()
00061 {
00062     while(!empty()) {
00063         iterator it = begin();
00064         DeleteBitmap(it->second._hbmp);
00065         erase(it);
00066     }
00067 }
00068 
00069 
00070 TaskBar::TaskBar(HWND hwnd)
00071  :  super(hwnd),
00072     WM_SHELLHOOK(RegisterWindowMessage(WINMSG_SHELLHOOK))
00073 {
00074     _last_btn_width = 0;
00075 
00076     _mmMetrics_org.cbSize = sizeof(MINIMIZEDMETRICS);
00077 
00078     SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(_mmMetrics_org), &_mmMetrics_org, 0);
00079 
00080      // configure the window manager to hide windows when they are minimized
00081      // This is neccessary to enable shell hook messages.
00082     if (!(_mmMetrics_org.iArrange & ARW_HIDE)) {
00083         MINIMIZEDMETRICS _mmMetrics_new = _mmMetrics_org;
00084 
00085         _mmMetrics_new.iArrange |= ARW_HIDE;
00086 
00087         SystemParametersInfo(SPI_SETMINIMIZEDMETRICS, sizeof(_mmMetrics_new), &_mmMetrics_new, 0);
00088     }
00089 }
00090 
00091 TaskBar::~TaskBar()
00092 {
00093 //  if (g_RegisterShellHook)
00094 //      (*g_RegisterShellHook)(_hwnd, RSH_UNREGISTER);
00095 
00096     if (g_DeregisterShellHookWindow)
00097         (*g_DeregisterShellHookWindow)(_hwnd);
00098     else
00099         KillTimer(_hwnd, 0);
00100 
00101     if (g_SetTaskmanWindow)
00102         (*g_SetTaskmanWindow)(0);
00103 
00104     SystemParametersInfo(SPI_GETMINIMIZEDMETRICS, sizeof(_mmMetrics_org), &_mmMetrics_org, 0);
00105 }
00106 
00107 HWND TaskBar::Create(HWND hwndParent)
00108 {
00109     ClientRect clnt(hwndParent);
00110 
00111     int taskbar_pos = 80;   // This start position will be adjusted in DesktopBar::Resize().
00112 
00113     return Window::Create(WINDOW_CREATOR(TaskBar), 0,
00114                             BtnWindowClass(CLASSNAME_TASKBAR), TITLE_TASKBAR,
00115                             WS_CHILD|WS_VISIBLE | CCS_TOP|CCS_NODIVIDER|CCS_NORESIZE,
00116                             taskbar_pos, 0, clnt.right-taskbar_pos-(NOTIFYAREA_WIDTH_DEF+1), clnt.bottom, hwndParent);
00117 }
00118 
00119 LRESULT TaskBar::Init(LPCREATESTRUCT pcs)
00120 {
00121     if (super::Init(pcs))
00122         return 1;
00123 
00124     /* FIXME: There's an internal padding for non-flat toolbar. Get rid of it somehow. */
00125     _htoolbar = CreateToolbarEx(_hwnd,
00126                                 WS_CHILD|WS_VISIBLE|WS_CLIPSIBLINGS|WS_CLIPCHILDREN|
00127                                 CCS_TOP|CCS_NODIVIDER|TBSTYLE_LIST|TBSTYLE_TOOLTIPS|TBSTYLE_WRAPABLE,//|TBSTYLE_AUTOSIZE
00128                                 IDW_TASKTOOLBAR, 0, 0, 0, NULL, 0, 0, 0, 16, 16, sizeof(TBBUTTON));
00129 
00130     SendMessage(_htoolbar, TB_SETBUTTONWIDTH, 0, MAKELONG(TASKBUTTONWIDTH_MAX,TASKBUTTONWIDTH_MAX));
00131     //SendMessage(_htoolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
00132     //SendMessage(_htoolbar, TB_SETDRAWTEXTFLAGS, DT_CENTER|DT_VCENTER, DT_CENTER|DT_VCENTER);
00133     //SetWindowFont(_htoolbar, GetStockFont(ANSI_VAR_FONT), FALSE);
00134     //SendMessage(_htoolbar, TB_SETPADDING, 0, MAKELPARAM(8,8));
00135 
00136 #ifndef __MINGW32__ // TBMETRICS missing in MinGW (as of 20.09.2005)
00137      // set metrics for the Taskbar toolbar to enable button spacing
00138     TBMETRICS metrics;
00139 
00140     metrics.cbSize = sizeof(TBMETRICS);
00141     metrics.dwMask = TBMF_BARPAD | TBMF_BUTTONSPACING;
00142     metrics.cxBarPad = 0;
00143     metrics.cyBarPad = 0;
00144     metrics.cxButtonSpacing = 3;
00145     metrics.cyButtonSpacing = 3;
00146 
00147     SendMessage(_htoolbar, TB_SETMETRICS, 0, (LPARAM)&metrics);
00148 #endif
00149 
00150     _next_id = IDC_FIRST_APP;
00151 
00152      // register the taskbar window as task manager window to make the following call to RegisterShellHookWindow working
00153     if (g_SetTaskmanWindow)
00154         (*g_SetTaskmanWindow)(_hwnd);
00155 
00156     if (g_RegisterShellHookWindow) {
00157         LOG(TEXT("Using shell hooks for notification of shell events."));
00158 
00159         (*g_RegisterShellHookWindow)(_hwnd);
00160     } else {
00161         LOG(TEXT("Shell hooks not available."));
00162 
00163         SetTimer(_hwnd, 0, 200, NULL);
00164     }
00165 
00166 /* Alternatively we could use the RegisterShellHook() function in SHELL32, but this is not yet implemented in the WINE code.
00167     if (g_RegisterShellHook) {
00168         (*g_RegisterShellHook)(0, RSH_REGISTER);
00169 
00170         if ((HIWORD(GetVersion())>>14) == W_VER_NT)
00171             (*g_RegisterShellHook)(_hwnd, RSH_REGISTER_TASKMAN);
00172         else
00173             (*g_RegisterShellHook)(_hwnd, RSH_REGISTER);
00174     }
00175 */
00176     Refresh();
00177 
00178     return 0;
00179 }
00180 
00181 LRESULT TaskBar::WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
00182 {
00183     switch(nmsg) {
00184       case WM_SIZE:
00185         SendMessage(_htoolbar, WM_SIZE, 0, 0);
00186         ResizeButtons();
00187         break;
00188 
00189       case WM_TIMER:
00190         Refresh();
00191         return 0;
00192 
00193       case WM_CONTEXTMENU: {
00194         Point pt(lparam);
00195         ScreenToClient(_htoolbar, &pt);
00196 
00197         if ((HWND)wparam==_htoolbar && SendMessage(_htoolbar, TB_HITTEST, 0, (LPARAM)&pt)>=0)
00198             break;  // avoid displaying context menu for application button _and_ desktop bar at the same time
00199 
00200         goto def;}
00201 
00202       case PM_GET_LAST_ACTIVE:
00203         return (LRESULT)(HWND)_last_foreground_wnd;
00204 
00205       default: def:
00206         if (nmsg == WM_SHELLHOOK) {
00207             switch(wparam) {
00208               case HSHELL_WINDOWCREATED:
00209               case HSHELL_WINDOWDESTROYED:
00210               case HSHELL_WINDOWACTIVATED:
00211               case HSHELL_REDRAW:
00212 #ifdef HSHELL_FLASH
00213               case HSHELL_FLASH:
00214 #endif
00215 #ifdef HSHELL_RUDEAPPACTIVATED
00216               case HSHELL_RUDEAPPACTIVATED:
00217 #endif
00218                 Refresh();
00219                 break;
00220             }
00221         } else {
00222             return super::WndProc(nmsg, wparam, lparam);
00223         }
00224     }
00225 
00226     return 0;
00227 }
00228 
00229 int TaskBar::Command(int id, int code)
00230 {
00231     TaskBarMap::iterator found = _map.find_id(id);
00232 
00233     if (found != _map.end()) {
00234         ActivateApp(found);
00235         return 0;
00236     }
00237 
00238     return super::Command(id, code);
00239 }
00240 
00241 int TaskBar::Notify(int id, NMHDR* pnmh)
00242 {
00243     if (pnmh->hwndFrom == _htoolbar)
00244         switch(pnmh->code) {
00245           case NM_RCLICK: {
00246             TBBUTTONINFO btninfo;
00247             TaskBarMap::iterator it;
00248             Point pt(GetMessagePos());
00249             ScreenToClient(_htoolbar, &pt);
00250 
00251             btninfo.cbSize = sizeof(TBBUTTONINFO);
00252             btninfo.dwMask = TBIF_BYINDEX|TBIF_COMMAND;
00253 
00254             int idx = SendMessage(_htoolbar, TB_HITTEST, 0, (LPARAM)&pt);
00255 
00256             if (idx>=0 &&
00257                 SendMessage(_htoolbar, TB_GETBUTTONINFO, idx, (LPARAM)&btninfo)!=-1 &&
00258                 (it=_map.find_id(btninfo.idCommand))!=_map.end()) {
00259                 //TaskBarEntry& entry = it->second;
00260 
00261                 ActivateApp(it, false, false);  // don't restore minimized windows on right button click
00262 
00263 #ifndef __MINGW32__ // SHRestricted() missing in MinGW (as of 29.10.2003)
00264                 static DynamicFct<DWORD(STDAPICALLTYPE*)(RESTRICTIONS)> pSHRestricted(TEXT("SHELL32"), "SHRestricted");
00265 
00266                 if (pSHRestricted && !(*pSHRestricted)(REST_NOTRAYCONTEXTMENU))
00267 #endif
00268                     ShowAppSystemMenu(it);
00269             }
00270             break;}
00271 
00272           default:
00273             return super::Notify(id, pnmh);
00274         }
00275 
00276     return 0;
00277 }
00278 
00279 
00280 void TaskBar::ActivateApp(TaskBarMap::iterator it, bool can_minimize, bool can_restore)
00281 {
00282     HWND hwnd = it->first;
00283 
00284     bool minimize_it = can_minimize && !IsIconic(hwnd) &&
00285                         (hwnd==GetForegroundWindow() || hwnd==_last_foreground_wnd);
00286 
00287      // switch to selected application window
00288     if (can_restore && !minimize_it)
00289         if (IsIconic(hwnd))
00290             PostMessage(hwnd, WM_SYSCOMMAND, SC_RESTORE, 0);
00291 
00292      // In case minimize_it is true, we _have_ to switch to the app before
00293      // posting SW_MINIMIZE to be compatible with some applications (e.g. "Sleipnir")
00294     SetForegroundWindow(hwnd);
00295 
00296     if (minimize_it) {
00297         PostMessage(hwnd, WM_SYSCOMMAND, SC_MINIMIZE, 0);
00298         _last_foreground_wnd = 0;
00299     } else
00300         _last_foreground_wnd = hwnd;
00301 
00302     Refresh();
00303 }
00304 
00305 void TaskBar::ShowAppSystemMenu(TaskBarMap::iterator it)
00306 {
00307     HMENU hmenu = GetSystemMenu(it->first, FALSE);
00308 
00309     if (hmenu) {
00310         POINT pt;
00311 
00312         GetCursorPos(&pt);
00313         int cmd = TrackPopupMenu(hmenu, TPM_LEFTBUTTON|TPM_RIGHTBUTTON|TPM_RETURNCMD, pt.x, pt.y, 0, _hwnd, NULL);
00314 
00315         if (cmd) {
00316             ActivateApp(it, false, false);  // reactivate window after the context menu has closed
00317             PostMessage(it->first, WM_SYSCOMMAND, cmd, 0);
00318         }
00319     }
00320 }
00321 
00322 
00323 HICON get_window_icon_small(HWND hwnd)
00324 {
00325     HICON hIcon = 0;
00326 
00327     SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL2, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&hIcon);
00328 
00329     if (!hIcon)
00330         SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&hIcon);
00331 
00332     if (!hIcon)
00333         SendMessageTimeout(hwnd, WM_GETICON, ICON_BIG, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&hIcon);
00334 
00335     if (!hIcon)
00336         hIcon = (HICON)GetClassLong(hwnd, GCL_HICONSM);
00337 
00338     if (!hIcon)
00339         hIcon = (HICON)GetClassLong(hwnd, GCL_HICON);
00340 
00341     if (!hIcon)
00342         SendMessageTimeout(hwnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (LPDWORD)&hIcon);
00343 
00344     return hIcon;
00345 }
00346 
00347 HICON get_window_icon_big(HWND hwnd, bool allow_from_class)
00348 {
00349     HICON hIcon = 0;
00350 
00351     SendMessageTimeout(hwnd, WM_GETICON, ICON_BIG, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&hIcon);
00352 
00353     if (!hIcon)
00354         SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL2, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&hIcon);
00355 
00356     if (!hIcon)
00357         SendMessageTimeout(hwnd, WM_GETICON, ICON_SMALL, 0, SMTO_ABORTIFHUNG, 1000, (LPDWORD)&hIcon);
00358 
00359     if (allow_from_class) {
00360         if (!hIcon)
00361             hIcon = (HICON)GetClassLong(hwnd, GCL_HICON);
00362 
00363         if (!hIcon)
00364             hIcon = (HICON)GetClassLong(hwnd, GCL_HICONSM);
00365     }
00366 
00367     if (!hIcon)
00368         SendMessageTimeout(hwnd, WM_QUERYDRAGICON, 0, 0, 0, 1000, (LPDWORD)&hIcon);
00369 
00370     return hIcon;
00371 }
00372 
00373  // fill task bar with buttons for enumerated top level windows
00374 BOOL CALLBACK TaskBar::EnumWndProc(HWND hwnd, LPARAM lparam)
00375 {
00376     TaskBar* pThis = (TaskBar*)lparam;
00377 
00378     DWORD style = GetWindowStyle(hwnd);
00379     DWORD ex_style = GetWindowExStyle(hwnd);
00380 
00381     if ((style&WS_VISIBLE) && !(ex_style&WS_EX_TOOLWINDOW) &&
00382         !GetParent(hwnd) && !GetWindow(hwnd,GW_OWNER)) {
00383         TCHAR title[BUFFER_LEN];
00384 
00385         if (!GetWindowText(hwnd, title, BUFFER_LEN))
00386             title[0] = '\0';
00387 
00388         TaskBarMap::iterator found = pThis->_map.find(hwnd);
00389         int last_id = 0;
00390 
00391         if (found != pThis->_map.end()) {
00392             last_id = found->second._id;
00393 
00394             if (!last_id)
00395                 found->second._id = pThis->_next_id++;
00396         } else {
00397             HBITMAP hbmp;
00398             HICON hIcon = get_window_icon_small(hwnd);
00399             BOOL delete_icon = FALSE;
00400 
00401             if (!hIcon) {
00402                 hIcon = LoadIcon(0, IDI_APPLICATION);
00403                 delete_icon = TRUE;
00404             }
00405 
00406             if (hIcon) {
00407                 hbmp = create_bitmap_from_icon(hIcon, GetSysColorBrush(COLOR_BTNFACE), WindowCanvas(pThis->_htoolbar));
00408                 if (delete_icon)
00409                     DestroyIcon(hIcon); // some icons can be freed, some not - so ignore any error return of DestroyIcon()
00410             } else
00411                 hbmp = 0;
00412 
00413             TBADDBITMAP ab = {0, (UINT_PTR)hbmp};
00414             int bmp_idx = SendMessage(pThis->_htoolbar, TB_ADDBITMAP, 1, (LPARAM)&ab);
00415 
00416             TaskBarEntry entry;
00417 
00418             entry._id = pThis->_next_id++;
00419             entry._hbmp = hbmp;
00420             entry._bmp_idx = bmp_idx;
00421             entry._title = title;
00422 
00423             pThis->_map[hwnd] = entry;
00424             found = pThis->_map.find(hwnd);
00425         }
00426 
00427         TBBUTTON btn = {-2/*I_IMAGENONE*/, 0, TBSTATE_ENABLED/*|TBSTATE_ELLIPSES*/, BTNS_BUTTON, {0, 0}, 0, 0};
00428         TaskBarEntry& entry = found->second;
00429 
00430         ++entry._used;
00431         btn.idCommand = entry._id;
00432 
00433         HWND foreground = GetForegroundWindow();
00434         HWND foreground_owner = GetWindow(foreground, GW_OWNER);
00435 
00436         if (hwnd==foreground || hwnd==foreground_owner) {
00437             btn.fsState |= TBSTATE_PRESSED|TBSTATE_CHECKED;
00438             pThis->_last_foreground_wnd = hwnd;
00439         }
00440 
00441         if (!last_id) {
00442              // create new toolbar buttons for new windows
00443             if (title[0])
00444                 btn.iString = (INT_PTR)title;
00445 
00446             btn.iBitmap = entry._bmp_idx;
00447             entry._btn_idx = SendMessage(pThis->_htoolbar, TB_BUTTONCOUNT, 0, 0);
00448 
00449             SendMessage(pThis->_htoolbar, TB_INSERTBUTTON, entry._btn_idx, (LPARAM)&btn);
00450 
00451             pThis->ResizeButtons();
00452         } else {
00453              // refresh attributes of existing buttons
00454             if (btn.fsState != entry._fsState)
00455                 SendMessage(pThis->_htoolbar, TB_SETSTATE, entry._id, MAKELONG(btn.fsState,0));
00456 
00457             if (entry._title != title) {
00458                 TBBUTTONINFO info;
00459 
00460                 info.cbSize = sizeof(TBBUTTONINFO);
00461                 info.dwMask = TBIF_TEXT;
00462                 info.pszText = title;
00463 
00464                 SendMessage(pThis->_htoolbar, TB_SETBUTTONINFO, entry._id, (LPARAM)&info);
00465 
00466                 entry._title = title;
00467             }
00468         }
00469 
00470         entry._fsState = btn.fsState;
00471 
00472 #ifdef __REACTOS__  // now handled by activating the ARW_HIDE flag with SystemParametersInfo(SPI_SETMINIMIZEDMETRICS)
00473          // move minimized windows out of sight
00474         if (IsIconic(hwnd)) {
00475             RECT rect;
00476 
00477             GetWindowRect(hwnd, &rect);
00478 
00479             if (rect.bottom > 0)
00480                 SetWindowPos(hwnd, 0, -32000, -32000, 0, 0, SWP_NOSIZE|SWP_NOZORDER|SWP_NOACTIVATE);
00481         }
00482 #endif
00483     }
00484 
00485     return TRUE;
00486 }
00487 
00488 void TaskBar::Refresh()
00489 {
00490     for(TaskBarMap::iterator it=_map.begin(); it!=_map.end(); ++it)
00491         it->second._used = 0;
00492 
00493     EnumWindows(EnumWndProc, (LPARAM)this);
00494     //EnumDesktopWindows(GetThreadDesktop(GetCurrentThreadId()), EnumWndProc, (LPARAM)_htoolbar);
00495 
00496     set<int> btn_idx_to_delete;
00497     set<HBITMAP> hbmp_to_delete;
00498 
00499     for(TaskBarMap::iterator it=_map.begin(); it!=_map.end(); ++it) {
00500         TaskBarEntry& entry = it->second;
00501 
00502         if (!entry._used && entry._id) {
00503              // store button indexes to remove
00504             btn_idx_to_delete.insert(entry._btn_idx);
00505             hbmp_to_delete.insert(entry._hbmp);
00506             entry._id = 0;
00507         }
00508     }
00509 
00510     if (!btn_idx_to_delete.empty()) {
00511          // remove buttons from right to left
00512         for(set<int>::reverse_iterator it=btn_idx_to_delete.rbegin(); it!=btn_idx_to_delete.rend(); ++it) {
00513             int idx = *it;
00514 
00515             SendMessage(_htoolbar, TB_DELETEBUTTON, idx, 0);
00516 
00517             for(TaskBarMap::iterator it=_map.begin(); it!=_map.end(); ++it) {
00518                 TaskBarEntry& entry = it->second;
00519 
00520                  // adjust button indexes
00521                 if (entry._btn_idx > idx) {
00522                     --entry._btn_idx;
00523                     --entry._bmp_idx;
00524 
00525                     TBBUTTONINFO info;
00526 
00527                     info.cbSize = sizeof(TBBUTTONINFO);
00528                     info.dwMask = TBIF_IMAGE;
00529                     info.iImage = entry._bmp_idx;
00530 
00531                     SendMessage(_htoolbar, TB_SETBUTTONINFO, entry._id, (LPARAM)&info);
00532                 }
00533             }
00534         }
00535 
00536         for(set<HBITMAP>::iterator it=hbmp_to_delete.begin(); it!=hbmp_to_delete.end(); ++it) {
00537             HBITMAP hbmp = *it;
00538 
00539             TBREPLACEBITMAP tbrepl = {0, (UINT_PTR)hbmp, 0, 0};
00540             SendMessage(_htoolbar, TB_REPLACEBITMAP, 0, (LPARAM)&tbrepl);
00541 
00542             DeleteObject(hbmp);
00543 
00544             for(TaskBarMap::iterator it=_map.begin(); it!=_map.end(); ++it)
00545                 if (it->second._hbmp == hbmp) {
00546                     _map.erase(it);
00547                     break;
00548                 }
00549         }
00550 
00551         ResizeButtons();
00552     }
00553 }
00554 
00555 TaskBarMap::iterator TaskBarMap::find_id(int id)
00556 {
00557     for(iterator it=begin(); it!=end(); ++it)
00558         if (it->second._id == id)
00559             return it;
00560 
00561     return end();
00562 }
00563 
00564 void TaskBar::ResizeButtons()
00565 {
00566     int btns = _map.size();
00567 
00568     if (btns > 0) {
00569         int bar_width = ClientRect(_hwnd).right;
00570         int btn_width = (bar_width / btns) - 3;
00571 
00572         if (btn_width < TASKBUTTONWIDTH_MIN)
00573             btn_width = TASKBUTTONWIDTH_MIN;
00574         else if (btn_width > TASKBUTTONWIDTH_MAX)
00575             btn_width = TASKBUTTONWIDTH_MAX;
00576 
00577         if (btn_width != _last_btn_width) {
00578             _last_btn_width = btn_width;
00579 
00580             SendMessage(_htoolbar, TB_SETBUTTONWIDTH, 0, MAKELONG(btn_width,btn_width));
00581             SendMessage(_htoolbar, TB_AUTOSIZE, 0, 0);
00582         }
00583     }
00584 }

ROS Explorer Source Code Documentation
generated on 02.01.2013 by doxygen

ROS Explorer Homepage