1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/xhtml;charset=UTF-8"/>
<meta http-equiv="X-UA-Compatible" content="IE=9"/>
<title>wxWidgets: Creating a Custom Widget</title>
<link href="tabs.css" rel="stylesheet" type="text/css"/>
<script type="text/javascript" src="jquery.js"></script>
<script type="text/javascript" src="dynsections.js"></script>
<link href="doxygen.css" rel="stylesheet" type="text/css" />
<link href="extra_stylesheet.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<div id="page_container">
<div id="top"><!-- do not remove this div, it is closed by doxygen! -->
<div id="titlearea">
<table cellspacing="0" cellpadding="0" style="width: 100%;">
<tbody>
<tr>
<td id="projectlogo">
<a href="http://www.wxwidgets.org/" target="_new">
<img alt="wxWidgets" src="logo.png"/>
</a>
</td>
<td style="padding-left: 0.5em; text-align: right;">
<span id="projectnumber">Version: 3.0.2</span>
</td>
</tr>
</tbody>
</table>
</div>
<!-- Generated by Doxygen 1.8.2 -->
<div id="navrow1" class="tabs">
<ul class="tablist">
<li><a href="index.html"><span>Main Page</span></a></li>
<li class="current"><a href="pages.html"><span>Related Pages</span></a></li>
<li><a href="modules.html"><span>Categories</span></a></li>
<li><a href="annotated.html"><span>Classes</span></a></li>
<li><a href="files.html"><span>Files</span></a></li>
</ul>
</div>
<div id="nav-path" class="navpath">
<ul>
<li class="navelem"><a class="el" href="index.html">Documentation</a></li><li class="navelem"><a class="el" href="page_topics.html">Programming Guides</a></li> </ul>
</div>
</div><!-- top -->
<div class="header">
<div class="headertitle">
<div class="title">Creating a Custom Widget </div> </div>
</div><!--header-->
<div class="contents">
<div class="toc"><h3>Table of Contents</h3>
<ul><li class="level1"><a href="#overview_customwidgets_how">Writing a Custom Widget</a><ul><li class="level2"><a href="#overview_customwidgets_how_generic">Writing a Generic Widget</a></li>
<li class="level2"><a href="#overview_customwidgets_how_native">Writing a Native Widget</a></li>
</ul>
</li>
</ul>
</div>
<div class="textblock"><p>Typically combining the existing <a class="el" href="group__group__class__ctrl.html">Controls</a> controls in wxDialogs and wxFrames is sufficient to fullfill any GUI design.</p>
<p>Using the wxWidgets standard controls makes your GUI looks native on all ports and is obviously easier and faster.</p>
<p>However there are situations where you need to show some particular kind of data which is not suited to any existing control. In these cases rather than hacking an existing control for something it has not been conceived for, it's better to write a new widget.</p>
<h1><a class="anchor" id="overview_customwidgets_how"></a>
Writing a Custom Widget</h1>
<p>There are at least two very different ways to implement a new widget.</p>
<p>The first is to build it upon wxWidgets existing classes, thus deriving it from <a class="el" href="classwx_control.html" title="This is the base class for a control or "widget".">wxControl</a> or <a class="el" href="classwx_window.html" title="wxWindow is the base class for all windows and represents any visible object on screen.">wxWindow</a>. In this way you'll get a <b>generic</b> widget. This method has the advantage that writing a single implementation works on all ports; the disadvantage is that it the widget will look the same on all platforms, and thus it may not integrate well with the native look and feel.</p>
<p>The second method is to build it directly upon the native toolkits of the platforms you want to support (e.g. GTK+, Carbon and GDI). In this way you'll get a <b>native</b> widget. This method in fact has the advantage of a native look and feel but requires different implementations and thus more work.</p>
<p>In both cases you'll want to better explore some hot topics like:</p>
<ul>
<li><a class="el" href="overview_windowsizing.html">Window Sizing Overview</a></li>
<li><a class="el" href="overview_events.html#overview_events_custom">Custom Event Summary</a> to implement your custom widget's events.</li>
</ul>
<p>You will probably need also to gain some familiarity with the wxWidgets sources, since you'll need to interface with some undocumented wxWidgets internal mechanisms.</p>
<h2><a class="anchor" id="overview_customwidgets_how_generic"></a>
Writing a Generic Widget</h2>
<p>Generic widgets are typically derived from <a class="el" href="classwx_control.html" title="This is the base class for a control or "widget".">wxControl</a> or <a class="el" href="classwx_window.html" title="wxWindow is the base class for all windows and represents any visible object on screen.">wxWindow</a>. They are easy to write. The typical "template" is as follows:</p>
<div class="fragment"><div class="line"><span class="keyword">enum</span> MySpecialWidgetStyles</div>
<div class="line">{</div>
<div class="line"> SWS_LOOK_CRAZY = 1,</div>
<div class="line"> SWS_LOOK_SERIOUS = 2,</div>
<div class="line"> SWS_SHOW_BUTTON = 4,</div>
<div class="line"></div>
<div class="line"> SWS_DEFAULT_STYLE = (SWS_SHOW_BUTTON|SWS_LOOK_SERIOUS)</div>
<div class="line">};</div>
<div class="line"></div>
<div class="line"><span class="keyword">class </span>MySpecialWidget : <span class="keyword">public</span> <a class="code" href="classwx_control.html" title="This is the base class for a control or "widget".">wxControl</a></div>
<div class="line">{</div>
<div class="line"><span class="keyword">public</span>:</div>
<div class="line"> MySpecialWidget() { Init(); }</div>
<div class="line"></div>
<div class="line"> MySpecialWidget(<a class="code" href="classwx_window.html" title="wxWindow is the base class for all windows and represents any visible object on screen.">wxWindow</a> *parent,</div>
<div class="line"> <a class="code" href="windowid_8h.html#ae8091432cc2cb2485d45f2302fb51133" title="The type of unique identifiers (ID) used for wxWindow-derived classes.">wxWindowID</a> winid,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a>& label,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_point.html" title="A wxPoint is a useful data structure for graphics operations.">wxPoint</a>& pos = <a class="code" href="gdicmn_8h.html#af5a90c753eaf3d3e3e5068a19ec3c1d0" title="Global instance of a wxPoint initialized with values (-1,-1).">wxDefaultPosition</a>,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_size.html" title="A wxSize is a useful data structure for graphics operations.">wxSize</a>& size = <a class="code" href="gdicmn_8h.html#a33a012cdb075e9f78c93f63bec2dc27b" title="Global instance of a wxSize object initialized to (-1,-1).">wxDefaultSize</a>,</div>
<div class="line"> <span class="keywordtype">long</span> style = SWS_DEFAULT_STYLE,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_validator.html" title="wxValidator is the base class for a family of validator classes that mediate between a class of contr...">wxValidator</a>& val = <a class="code" href="validate_8h.html#af1e90d8aa1824fd2ce4024ef7e40703c" title="An empty, "null" wxValidator instance.">wxDefaultValidator</a>,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a>& name = <span class="stringliteral">"MySpecialWidget"</span>)</div>
<div class="line"> {</div>
<div class="line"> Init();</div>
<div class="line"></div>
<div class="line"> <a class="code" href="classwx_control.html#abe23789c94c86907463a0e8434be822a">Create</a>(parent, winid, label, pos, size, style, val, name);</div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="keywordtype">bool</span> <a class="code" href="classwx_control.html#abe23789c94c86907463a0e8434be822a">Create</a>(<a class="code" href="classwx_window.html" title="wxWindow is the base class for all windows and represents any visible object on screen.">wxWindow</a> *parent,</div>
<div class="line"> <a class="code" href="windowid_8h.html#ae8091432cc2cb2485d45f2302fb51133" title="The type of unique identifiers (ID) used for wxWindow-derived classes.">wxWindowID</a> winid,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a>& label,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_point.html" title="A wxPoint is a useful data structure for graphics operations.">wxPoint</a>& pos = <a class="code" href="gdicmn_8h.html#af5a90c753eaf3d3e3e5068a19ec3c1d0" title="Global instance of a wxPoint initialized with values (-1,-1).">wxDefaultPosition</a>,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_size.html" title="A wxSize is a useful data structure for graphics operations.">wxSize</a>& size = <a class="code" href="gdicmn_8h.html#a33a012cdb075e9f78c93f63bec2dc27b" title="Global instance of a wxSize object initialized to (-1,-1).">wxDefaultSize</a>,</div>
<div class="line"> <span class="keywordtype">long</span> style = SWS_DEFAULT_STYLE,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_validator.html" title="wxValidator is the base class for a family of validator classes that mediate between a class of contr...">wxValidator</a>& val = <a class="code" href="validate_8h.html#af1e90d8aa1824fd2ce4024ef7e40703c" title="An empty, "null" wxValidator instance.">wxDefaultValidator</a>,</div>
<div class="line"> <span class="keyword">const</span> <a class="code" href="classwx_string.html" title="String class for passing textual data to or receiving it from wxWidgets.">wxString</a>& name = wxCollapsiblePaneNameStr);</div>
<div class="line"></div>
<div class="line"> <span class="comment">// accessors...</span></div>
<div class="line"></div>
<div class="line"><span class="keyword">protected</span>:</div>
<div class="line"></div>
<div class="line"> <span class="keywordtype">void</span> Init() {</div>
<div class="line"> <span class="comment">// init widget's internals...</span></div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="keyword">virtual</span> <a class="code" href="classwx_size.html" title="A wxSize is a useful data structure for graphics operations.">wxSize</a> <a class="code" href="classwx_window.html#a01e7604ab0f0b2b1a8e322a630a4669e" title="Implementation of GetBestSize() that can be overridden.">DoGetBestSize</a>()<span class="keyword"> const </span>{</div>
<div class="line"> <span class="comment">// we need to calculate and return the best size of the widget...</span></div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"> <span class="keywordtype">void</span> OnPaint(<a class="code" href="classwx_paint_event.html" title="A paint event is sent when a window's contents needs to be repainted.">wxPaintEvent</a>&) {</div>
<div class="line"> <span class="comment">// draw the widget on a wxDC...</span></div>
<div class="line"> }</div>
<div class="line"></div>
<div class="line"><span class="keyword">private</span>:</div>
<div class="line"> DECLARE_DYNAMIC_CLASS(MySpecialWidget)</div>
<div class="line"> DECLARE_EVENT_TABLE()</div>
<div class="line">};</div>
</div><!-- fragment --><h2><a class="anchor" id="overview_customwidgets_how_native"></a>
Writing a Native Widget</h2>
<p>Writing a native widget is typically more difficult as it requires you to know the APIs of the platforms you want to support. See <a class="el" href="page_port.html#page_port_nativedocs">Native Toolkit Documentation</a> for links to the documentation manuals of the various toolkits.</p>
<p>The organization used by wxWidgets consists in:</p>
<ul>
<li>declaring the common interface of the control in a generic header, using the 'Base' postfix; e.g. MySpecialWidgetBase. See for example the wxWidgets' <code>"wx/button.h"</code> file.</li>
</ul>
<ul>
<li>declaring the real widget class inheriting from the Base version in platform-specific headers; see for example the wxWidgets' <code>"wx/gtk/button.h"</code> file.</li>
</ul>
<ul>
<li>separating the different implementations in different source files, putting all common stuff in a separate source. See for example the wxWidgets' <code>"src/common/btncmn.cpp"</code>, <code>"src/gtk/button.cpp"</code> and <code>"src/msw/button.cpp"</code> files. </li>
</ul>
</div></div><!-- contents -->
<address class="footer">
<small>
Generated on Thu Nov 27 2014 13:46:42 for wxWidgets by <a href="http://www.doxygen.org/index.html" target="_new">Doxygen</a> 1.8.2
</small>
</address>
<script src="wxwidgets.js" type="text/javascript"></script>
</div><!-- #page_container -->
</body>
</html>
|