index.html

来自「《Big C++ 》Third Edition电子书和代码全集-Part1」· HTML 代码 · 共 620 行 · 第 1/2 页

HTML
620
字号
    </blockquote>
    </font> </li>
</ul>
<hr><h2><font color='#009999'>27.6 Layout Management (cont.)</font></h2>
<ul>
  <li><font size="+1">The problem is making user the buttons are placed correctly 
    inside the frame.</font></li>
  <li><font size="+1">Some user interface toolkits supply a graphical layout tool 
    to define the placement of buttons, text controls, and other user interface 
    elements in a frame.</font></li>
  <li><font size="+1">Such tools make designing a user interface simple, but the 
    design tends to be fragile.</font></li>
  <li><font size="+1">If a component size changes (perhaps the button text is 
    translated to another language: &quot;Goodbye&quot; to &quot;Auf Wiedersehen&quot;) 
    the entire layout needs to be rebuilt. </font></li>
  <li><font size="+1">More robust layouts require a description of the logic behind 
    the placement of the interface elements.</font></li>
</ul>
<hr><h2><font color='#009999'>27.6 Layout Management (cont.)</font></h2>
<ul>
  <li><font size="+1">In wxWindows, use objects of the <tt>wxSizer</tt> class 
    or one of its derived classes (such as <tt>wxBoxSizer</tt>) to specify the 
    layout of user interface elements. </font></li>
  <li><font size="+1">These buttons would be lined up horizontally: 
    <blockquote> 
      <pre>wxBoxSizer* button_sizer = new wxBoxSizer(wxHORIZONTAL);
button_sizer-&gt;Add(hello_button);
button_sizer-&gt;Add(goodbye_button);</pre>
    </blockquote>
    </font></li>
  <li><font size="+1">A second sizer places the text control on top of the button 
    row. 
    <blockquote>
      <pre>wxBoxSizer* frame_sizer = new wxBoxSizer(wxVERTICAL);
frame_sizer-&gt;Add(text, 1, wxGROW);
frame_sizer-&gt;Add(button_sizer, 0, wxALIGN_CENTER);</pre>
    </blockquote></font></li>
	<blockquote><img src="images/button_frame.png"></blockquote>
</ul>
<hr><h2><font color='#009999'>27.6 Layout Management (cont.)</font></h2>
<ul>
  <li><font size="+1">You must include commands to turn on auto layout and tell 
    the frame which sizer to use.
	<blockquote>
      <pre>SetAutoLayout(true);
SetSizer(frame_sizer);</pre>
    </blockquote></font></li>
  <li><font size="+1">The additional parameters in the <tt>Add</tt> function explain 
    how the layout is maintained when the user resizes. 
    <blockquote>
      <pre>wxBoxSizer* frame_sizer = new wxBoxSizer(wxVERTICAL);
frame_sizer-&gt;Add(text, 1, wxGROW);
frame_sizer-&gt;Add(button_sizer, 0, wxALIGN_CENTER);</pre>
    </blockquote></font></li>
  <li><font size="+1">The second parameter indicates the ratio of size used in 
    vertical components.</font> 
    <ul>
      <li><font size="+1">0 means don't resize.</font></li>
      <li><font size="+1">If you had a component with parameter 1, and another 
        with parameter 2, the second would always use twice as much (vertical) 
        space as the first.</font></li>
    </ul>
  </li>
  <li><font size="+1">The third parameter describes horizontal growth behavior.</font>
    <ul>
      <li><font size="+1">The text control grows with the window.</font></li>
      <li><font size="+1">The button bar doesn't grow, but should be centered.</font></li>
    </ul>
  </li>
</ul>
<hr><h2><font color='#009999'>27.6 Layout Management (<tt>button.cpp)</tt></font></h2>
<iframe src="code/button.cpp.html" width="80%" height="80%">Your browser does not 
support the &lt;iframe&gt; tag.</iframe> 
<hr><h2><font color='#009999'>27.7 Painting</font></h2>
<ul>
  <li><font size="+1">Drawing images in a windowing environment is not quite as 
    straightforward as you might think.</font> 
    <ul>
      <li><font size="+1">What happens when a user re-sizes the window? ... minimizes 
        the window? ... restores the window?</font></li>
      <li><font size="+1">What happens when another frame pops up over the image 
        and then vanishes?</font></li>
    </ul>
  </li>
  <li><font size="+1">The program has no idea when these events will happen.</font></li>
  <li><font size="+1">When they do happen, the window manager knows the contents 
    of the window have been corrupted and sends a paint event to the program.</font></li>
  <li><font size="+1">The program needs to draw the image not just once, but <i>every 
    time a paint even occurs</i>.</font></li>
  <li><font size="+1">All drawing instructions must be placed into a function 
    that is is the target of paint events. 
    <blockquote><pre>EVT_PAINT(EllipseWindow::OnPaint)</pre></blockquote></font></li>
</ul>
<hr><h2><font color='#009999'>27.7 Painting (cont.)</font></h2>
<ul>
  <li><font size="+1">The paint function obtains a <i>device context</i>, which 
    is an object that represents the surface of the window.</font></li>
  <li><font size="+1">The device context class has drawing functions such as <tt>DrawLine</tt>, 
    <tt>DrawEllipse</tt>, and <tt>DrawText</tt>.
	<blockquote>
      <pre>void EllipseWindow::OnPaint(wxPaintEvent&amp; event)
{
   wxPaintDC dc(this);
   dc.SetBrush(*wxTRANSPARENT_BRUSH);
   wxSize size = GetSize();
   int x = 0;
   int y = 0;
   int width = size.GetWidth();
   int height = size.GetHeight();
   dc.DrawEllipse(x, y, width, height);
}</pre>
    </blockquote></font></li>
</ul>
<hr><h2><font color='#009999'>27.7 Painting (cont.)</font></h2>
<ul>
  <li><font size="+1">The <tt>DrawEllipse</tt> function requires you specify the 
    top left corner of the bounding box. </font></li>
  <li><font size="+1">The device context coordinates are in pixels, with the point 
    (0, 0) in the top left corner.</font></li>
	<img src="images/EllipseCoordinates.png">
</ul>
<hr><h2><font color='#009999'>27.7 Painting (cont.)</font></h2>
<ul>
  <li><font size="+1">The <tt>OnPaint</tt> function does not draw on the application 
    frame, but on a separate window of type <tt>EllipseWindow</tt>, derived from 
    <tt>wxWindow</tt>.</font></li>
  <li><font size="+1">We believe that an &quot;ellipse window&quot; is a user 
    interface element, just like a text control or button, and deserves it's own 
    class.</font></li>
  <li><font size="+1">We will see another example later.</font></li>
</ul>
<blockquote><img src="images/ellipse_inheritance.png"></blockquote>
<hr><h2><font color='#009999'>27.7 Painting (<tt>paint.cpp</tt>)</font></h2>
<iframe src="code/paint.cpp.html" width="80%" height="80%">Your browser does not 
support the &lt;iframe&gt; tag.</iframe> 

<hr><h2><font color='#009999'>27.8 Mouse Events</font></h2>
<ul>
  <li><font size="+1">To handle mouse input in a graphical window, you install 
    a function that is notified when mouse events occur.</font></li>
  <li><font size="+1">There are several kinds of mouse events:</font> 
    <ul>
      <li><font size="+1">motion</font></li>
      <li><font size="+1">dragging (moving while depressing a mouse button)</font></li>
      <li><font size="+1">mouse button going down</font></li>
      <li><font size="+1">mouse button going up</font></li>
      <li><font size="+1">clicking (mouse button going up and down within a short 
        period)</font></li>
      <li><font size="+1">double clicking</font></li>
    </ul>
  </li>
  <li><font size="+1">You install the mouse handler with the <tt>EVT_MOUSE_EVENTS</tt> 
    macros.
	<blockquote>
      <pre>BEGIN_EVENT_TABLE(TriangleWindow, wxWindow)
   EVT_MOUSE_EVENTS(TriangleWindow::OnMouseEvent)
   . . .</pre>
    </blockquote> </font></li>
</ul>
<hr><h2><font color='#009999'>27.8 Mouse Events (cont.)</font></h2>
<ul>
  <li><font size="+1">In the notification functions, you can query the <tt>wxMouseEvent</tt> 
    about the event type (e.g. <tt>ButtonDown()</tt> returns <tt>true</tt> or 
    <tt>false</tt>, <tt>GetX()</tt> returns the <i>x</i>-position of the mouse, 
    etc.). 
    <blockquote> 
      <pre>void TriangleWindow::OnMouseEvent(wxMouseEvent& event)
{
   if (event.ButtonDown() &amp;&amp; corners &lt; 3)
   {
      x[corners] = event.GetX();
      y[corners] = event.GetY();
      corners++;
      Refresh();
   }   
}</pre>
    </blockquote>
    </font></li>
  <li><font size="+1">In our program, we allow the user to specify a triangle 
    by clicking on the three corners.</font></li>
  <li><font size="+1">With each press, we record the mouse position.</font></li>
  <li><font size="+1">All drawing should happen in the paint handler.</font></li>
  <li><font size="+1">The <tt>Refresh</tt> function generates a paint event, which 
    eventually causes the paint function to be called.</font></li>
  <li><font size="+1">Calling the paint function directly should never be done 
    - always refresh instead.</font></li>
</ul>
<hr><h2><font color='#009999'>27.8 Mouse Events (cont.)</font></h2>
<ul>
  <li><font size="+1">Depending on the number of corners that have already been 
    specified, the paint handler draws </font> 
    <ul>
      <li><font size="+1">a small circle for the first mouse click</font></li>
      <li><font size="+1">a line after the first two mouse clicks</font></li>
      <li><font size="+1">a triangle after three mouse clicks</font></li>
    </ul>
  </li>
  <font size="+1"> 
  <blockquote> 
    <pre>void TriangleWindow::OnPaint(wxPaintEvent &amp; event)
{
   const int RADIUS = 2;
   wxPaintDC(this);
   if (corners == 1)
      dc.DrawEllpse(x[0] - RADIUS, y[0] - RADIUS,
         2 * RADIUS, 2 * RADIUS);
   if (corners &gt;= 2)
      dc.DrawLine(x[0], y[0], x[1], y[1]);
   if (corners &gt;= 3)
   {
      dc.DrawLine(x[1], y[1], x[2], y[2]);
      dc.DrawLine(x[2], y[2], x[0], y[0]);
   }
}
</pre>
  </blockquote>
  </font>
</ul>
<hr><h2><font color='#009999'>27.8 Mouse Events (<tt>mouse.cpp</tt>)</font></h2>
<iframe src="code/mouse.cpp.html" width="80%" height="80%">Your browser does not 
support the &lt;iframe&gt; tag.</iframe> 
<hr><h2><font color='#009999'>27.9 Dialogs</font></h2>
<ul>
  <li><font size="+1">A <i>mode</i> restricts what a user can do at any given 
    time, or interprets a user in a way that depends on the mode.</font></li>
  <li><font size="+1">Example: In over type mode in a word processor, the typed 
    characters replace existing characters instead of inserting themselves before 
    the cursor.</font></li>
  <li><font size="+1">Experience has shown that modes burden program users - the 
    user must expend some mental effort and keep track of the current mode.</font></li>
  <li><font size="+1">When designing a user interface, it is generally preferred 
    to minimize modes.</font></li>
</ul>
<hr><h2><font color='#009999'>27.9 Dialogs (cont.)</font></h2>
<ul>
  <li><font size="+1">Another example of a special program mode is a dialog box 
    that requires immediate input from the user.</font></li>
  <li><font size="+1">Because the user can do nothing else except fill or cancel 
    the dialog, it can be a burden.</font></li>
  <li><font size="+1">Nevertheless, modal dialog boxes are necessary whenever 
    a program simply cannot proceed with user intervention.</font></li>
  <li><font size="+1">The wxWindows toolkit makes is easy to program several kinds 
    of dialogs. 
    <blockquote>
      <pre>wxMessageDialog* dialog = new wxMessageDialog(parent, message);
dialog-&gt;ShowModal();
dialog-&gt;Destroy();</pre>
    </blockquote></font></li>
	
  <li><font size="+1">The dialog pops up and is displayed until the user clicks 
    the &quot;OK&quot; button.
	<blockquote><img src="images/Dialog1.png"></blockquote></font></li>
</ul>
<hr><h2><font color='#009999'>27.9 Dialogs (cont.)</font></h2>
<ul>
  <li><font size="+1">The parent parameter is a pointer to the parent window, 
    over which the dialog box is placed.</font></li>
  <li><font size="+1">The message parameter is of type <tt>wxString</tt>, a class 
    that is similar to the standard <tt>string</tt> type.</font></li>
  <li><font size="+1">We recommend you use the standard string class for all string 
    computations, then use the <tt>c_str</tt> function to convert to a C string, 
    which is then automatically converted to a <tt>wxString</tt>.
	<blockquote>
      <pre>string message = "Hello, " + name;
dialog = new wxMessageDialog(this, message.c_str());</pre>
    </blockquote></font></li>
  <li><font size="+1">When you are done with a dialog, you should destroy it.</font></li>
</ul>
<hr><h2><font color='#009999'>27.9 Dialogs (cont.)</font></h2>
<ul>
  <li><font size="+1">Another convenient dialog is the text entry dialog that 
    asks the user to supply a single line of text. 
    <blockquote>
      <pre>wxTextEntryDialog* dialog = new wxTextEntryDialog(this,
   &quot;What is your name?&quot;;
dialog-&gt;ShowModal();
string name = dialog-&gt;GetValue().c_str();
dialog-&gt;Destroy();</pre>
    </blockquote>
	<P><blockquote><img src="images/Dialog2.png"></blockquote></font></li>
  <li><font size="+1">The <tt>GetValue</tt> function returns a <tt>wxString</tt>. 
    That class also has a <tt>c_str</tt> function to convert to a C string.</font></li>
</ul>
<hr><h2><font color='#009999'>27.10 Case Study: A GUI for the Clock Game</font></h2>
<ul>
  <li><font size="+1">The final example is a wxWindows version of the clock game 
    of Chapter 13.</font></li>
  <li><font size="+1">Because of the event-driven nature of GUI programming, several 
    modifications had to be made to the program logic.</font></li>
  <li><font size="+1">In this program, each guess is communicated to the program 
    in the handler of the &quot;Guess&quot; button.</font></li>
  <li><font size="+1">A data field <tt>tries</tt> has been added to keep track 
    of whether the guess is a first or second guess.</font></li>
  <li><font size="+1">The user selects menu options that lead to dialog boxes 
    to enter the user name and choose level.</font></li>
  <li><font size="+1">Now the user can change level at any time during the game.</font></li>
  <li><font size="+1">To simplify compilation, the nonstandard Point and Time 
    classes have been eliminated from the program.</font></li>
</ul>
<hr><h2><font color='#009999'>27.10 Case Study: A GUI for the Clock Game (cont.)</font></h2>
<ul>
  <li><font size="+1">Classes of the Clock Game </font></li>
</ul>
<blockquote><img src="images/game_classes.png"></blockquote>
<hr><h2><font color='#009999'>27.10 Case Study: (<tt>game.cpp</tt>)</font></h2>
<iframe src="code/game.cpp.html" width="80%" height="80%">Your browser does not 
support the &lt;iframe&gt; tag.</iframe> 
</body>
</html>

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?