window.h

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  // ROS Internet Web Browser
00022  //
00023  // window.h
00024  //
00025  // Martin Fuchs, 23.07.2003
00026  //
00027 
00028 
00029 typedef set<HWND> WindowSet;
00030 
00031 
00032  /*
00033     Classes are declared using "struct", not "class" because the default
00034     access mode is "public". This way we can list the member functions in a
00035     natural order without explicitly specifying any access mode at the begin
00036     of the definition.
00037     First are public constructors and destructor, then public member functions.
00038     After that we list protected member varibables and functions. If needed,
00039     private implemenation varibales and functions are positioned at the end.
00040  */
00041 
00042 
00043  /// information structure for creation of a child window
00044 struct ChildWndInfo
00045 {
00046     ChildWndInfo(HWND hwndFrame)
00047      :  _hwndFrame(hwndFrame) {}
00048 
00049     HWND    _hwndFrame;
00050 };
00051 
00052 
00053  /**
00054     Class Window is the base class for several C++ window wrapper classes.
00055     Window objects are allocated from the heap. They are automatically freed
00056     when the window gets destroyed.
00057  */
00058 struct Window : public WindowHandle
00059 {
00060     Window(HWND hwnd);
00061     virtual ~Window();
00062 
00063 
00064     typedef map<HWND,Window*> WindowMap;
00065 
00066     typedef Window* (*CREATORFUNC)(HWND);
00067     typedef Window* (*CREATORFUNC_INFO)(HWND, const void*);
00068 
00069     static HWND Create(CREATORFUNC creator, DWORD dwExStyle,
00070                 LPCTSTR lpClassName, LPCTSTR lpWindowName,
00071                 DWORD dwStyle, int x, int y, int w, int h,
00072                 HWND hwndParent=0, HMENU hMenu=0/*, LPVOID lpParam=0*/);
00073 
00074     static HWND Create(CREATORFUNC_INFO creator, const void* info,
00075                 DWORD dwExStyle, LPCTSTR lpClassName, LPCTSTR lpWindowName,
00076                 DWORD dwStyle, int x, int y, int w, int h,
00077                 HWND hwndParent=0, HMENU hMenu=0/*, LPVOID lpParam=0*/);
00078 
00079     static LRESULT CALLBACK WindowWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
00080     static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
00081 
00082     static Window* get_window(HWND hwnd);
00083 #ifndef _MSC_VER
00084     template<typename CLASS> static CLASS* get_window(HWND hwnd) {return static_cast<CLASS*>(get_window(hwnd));}
00085 #define GET_WINDOW(CLASS, hwnd) Window::get_window<CLASS>(hwnd)
00086 #endif
00087 
00088     static void register_pretranslate(HWND hwnd);
00089     static void unregister_pretranslate(HWND hwnd);
00090     static BOOL pretranslate_msg(LPMSG pmsg);
00091 
00092     static void register_dialog(HWND hwnd);
00093     static void unregister_dialog(HWND hwnd);
00094     static BOOL dispatch_dialog_msg(LPMSG pmsg);
00095 
00096     static int  MessageLoop();
00097 
00098 
00099     LRESULT SendParent(UINT nmsg, WPARAM wparam=0, LPARAM lparam=0);
00100     LRESULT PostParent(UINT nmsg, WPARAM wparam=0, LPARAM lparam=0);
00101 
00102     static void CancelModes(HWND hwnd=0);
00103 
00104 
00105 protected:
00106     virtual LRESULT Init(LPCREATESTRUCT pcs);                           // WM_CREATE processing
00107     virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
00108     virtual int     Command(int id, int code);                          // WM_COMMAND processing
00109     virtual int     Notify(int id, NMHDR* pnmh);                        // WM_NOTIFY processing
00110 
00111     static Window* create_controller(HWND hwnd);
00112 
00113 
00114     static WindowMap    s_wnd_map;
00115 
00116     static const void*  s_new_info;
00117     static CREATORFUNC  s_window_creator;
00118 
00119 
00120      /// structure for managing critical sections as static class information in struct Window
00121     struct StaticWindowData {
00122         CritSect    _map_crit_sect;
00123         CritSect    _create_crit_sect;
00124     };
00125 
00126     static StaticWindowData& GetStaticWindowData();
00127 
00128 
00129     static WindowSet s_pretranslate_windows;
00130     static WindowSet s_dialogs;
00131 };
00132 
00133 #ifdef UNICODE
00134 #define NFR_CURRENT NFR_UNICODE
00135 #else
00136 #define NFR_CURRENT NFR_ANSI
00137 #endif
00138 
00139 
00140 #ifdef _MSC_VER
00141 template<typename CLASS> struct GetWindowHelper
00142 {
00143     static CLASS* get_window(HWND hwnd) {
00144         return static_cast<CLASS*>(Window::get_window(hwnd));
00145     }
00146 };
00147 #define GET_WINDOW(CLASS, hwnd) GetWindowHelper<CLASS>::get_window(hwnd)
00148 #endif
00149 
00150 
00151  /// dynamic casting of Window pointers
00152 template<typename CLASS> struct TypeCheck
00153 {
00154     static CLASS* dyn_cast(Window* wnd)
00155         {return dynamic_cast<CLASS*>(wnd);}
00156 };
00157 
00158 #define WINDOW_DYNAMIC_CAST(CLASS, hwnd) \
00159     TypeCheck<CLASS>::dyn_cast(Window::get_window(hwnd))
00160 
00161 
00162  /**
00163     SubclassedWindow is used to wrap already existing window handles
00164     into C++ Window objects. To construct a object, use the "new" operator
00165     to put it in the heap. It is automatically freed, when the window
00166     gets destroyed.
00167  */
00168 struct SubclassedWindow : public Window
00169 {
00170     typedef Window super;
00171 
00172     SubclassedWindow(HWND);
00173 
00174 protected:
00175     WNDPROC _orgWndProc;
00176 
00177     static LRESULT CALLBACK SubclassedWndProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
00178 
00179     virtual LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
00180     virtual int     Command(int id, int code);
00181     virtual int     Notify(int id, NMHDR* pnmh);
00182 };
00183 
00184 
00185  /// template class used in macro WINDOW_CREATOR to define the creater functions for Window objects
00186 template<typename WND_CLASS> struct WindowCreator
00187 {
00188     static WND_CLASS* window_creator(HWND hwnd)
00189     {
00190         return new WND_CLASS(hwnd);
00191     }
00192 };
00193 
00194 #define WINDOW_CREATOR(WND_CLASS) \
00195     ((Window::CREATORFUNC) WindowCreator<WND_CLASS>::window_creator)
00196 
00197 
00198  /// template class used in macro WINDOW_CREATOR_INFO to the define creater functions for Window objects with additional creation information
00199 template<typename WND_CLASS, typename INFO_CLASS> struct WindowCreatorInfo
00200 {
00201     static WND_CLASS* window_creator(HWND hwnd, const void* info)
00202     {
00203         return new WND_CLASS(hwnd, *static_cast<const INFO_CLASS*>(info));
00204     }
00205 };
00206 
00207 #define WINDOW_CREATOR_INFO(WND_CLASS, INFO_CLASS) \
00208     ((Window::CREATORFUNC_INFO) WindowCreatorInfo<WND_CLASS, INFO_CLASS>::window_creator)
00209 
00210 
00211  /**
00212     WindowClass is a neat wrapper for RegisterClassEx().
00213     Just construct a WindowClass object, override the attributes you want
00214     to change, then call Register() or simply request the ATOM value to
00215     register the window class. You don't have to worry calling Register()
00216     more than once. It checks if, the class has already been registered.
00217  */
00218 struct WindowClass : public WNDCLASSEX
00219 {
00220     WindowClass(LPCTSTR classname, UINT style=0, WNDPROC wndproc=Window::WindowWndProc);
00221 
00222     ATOM Register()
00223     {
00224         if (!_atomClass)
00225             _atomClass = RegisterClassEx(this);
00226 
00227         return _atomClass;
00228     }
00229 
00230     operator ATOM() {return Register();}
00231 
00232      // return LPCTSTR for the CreateWindowEx() parameter
00233     operator LPCTSTR() {return (LPCTSTR)(int)Register();}
00234 
00235 protected:
00236     ATOM    _atomClass;
00237 };
00238 
00239  /// window class with gray background color
00240 struct BtnWindowClass : public WindowClass
00241 {
00242     BtnWindowClass(LPCTSTR classname, UINT style=0, WNDPROC wndproc=Window::WindowWndProc)
00243      :  WindowClass(classname, style, wndproc)
00244     {
00245         hbrBackground = (HBRUSH)(COLOR_BTNFACE+1);
00246     }
00247 };
00248 
00249  /// window class with specified icon from resources
00250 struct IconWindowClass : public WindowClass
00251 {
00252     IconWindowClass(LPCTSTR classname, UINT nid, UINT style=0, WNDPROC wndproc=Window::WindowWndProc);
00253 };
00254 
00255 
00256  // private message constants
00257 #define PM_DISPATCH_COMMAND     (WM_APP+0x00)
00258 #define PM_TRANSLATE_MSG        (WM_APP+0x01)
00259 
00260 
00261 #define SPLIT_WIDTH         5
00262 #define DEFAULT_SPLIT_POS   300
00263 #define COLOR_SPLITBAR      LTGRAY_BRUSH
00264 
00265 
00266  /// menu info structure
00267 struct MenuInfo
00268 {
00269     HMENU   _hMenuView;
00270 };
00271 
00272 #define PM_FRM_GET_MENUINFO     (WM_APP+0x02)
00273 
00274 #define Frame_GetMenuInfo(hwnd) ((MenuInfo*)SNDMSG(hwnd, PM_FRM_GET_MENUINFO, 0, 0))
00275 
00276 
00277  /**
00278     Class ChildWindow is used with class MainFrame.
00279  */
00280 struct ChildWindow : public Window
00281 {
00282     typedef Window super;
00283 
00284     ChildWindow(HWND hwnd, HWND hwndFrame);
00285 
00286     static ChildWindow* create(const ChildWndInfo& info, CREATORFUNC_INFO creator,
00287                                 LPCTSTR classname, LPCTSTR title=NULL, DWORD style=0);
00288 
00289     bool    go_to(LPCTSTR url);
00290 
00291 protected:
00292     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
00293 
00294     virtual String jump_to_int(LPCTSTR url) = 0;
00295 
00296 protected:
00297     MenuInfo*_menu_info;
00298 
00299     HWND    _hwndFrame;
00300     String  _statusText;
00301     String  _url;
00302 
00303     stack<String> _url_history;
00304 
00305     void    set_url(LPCTSTR url);
00306 };
00307 
00308 #define PM_SETSTATUSTEXT        (WM_APP+0x1E)
00309 
00310 
00311  /**
00312     PreTranslateWindow is used to register windows to be called by Window::pretranslate_msg().
00313     This way you get PM_TRANSLATE_MSG messages before the message loop dispatches messages.
00314     You can then for example use TranslateAccelerator() to implement key shortcuts.
00315  */
00316 struct PreTranslateWindow : public Window
00317 {
00318     typedef Window super;
00319 
00320     PreTranslateWindow(HWND);
00321     ~PreTranslateWindow();
00322 };
00323 
00324 
00325  /**
00326     The class DialogWindow implements modeless dialogs, which are managed by
00327     Window::dispatch_dialog_msg() in Window::MessageLoop().
00328     A DialogWindow object should be constructed by calling Window::Create()
00329     and specifying the class using the WINDOW_CREATOR() macro.
00330  */
00331 struct DialogWindow : public Window
00332 {
00333     typedef Window super;
00334 
00335     DialogWindow(HWND hwnd)
00336      :  super(hwnd)
00337     {
00338         register_dialog(hwnd);
00339     }
00340 
00341     ~DialogWindow()
00342     {
00343         unregister_dialog(_hwnd);
00344     }
00345 };
00346 
00347 
00348  /**
00349     The class Dialog implements modal dialogs.
00350     A Dialog object should be constructed by calling Dialog::DoModal()
00351     and specifying the class using the WINDOW_CREATOR() macro.
00352  */
00353 struct Dialog : public Window
00354 {
00355     typedef Window super;
00356 
00357     Dialog(HWND);
00358     ~Dialog();
00359 
00360     static int DoModal(UINT nid, CREATORFUNC creator, HWND hwndParent=0);
00361     static int DoModal(UINT nid, CREATORFUNC_INFO creator, const void* info, HWND hwndParent=0);
00362 
00363 protected:
00364     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
00365     int     Command(int id, int code);
00366 };
00367 
00368 
00369 #define PM_FRM_CALC_CLIENT      (WM_APP+0x03)
00370 #define Frame_CalcFrameClient(hwnd, prt) ((BOOL)SNDMSG(hwnd, PM_FRM_CALC_CLIENT, 0, (LPARAM)(PRECT)prt))
00371 
00372 #define PM_JUMP_TO_URL          (WM_APP+0x25)
00373 #define PM_URL_CHANGED          (WM_APP+0x26)
00374 
00375 
00376 struct PropSheetPage : public PROPSHEETPAGE
00377 {
00378     PropSheetPage(UINT nid, Window::CREATORFUNC dlg_creator);
00379 
00380     void    init(struct PropertySheetDialog*);
00381 
00382 protected:
00383     friend struct PropSheetPageDlg;
00384 
00385     Window::CREATORFUNC _dlg_creator;
00386 };
00387 
00388 
00389  /// Property Sheet dialog
00390 struct PropertySheetDialog : public PROPSHEETHEADER
00391 {
00392     PropertySheetDialog(HWND owner);
00393 
00394     void    add(PropSheetPage& psp);
00395     int     DoModal(int start_page=0);
00396 
00397     HWND    GetCurrentPage();
00398 
00399 protected:
00400     typedef vector<PROPSHEETPAGE> Vector;
00401     Vector  _pages;
00402     HWND    _hwnd;
00403 };
00404 
00405 
00406  /// Property Sheet Page (inner dialog)
00407 struct PropSheetPageDlg : public Dialog
00408 {
00409     typedef Dialog super;
00410 
00411     PropSheetPageDlg(HWND);
00412 
00413 protected:
00414     friend struct PropertySheetDialog;
00415     friend struct PropSheetPage;
00416 
00417     static INT_PTR CALLBACK DialogProc(HWND hwnd, UINT nmsg, WPARAM wparam, LPARAM lparam);
00418 
00419     int Command(int id, int code);
00420 };
00421 
00422 
00423 /*
00424  /// Property Sheet Dialog (outer dialog)
00425 struct PropertySheetDlg : public SubclassedWindow
00426 {
00427     typedef SubclassedWindow super;
00428 
00429     PropertySheetDlg(HWND hwnd) : super(hwnd) {}
00430 };
00431 */
00432 
00433 
00434  // Layouting of resizable windows
00435 
00436  /// Flags to specify how to move and resize controls when resizing their parent window
00437 enum RESIZE_FLAGS {
00438     MOVE_LEFT   = 0x1,
00439     MOVE_RIGHT  = 0x2,
00440     MOVE_TOP    = 0x4,
00441     MOVE_BOTTOM = 0x8,
00442 
00443     MOVE_X  =  MOVE_LEFT | MOVE_RIGHT,
00444     MOVE_Y  =  MOVE_TOP | MOVE_BOTTOM,
00445     RESIZE_X=  MOVE_RIGHT,
00446     RESIZE_Y=  MOVE_BOTTOM,
00447 
00448     MOVE    = MOVE_X   | MOVE_Y,
00449     RESIZE  = RESIZE_X | RESIZE_Y
00450 };
00451 
00452  /// structure to assign RESIZE_FLAGS to dialogs control
00453 struct ResizeEntry
00454 {
00455     ResizeEntry(UINT id, int flags)
00456      : _id(id), _flags(flags) {}
00457 
00458     ResizeEntry(HWND hwnd, int flags)
00459      : _id(GetDlgCtrlID(hwnd)), _flags(flags) {}
00460 
00461     UINT    _id;
00462     int     _flags;
00463 };
00464 
00465 
00466  /// Management of controls in resizable dialogs
00467 struct ResizeManager : public std::list<ResizeEntry>
00468 {
00469     typedef std::list<ResizeEntry> super;
00470 
00471     ResizeManager(HWND hwnd);
00472 
00473     void Add(UINT id, int flags)
00474         {push_back(ResizeEntry(id, flags));}
00475 
00476     void Add(HWND hwnd, int flags)
00477         {push_back(ResizeEntry(hwnd, flags));}
00478 
00479     void HandleSize(int cx, int cy);
00480     void Resize(int dx, int dy);
00481 
00482     void SetMinMaxInfo(LPMINMAXINFO lpmmi)
00483     {
00484         lpmmi->ptMinTrackSize.x = _min_wnd_size.cx;
00485         lpmmi->ptMinTrackSize.y = _min_wnd_size.cy;
00486     }
00487 
00488     SIZE    _min_wnd_size;
00489 
00490 protected:
00491     HWND    _hwnd;
00492     SIZE    _last_size;
00493 };
00494 
00495 
00496  /// Controller base template class for resizable dialogs
00497 template<typename BASE> struct ResizeController : public BASE
00498 {
00499     typedef BASE super;
00500 
00501     ResizeController(HWND hwnd)
00502      :  super(hwnd),
00503         _resize_mgr(hwnd)
00504     {
00505     }
00506 
00507     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
00508     {
00509         switch(nmsg) {
00510           case PM_FRM_CALC_CLIENT:
00511             GetClientSpace((PRECT)lparam);
00512             return TRUE;
00513 
00514           case WM_SIZE:
00515             if (wparam != SIZE_MINIMIZED)
00516                 _resize_mgr.HandleSize(LOWORD(lparam), HIWORD(lparam));
00517             goto def;
00518 
00519           case WM_GETMINMAXINFO:
00520             _resize_mgr.SetMinMaxInfo((LPMINMAXINFO)lparam);
00521             goto def;
00522 
00523           default: def:
00524             return super::WndProc(nmsg, wparam, lparam);
00525         }
00526     }
00527 
00528     virtual void GetClientSpace(PRECT prect)
00529     {
00530          if (!IsIconic(this->_hwnd)) {
00531             GetClientRect(this->_hwnd, prect);
00532          } else {
00533             WINDOWPLACEMENT wp;
00534             GetWindowPlacement(this->_hwnd, &wp);
00535             prect->left = prect->top = 0;
00536             prect->right = wp.rcNormalPosition.right-wp.rcNormalPosition.left-
00537                 2*(GetSystemMetrics(SM_CXSIZEFRAME)+GetSystemMetrics(SM_CXEDGE));
00538             prect->bottom = wp.rcNormalPosition.bottom-wp.rcNormalPosition.top-
00539                 2*(GetSystemMetrics(SM_CYSIZEFRAME)+GetSystemMetrics(SM_CYEDGE))-
00540                 GetSystemMetrics(SM_CYCAPTION)-GetSystemMetrics(SM_CYMENUSIZE);
00541         }
00542     }
00543 
00544 protected:
00545     ResizeManager _resize_mgr;
00546 };
00547 
00548 
00549  /**
00550     This class constructs button controls.
00551     The button will remain existent when the C++ Button object is destroyed.
00552     There is no conjunction between C++ object and windows control life time.
00553  */
00554 struct Button : public WindowHandle
00555 {
00556     Button(HWND parent, LPCTSTR text, int left, int top, int width, int height,
00557             int id, DWORD flags=WS_VISIBLE|WS_CHILD|BS_PUSHBUTTON, DWORD exStyle=0);
00558 };
00559 
00560 
00561  /**
00562     This class constructs static controls.
00563     The control will remain existent when the C++ object is destroyed.
00564     There is no conjunction between C++ object and windows control life time.
00565  */
00566 struct Static : public WindowHandle
00567 {
00568     Static(HWND parent, LPCTSTR text, int left, int top, int width, int height,
00569             int id, DWORD flags=WS_VISIBLE|WS_CHILD|SS_SIMPLE, DWORD ex_flags=0);
00570 };
00571 
00572 
00573  // control color message routing for ColorStatic and HyperlinkCtrl
00574 
00575 #define PM_DISPATCH_CTLCOLOR    (WM_APP+0x08)
00576 
00577 template<typename BASE> struct CtlColorParent : public BASE
00578 {
00579     typedef BASE super;
00580 
00581     CtlColorParent(HWND hwnd)
00582      : super(hwnd) {}
00583 
00584     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
00585     {
00586         switch(nmsg) {
00587           case WM_CTLCOLOR:
00588           case WM_CTLCOLORBTN:
00589           case WM_CTLCOLORDLG:
00590           case WM_CTLCOLORSCROLLBAR:
00591           case WM_CTLCOLORSTATIC: {
00592             HWND hctl = (HWND) lparam;
00593             return SendMessage(hctl, PM_DISPATCH_CTLCOLOR, wparam, nmsg);
00594           }
00595 
00596           default:
00597             return super::WndProc(nmsg, wparam, lparam);
00598         }
00599     }
00600 };
00601 
00602 
00603 #define PM_DISPATCH_DRAWITEM    (WM_APP+0x09)
00604 
00605  /// draw message routing for ColorButton and PictureButton
00606 template<typename BASE> struct OwnerDrawParent : public BASE
00607 {
00608     typedef BASE super;
00609 
00610     OwnerDrawParent(HWND hwnd)
00611      : super(hwnd) {}
00612 
00613     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
00614     {
00615         switch(nmsg) {
00616           case WM_DRAWITEM:
00617             if (wparam) {   // should there be drawn a control?
00618                 HWND hctl = GetDlgItem(this->_hwnd, wparam);
00619 
00620                 if (hctl)
00621                     return SendMessage(hctl, PM_DISPATCH_DRAWITEM, wparam, lparam);
00622             } /*else        // or is it a menu entry?
00623                 ; */
00624 
00625             return 0;
00626 
00627           default:
00628             return super::WndProc(nmsg, wparam, lparam);
00629         }
00630     }
00631 };
00632 
00633 
00634  /**
00635     Subclass button controls to draw them by using PM_DISPATCH_DRAWITEM
00636     The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
00637  */
00638 struct OwnerdrawnButton : public SubclassedWindow
00639 {
00640     typedef SubclassedWindow super;
00641 
00642     OwnerdrawnButton(HWND hwnd)
00643      :  super(hwnd) {}
00644 
00645 protected:
00646     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
00647 
00648     virtual void DrawItem(LPDRAWITEMSTRUCT dis) = 0;
00649 };
00650 
00651 extern void DrawGrayText(HDC hdc, LPRECT pRect, LPCTSTR text, int dt_flags);
00652 
00653 
00654  /**
00655     Subclass button controls to paint colored text labels.
00656     The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
00657  */
00658 /* not yet used
00659 struct ColorButton : public OwnerdrawnButton
00660 {
00661     typedef OwnerdrawnButton super;
00662 
00663     ColorButton(HWND hwnd, COLORREF textColor)
00664      :  super(hwnd), _textColor(textColor) {}
00665 
00666 protected:
00667     virtual void DrawItem(LPDRAWITEMSTRUCT dis);
00668 
00669     COLORREF _textColor;
00670 };
00671 */
00672 
00673 
00674 struct FlatButton : public OwnerdrawnButton
00675 {
00676     typedef OwnerdrawnButton super;
00677 
00678     FlatButton(HWND hwnd)
00679      : super(hwnd), _active(false) {}
00680 
00681     FlatButton(HWND owner, int id)
00682      : super(GetDlgItem(owner, IDOK)), _active(false) {}
00683 
00684 protected:
00685     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
00686     virtual void DrawItem(LPDRAWITEMSTRUCT dis);
00687 
00688     COLORREF _textColor;
00689     COLORREF _activeColor;
00690     bool    _active;
00691 };
00692 
00693 
00694  /**
00695     Subclass button controls to paint pictures left to the labels.
00696     The buttons should have set the style bit BS_OWNERDRAW.
00697     The owning window should use the OwnerDrawParent template to route owner draw messages to the buttons.
00698  */
00699 struct PictureButton : public OwnerdrawnButton
00700 {
00701     typedef OwnerdrawnButton super;
00702 
00703     PictureButton(HWND hwnd, HICON hIcon, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
00704      :  super(hwnd), _hIcon(hIcon), _hBmp(0), _hBrush(hbrush), _flat(flat)
00705     {
00706         _cx = 16;
00707         _cy = 16;
00708     }
00709 
00710     PictureButton(HWND hparent, int id, HICON hIcon, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
00711      :  super(GetDlgItem(hparent, id)), _hIcon(hIcon), _hBmp(0), _hBrush(hbrush), _flat(flat)
00712     {
00713         _cx = 16;
00714         _cy = 16;
00715     }
00716 
00717     PictureButton(HWND hwnd, HBITMAP hBmp, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
00718      :  super(hwnd), _hIcon(0), _hBmp(hBmp), _hBrush(hbrush), _flat(flat)
00719     {
00720         BITMAP bmp;
00721         GetObject(hBmp, sizeof(bmp), &bmp);
00722         _cx = bmp.bmWidth;
00723         _cy = bmp.bmHeight;
00724     }
00725 
00726     PictureButton(HWND hparent, int id, HBITMAP hBmp, HBRUSH hbrush=GetSysColorBrush(COLOR_BTNFACE), bool flat=false)
00727      :  super(GetDlgItem(hparent, id)), _hIcon(0), _hBmp(hBmp), _hBrush(hbrush), _flat(flat)
00728     {
00729         BITMAP bmp;
00730         GetObject(hBmp, sizeof(bmp), &bmp);
00731         _cx = bmp.bmWidth;
00732         _cy = bmp.bmHeight;
00733     }
00734 
00735 protected:
00736     virtual void DrawItem(LPDRAWITEMSTRUCT dis);
00737 
00738     HICON   _hIcon;
00739     HBITMAP _hBmp;
00740     HBRUSH  _hBrush;
00741 
00742     int     _cx;
00743     int     _cy;
00744 
00745     bool    _flat;
00746 };
00747 
00748 
00749 struct ColorStatic : public SubclassedWindow
00750 {
00751     typedef SubclassedWindow super;
00752 
00753     ColorStatic(HWND hwnd, COLORREF textColor=RGB(255,0,0), HBRUSH hbrush_bkgnd=0, HFONT hfont=0)
00754      :  super(hwnd),
00755         _textColor(textColor),
00756         _hbrush_bkgnd(hbrush_bkgnd),
00757         _hfont(hfont)
00758     {
00759     }
00760 
00761     ColorStatic(HWND owner, int id, COLORREF textColor=RGB(255,0,0), HBRUSH hbrush_bkgnd=0, HFONT hfont=0)
00762      :  super(GetDlgItem(owner, id)),
00763         _textColor(textColor),
00764         _hbrush_bkgnd(hbrush_bkgnd),
00765         _hfont(hfont)
00766     {
00767     }
00768 
00769 protected:
00770     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
00771     {
00772         if (nmsg == PM_DISPATCH_CTLCOLOR) {
00773             HDC hdc = (HDC) wparam;
00774 
00775             SetTextColor(hdc, _textColor);
00776 
00777             if (_hfont)
00778                 SelectFont(hdc, _hfont);
00779 
00780             if (_hbrush_bkgnd)
00781                 return (LRESULT)_hbrush_bkgnd;
00782             else {
00783                 SetBkMode(hdc, TRANSPARENT);
00784                 return (LRESULT)GetStockBrush(HOLLOW_BRUSH);
00785             }
00786         } else
00787             return super::WndProc(nmsg, wparam, lparam);
00788     }
00789 
00790     COLORREF    _textColor;
00791     HBRUSH      _hbrush_bkgnd;
00792     HFONT       _hfont;
00793 };
00794 
00795 
00796   /// Hyperlink Controls
00797 
00798 struct HyperlinkCtrl : public SubclassedWindow
00799 {
00800     typedef SubclassedWindow super;
00801 
00802     HyperlinkCtrl(HWND hwnd, COLORREF colorLink=RGB(0,0,255), COLORREF colorVisited=RGB(128,0,128));
00803     HyperlinkCtrl(HWND owner, int id, COLORREF colorLink=RGB(0,0,255), COLORREF colorVisited=RGB(128,0,128));
00804 
00805     ~HyperlinkCtrl();
00806 
00807     String  _cmd;
00808 
00809 protected:
00810     COLORREF _textColor;
00811     COLORREF _colorVisited;
00812     HFONT    _hfont;
00813     HCURSOR _crsr_link;
00814 
00815     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam);
00816 
00817     void init();
00818 
00819     bool LaunchLink()
00820     {
00821         if (!_cmd.empty()) {
00822             HINSTANCE hinst = ShellExecute(GetParent(_hwnd), _T("open"), _cmd, 0, 0, SW_SHOWNORMAL);
00823             return (int)hinst > HINSTANCE_ERROR;
00824         }
00825 
00826         return true;
00827     }
00828 };
00829 
00830 
00831  /// encapsulation of tool tip controls
00832 struct ToolTip : public WindowHandle
00833 {
00834     typedef WindowHandle super;
00835 
00836     ToolTip(HWND owner);
00837 
00838     void activate(BOOL active=TRUE)
00839     {
00840         SendMessage(_hwnd, TTM_ACTIVATE, active, 0);
00841     }
00842 
00843     void add(HWND hparent, HWND htool, LPCTSTR txt=LPSTR_TEXTCALLBACK, LPARAM lparam=0)
00844     {
00845         TOOLINFO ti = {
00846             sizeof(TOOLINFO), TTF_SUBCLASS|TTF_IDISHWND|TTF_TRANSPARENT, hparent, (UINT)htool,
00847             {0,0,0,0}, 0, (LPTSTR)txt, lparam
00848         };
00849 
00850 #ifdef UNICODE  ///@todo Why is it neccesary to try both TTM_ADDTOOLW and TTM_ADDTOOLW ?!
00851         if (!SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti))
00852             SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
00853 #else
00854         if (!SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti))
00855             SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti);
00856 #endif
00857     }
00858 
00859     void add(HWND hparent, UINT id, const RECT& rect, LPCTSTR txt=LPSTR_TEXTCALLBACK, LPARAM lparam=0)
00860     {
00861         TOOLINFO ti = {
00862             sizeof(TOOLINFO), TTF_SUBCLASS|TTF_TRANSPARENT, hparent, id,
00863             {rect.left,rect.top,rect.right,rect.bottom}, 0, (LPTSTR)txt, lparam
00864         };
00865 
00866 #ifdef UNICODE
00867         if (!SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti))
00868             SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti);
00869 #else
00870         if (!SendMessage(_hwnd, TTM_ADDTOOLA, 0, (LPARAM)&ti))
00871             SendMessage(_hwnd, TTM_ADDTOOLW, 0, (LPARAM)&ti);
00872 #endif
00873     }
00874 
00875     void remove(HWND hparent, HWND htool)
00876     {
00877         TOOLINFO ti = {
00878             sizeof(TOOLINFO), TTF_IDISHWND, hparent, (UINT)htool,
00879             {0,0,0,0}, 0, 0, 0
00880         };
00881 
00882         SendMessage(_hwnd, TTM_DELTOOL, 0, (LPARAM)&ti);
00883     }
00884 
00885     void remove(HWND hparent, UINT id)
00886     {
00887         TOOLINFO ti = {
00888             sizeof(TOOLINFO), 0, hparent, id,
00889             {0,0,0,0}, 0, 0, 0
00890         };
00891 
00892         SendMessage(_hwnd, TTM_DELTOOL, 0, (LPARAM)&ti);
00893     }
00894 };
00895 
00896 
00897 inline int ListView_GetItemData(HWND list_ctrl, int idx)
00898 {
00899     LV_ITEM item;
00900 
00901     item.mask = LVIF_PARAM;
00902     item.iItem = idx;
00903 
00904     if (!ListView_GetItem(list_ctrl, &item))
00905         return 0;
00906 
00907     return item.lParam;
00908 }
00909 
00910 inline int ListView_FindItemPara(HWND list_ctrl, LPARAM param)
00911 {
00912     LVFINDINFO fi;
00913 
00914     fi.flags = LVFI_PARAM;
00915     fi.lParam = param;
00916 
00917     return ListView_FindItem(list_ctrl, (unsigned)-1, &fi);
00918 }
00919 
00920 inline int ListView_GetFocusedItem(HWND list_ctrl)
00921 {
00922     int idx = ListView_GetItemCount(list_ctrl);
00923 
00924     while(--idx >= 0)
00925         if (ListView_GetItemState(list_ctrl, idx, LVIS_FOCUSED))
00926             break;
00927 
00928     return idx;
00929 }
00930 
00931 
00932  /// sorting of list controls
00933 struct ListSort : public WindowHandle
00934 {
00935     ListSort(HWND hwndListview, PFNLVCOMPARE compare_fct);
00936 
00937     void    toggle_sort(int idx);
00938     void    sort();
00939 
00940     int     _sort_crit;
00941     bool    _direction;
00942 
00943 protected:
00944     PFNLVCOMPARE _compare_fct;
00945 
00946     static int CALLBACK CompareFunc(LPARAM lparam1, LPARAM lparam2, LPARAM lparamSort);
00947 };
00948 
00949 
00950 inline LPARAM TreeView_GetItemData(HWND hwndTreeView, HTREEITEM hItem)
00951 {
00952     TVITEM tvItem;
00953 
00954     tvItem.mask = TVIF_PARAM;
00955     tvItem.hItem = hItem;
00956 
00957     if (!TreeView_GetItem(hwndTreeView, &tvItem))
00958         return 0;
00959 
00960     return tvItem.lParam;
00961 }
00962 
00963 
00964 enum {TRAYBUTTON_LEFT=0, TRAYBUTTON_RIGHT, TRAYBUTTON_MIDDLE};
00965 
00966 #define PM_TRAYICON     (WM_APP+0x20)
00967 
00968 #define WINMSG_TASKBARCREATED   TEXT("TaskbarCreated")
00969 
00970 
00971 struct TrayIcon
00972 {
00973     TrayIcon(HWND hparent, UINT id)
00974      :  _hparent(hparent), _id(id) {}
00975 
00976     ~TrayIcon()
00977         {Remove();}
00978 
00979     void    Add(HICON hIcon, LPCTSTR tooltip=NULL)
00980         {Set(NIM_ADD, _id, hIcon, tooltip);}
00981 
00982     void    Modify(HICON hIcon, LPCTSTR tooltip=NULL)
00983         {Set(NIM_MODIFY, _id, hIcon, tooltip);}
00984 
00985     void    Remove()
00986     {
00987         NOTIFYICONDATA nid = {
00988             sizeof(NOTIFYICONDATA), // cbSize
00989             _hparent,               // hWnd
00990             _id,                    // uID
00991         };
00992 
00993         Shell_NotifyIcon(NIM_DELETE, &nid);
00994     }
00995 
00996 protected:
00997     HWND    _hparent;
00998     UINT    _id;
00999 
01000     void    Set(DWORD dwMessage, UINT id, HICON hIcon, LPCTSTR tooltip=NULL)
01001     {
01002         NOTIFYICONDATA nid = {
01003             sizeof(NOTIFYICONDATA), // cbSize
01004             _hparent,               // hWnd
01005             id,                     // uID
01006             NIF_MESSAGE|NIF_ICON,   // uFlags
01007             PM_TRAYICON,            // uCallbackMessage
01008             hIcon                   // hIcon
01009         };
01010 
01011         if (tooltip)
01012             lstrcpyn(nid.szTip, tooltip, COUNTOF(nid.szTip));
01013 
01014         if (nid.szTip[0])
01015             nid.uFlags |= NIF_TIP;
01016 
01017         Shell_NotifyIcon(dwMessage, &nid);
01018     }
01019 };
01020 
01021 
01022 template<typename BASE> struct TrayIconControllerTemplate : public BASE
01023 {
01024     typedef BASE super;
01025 
01026     TrayIconControllerTemplate(HWND hwnd) : BASE(hwnd),
01027         WM_TASKBARCREATED(RegisterWindowMessage(WINMSG_TASKBARCREATED))
01028     {
01029     }
01030 
01031     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
01032     {
01033         if (nmsg == PM_TRAYICON) {
01034             switch(lparam) {
01035               case WM_MOUSEMOVE:
01036                 TrayMouseOver(wparam);
01037                 break;
01038 
01039               case WM_LBUTTONDOWN:
01040                 TrayClick(wparam, TRAYBUTTON_LEFT);
01041                 break;
01042 
01043               case WM_LBUTTONDBLCLK:
01044                 TrayDblClick(wparam, TRAYBUTTON_LEFT);
01045                 break;
01046 
01047               case WM_RBUTTONDOWN:
01048                 TrayClick(wparam, TRAYBUTTON_RIGHT);
01049                 break;
01050 
01051               case WM_RBUTTONDBLCLK:
01052                 TrayDblClick(wparam, TRAYBUTTON_RIGHT);
01053                 break;
01054 
01055               case WM_MBUTTONDOWN:
01056                 TrayClick(wparam, TRAYBUTTON_MIDDLE);
01057                 break;
01058 
01059               case WM_MBUTTONDBLCLK:
01060                 TrayDblClick(wparam, TRAYBUTTON_MIDDLE);
01061                 break;
01062             }
01063 
01064             return 0;
01065         } else if (nmsg == WM_TASKBARCREATED) {
01066             AddTrayIcons();
01067             return 0;
01068         } else
01069             return super::WndProc(nmsg, wparam, lparam);
01070     }
01071 
01072     virtual void AddTrayIcons() = 0;
01073     virtual void TrayMouseOver(UINT id) {}
01074     virtual void TrayClick(UINT id, int btn) {}
01075     virtual void TrayDblClick(UINT id, int btn) {}
01076 
01077 protected:
01078     const UINT WM_TASKBARCREATED;
01079 };
01080 
01081 
01082 struct EditController : public SubclassedWindow
01083 {
01084     typedef SubclassedWindow super;
01085 
01086     EditController(HWND hwnd)
01087      :  super(hwnd)
01088     {
01089     }
01090 
01091 protected:
01092     LRESULT WndProc(UINT nmsg, WPARAM wparam, LPARAM lparam)
01093     {
01094         if (nmsg==WM_KEYDOWN && wparam==VK_RETURN) {
01095             SendParent(WM_COMMAND, MAKEWPARAM(GetDlgCtrlID(_hwnd),1), (LPARAM)_hwnd);
01096             return 0;
01097         } else
01098             return super::WndProc(nmsg, wparam, lparam);
01099     }
01100 };

IBrowser Source Code Documentation
generated on 18.09.2008 by doxygen

Homepage