setnode.comhttp://www.setnode.com/Sun, 12 Sep 2010 18:21:00 -0700Mouse wheel events, event filters, and QScrollAreahttp://www.setnode.com/blog/mouse-wheel-events-event-filters-and-qscrollarea/<p>Let’s say you have a <code>QScrollArea</code> which contains some custom widget. Now, although this widget itself has no use for mouse wheel events, when it’s in your <code>QScrollArea</code> you’d really like for it to grow and shrink in response to the wheel. Or maybe you’d just like to map vertical wheel events to horizontal scrolling, since you know the widget will never need vertical scrollbars.</p> <p>The biggest problem here is that <code>QScrollArea</code> accepts wheel events (this isn’t strictly true, as you’ll soon see). Events propagate from the child up to the parent until someone accepts the event, and this means that <code>QScrollArea</code> will prevent wheel events from getting to your own code (again, this isn’t strictly true).</p> <p>Reading the documentation it’s clear that you’d either want to subclass <code>QScrollArea</code> or use <a href="http://qt-project.org/doc/qt-4.8/eventsandfilters.html">event filters</a>. Since you don’t need to subclass <code>QScrollArea</code> for any other reason, using event filters sounds like a reasonable approach. You’ll set up an event filter that forces wheel events to be ignored and install it on the <code>QScrollArea</code>. That way, it’ll propagate up to your containing widget.</p> <p>So you’d adjust your containing widget like so:</p> <div class="codehilite"><pre><span class="k">class</span> <span class="nc">MyWidget</span> <span class="o">:</span> <span class="k">public</span> <span class="n">QObject</span> <span class="p">{</span> <span class="nl">public:</span> <span class="c1">// ...</span> <span class="kt">bool</span> <span class="n">eventFilter</span><span class="p">(</span><span class="n">QObject</span><span class="o">*</span> <span class="cm">/*obj*/</span><span class="p">,</span> <span class="n">QEvent</span><span class="o">*</span> <span class="n">evt</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">(</span><span class="n">evt</span><span class="o">-&gt;</span><span class="n">type</span><span class="p">()</span> <span class="o">==</span> <span class="n">QEvent</span><span class="o">::</span><span class="n">Wheel</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// ignore the event (this effectively </span> <span class="c1">// makes it &quot;skip&quot; one object)</span> <span class="n">evt</span><span class="o">-&gt;</span><span class="n">ignore</span><span class="p">();</span> <span class="p">}</span> <span class="c1">// return false to continue event propagation</span> <span class="c1">// for all events</span> <span class="k">return</span> <span class="nb">false</span><span class="p">;</span> <span class="p">}</span> <span class="nl">protected:</span> <span class="kt">void</span> <span class="n">wheelEvent</span><span class="p">(</span><span class="n">QWheelEvent</span><span class="o">*</span> <span class="n">event</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// your own custom stuff</span> <span class="c1">// ...</span> <span class="c1">// if you handle the event and don&#39;t want it to</span> <span class="c1">// propagate any further, accept it:</span> <span class="n">event</span><span class="o">-&gt;</span><span class="n">accept</span><span class="p">();</span> <span class="p">}</span> <span class="p">};</span> </pre></div> <p>And then you’d use it like so:</p> <div class="codehilite"><pre><span class="n">QScrollArea</span><span class="o">*</span> <span class="n">scrollArea</span> <span class="o">=</span> <span class="k">new</span> <span class="n">QScrollArea</span><span class="p">(</span><span class="n">parent</span><span class="p">);</span> <span class="n">scrollArea</span><span class="o">-&gt;</span><span class="n">setWidget</span><span class="p">(</span><span class="n">someWidget</span><span class="p">);</span> <span class="c1">// assuming that &#39;this&#39; is MyWidget</span> <span class="n">scrollArea</span><span class="o">-&gt;</span><span class="n">installEventFilter</span><span class="p">(</span><span class="k">this</span><span class="p">);</span> </pre></div> <p>This doesn’t work. Instead, what you need to do is <code>installEventFilter()</code> on <code>QScrollArea</code>’s viewport:</p> <div class="codehilite"><pre><span class="n">scrollArea</span><span class="o">-&gt;</span><span class="n">viewport</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">installEventFilter</span><span class="p">(</span><span class="k">this</span><span class="p">);</span> </pre></div> <p>In fact, <code>QScrollArea</code> is not the one that is accepting wheel events. It’s the viewport that is doing all of that. By installing an event filter on the viewport, the wheel events will continue to propagate up the tree.</p>richardwbSun, 12 Sep 2010 18:21:00 -0700tag:www.setnode.com,2010-09-12:blog/mouse-wheel-events-event-filters-and-qscrollarea/Logitech G500 Gaming Mouse - Impressionshttp://www.setnode.com/blog/logitech-g500-gaming-mouse-impressions/<p>Got a Logitech G500 mouse recently and I thought I'd just quickly note my impressions of the mouse and its associated software. First, some background on my previous (non-throwaway) mice to give an idea of what I've used before:</p> <ol> <li>Logitech MX1000: a wireless mouse that had little to no lag in my particular environment, in contrast to:</li> <li>Logitech MX Revolution: the wireless mouse Logitech sent me as a replacement for the MX1000 above; had <em>two</em> wheels, one of which had a free spinning mode; unfortunately had terrible interference problems for me and was essentially unusable</li> <li>Razer DeathAdder: a wired mouse with a great shape, just wish it had more buttons</li> <li>Purchased the Logitech G500 because my Razer mouse was double-clicking sporadically and developed a flaky scroll wheel (scrolling down would sometimes scroll up)</li> </ol> <p>I don't have much to say about the mouse itself that hasn't already been said on the internet -- it feels good in the hand and has plenty of buttons. I'm going to focus on the part I found more interesting, the on-board memory.</p> <p>Now, one problem with most of these mice is that while the left, right, middle, and two side buttons (Mouse4 and Mouse5) are supported natively by Windows, any additional buttons on them require the appropriate drivers to be installed. This isn't necessarily bad in itself, but I always liked the idea of a mouse that just works, fully functional, without requiring any drivers. The DeathAdder added on-board memory to avoid this issue, so you could do things like save a macro to Mouse5 and bring it to another computer and have that macro available. Unfortunately, it only had five buttons, all of which already have standard functions, so I never found a good use for this feature. However, the on-board memory did let you save your mouse DPI settings, which was somewhat useful.</p> <p>The G500 also has on-board memory, but this time it also has the spare buttons to make it worthwhile. In addition to the five standard buttons, the G500 has one extra side button, two DPI buttons, a left wheel tilt and a right wheel tilt. All of these are programmable and, as long as you stick to commands that can be sent by a keyboard or a mouse (including standard media keys like volume and playback controls), will work on any computer without drivers. It apparently does this by acting as several human interface devices, including a keyboard and a mouse:</p> <p><a href="/images/logitech_g500_properties.png"><img src="/images/logitech_g500_properties_thumb.jpg" alt="Logitech G500 Properties Dialog Thumbnail" height="200" width="162" /></a></p> <p>It's pretty interesting assigning a keystroke like 'A' to a side button or having your DPI buttons control the system's volume. After setting my bindings up I uninstalled the SetPoint software and still have a fully working mouse. Neat.</p>richardwbSat, 22 May 2010 16:06:00 -0700tag:www.setnode.com,2010-05-22:blog/logitech-g500-gaming-mouse-impressions/Accessing a Git repository with TortoiseHg on Windowshttp://www.setnode.com/blog/accessing-a-git-repository-with-tortoisehg-on-windows/<p>If you're using Hg and you want to get hold of a Git repository there is an extension, hg-git, that lets you do this.</p> <p>On Windows the installation process for this hasn't always been the easiest, as you needed to first install the dulwich Python library (which I always seemed to have trouble doing) and then hg-git. The TortoiseHg guys have made this a lot easier in recent versions of TortoiseHg, as they now include the dulwich libraries.</p> <p>So, step by step:</p> <ol> <li>You'll need <a href="http://tortoisehg.bitbucket.org/‎">TortoiseHg 0.9.3</a> or later. Get the latest version.</li> <li> <p>Bring up a command line and enter this line to clone the latest hg-git to your desired directory (this is "installing" hg-git). I'll use <code>D:\TortoiseHg\hg-git</code> in this example.</p> <div class="codehilite"><pre>&gt; hg clone http://bitbucket.org/durin42/hg-git/ D:\TortoiseHg\hg-git </pre></div> </li> <li> <p>Open up your user-specific <code>Mercurial.ini</code>. The location of this file may change occasionally, read the <a href="http://www.selenic.com/mercurial/hgrc.5.html">Mercurial docs</a> if you have trouble finding it.<br /> On Windows Vista and Windows 7 this file is typically located at:</p> <div class="codehilite"><pre>C:\Users\YourUsername\Mercurial.ini </pre></div> <p>while on Windows XP you'll find it at:</p> <div class="codehilite"><pre>C:\Documents and Settings\YourUsername\Mercurial.ini </pre></div> <p>Alternatively, bring up the Windows "Run" dialog and enter:</p> <div class="codehilite"><pre>%USERPROFILE%\Mercurial.ini </pre></div> <p>which will work on all recent Windows platforms.</p> </li> <li> <p>Navigate down to the <code>[extensions]</code> section and add this line to that section:</p> <div class="codehilite"><pre>hggit = D:\TortoiseHg\hg-git </pre></div> <p>Where <code>D:\TortoiseHg\hg-git</code> is the directory you cloned hg-git to earlier. This line may already exist or may be commented out with a semicolon, in that case just remove the semicolon and update the directory.</p> </li> <li> <p>Now you can clone a Git repository like so:</p> <div class="codehilite"><pre>&gt; hg clone git://github.com/richhickey/clojure.git D:\TargetDirectory </pre></div> </li> <li> <p>The result is you'll have a Mercurial enabled repository at <code>D:\TargetDirectory</code>. You can <code>push</code>, <code>pull</code>, and generally treat it as an Hg repository. Try</p> <div class="codehilite"><pre>&gt; hg help hggit </pre></div> </li> </ol> <p>for additional help and information, or check the <a href="http://mercurial.selenic.com/wiki/HgGit">HgGit page</a> on the Mercurial wiki.</p>richardwbFri, 09 Apr 2010 10:31:00 -0700tag:www.setnode.com,2010-04-09:blog/accessing-a-git-repository-with-tortoisehg-on-windows/Great Boost Documentationhttp://www.setnode.com/blog/great-boost-documentation/<p>I found out from the <a href="http://sandfly.net.nz/blog/2010/04/a-better-boost-book/">Life of Andrew</a> blog that there is a new source for <a href="http://en.highscore.de/cpp/boost/">Boost information</a> available. It's a Creative Commons licensed book covering a wide range of Boost libraries, some of which are usually under-represented documentation-wise (looking at you, ASIO). It was originally written in German by <a href="http://www.highscore.de/">Boris Schäling</a>, but <a href="http://www.andreasmasur.com/">Andreas Masur</a> has translated it into English for those of us who aren't so culturally adapted.</p> <p>A brief skim of the book gives an extremely promising impression and I think it'll be one of the first resources I point newcomers to Boost to in the future.</p>richardwbSat, 03 Apr 2010 18:20:00 -0700tag:www.setnode.com,2010-04-03:blog/great-boost-documentation/Simplify signals and slots connections with unique connections in Qt 4.6http://www.setnode.com/blog/simplify-signals-and-slots-connections-with-unique-connections-in-qt-46/<p>Somehow there's absolutely no mention of this in the <a href="http://doc.trolltech.com/4.6/qt4-6-intro.html">What's New in Qt 4.6</a> summary, but one of my favorite new features in Qt 4.6 is a surprisingly simple one: the <a href="http://doc.trolltech.com/4.6/qt.html#ConnectionType-enum"><code>Qt::UniqueConnection</code></a> connection type.</p> <p>The default connection type for <a href="http://doc.trolltech.com/4.6/qobject.html#connect"><code>connect()</code></a> is <code>Qt::AutoConnection</code>, which sets up either a direct or queued connection depending on whether the signaling object and receiving slot are in the same thread or not. This connection type allows you to connect a particular signal/slot pair multiple times (so emitting a signal once could call a slot twice) which has caught me on a number of occasions.</p> <p>This is really simple to work around: you can add some bookkeeping to keep track of that particular connection or you can use <code>disconnect()</code> where appropriate to maintain 0 or 1 connections. The new <code>Qt::UniqueConnection</code> connection type, on the other hand, lets you be sure that a connection is made only once. It's not something you always need, but when you do, it lets you keep your code a bit cleaner.</p> <p>One caveat is that <code>Qt::UniqueConnection</code> makes a unique <code>Qt::AutoConnection</code>, meaning you don't have the ability to explicitly specify a unique queued connection, for example. In a case like that you will have to keep track of the connections yourself, as before.</p>richardwbTue, 12 Jan 2010 14:43:00 -0800tag:www.setnode.com,2010-01-12:blog/simplify-signals-and-slots-connections-with-unique-connections-in-qt-46/Qt 4.6 has prebuilt binaries for Visual Studiohttp://www.setnode.com/blog/qt-46-has-prebuilt-binaries-for-visual-studio/<p>I've just found out that Qt 4.6 actually includes prebuilt LGPL binaries for Visual Studio 2008, so there's little reason to spend time building Qt unless you need to use some other version of Visual Studio.</p> <p>The <a href="http://qt.nokia.com/downloads/windows-cpp-vs2008">prebuilt binaries are downloadable from here</a>. Alternatively, you can visit the <a href="http://qt.nokia.com/downloads">Qt download page</a>, choose LGPL, and look on the right hand side of the page for the download link.</p> <p>I highly recommend using the prebuilt libraries, as you will save a tremendous amount of time (it takes hours to build Qt). After you finish downloading and installing the libraries, install the <a href="http://qt.nokia.com/downloads/visual-studio-add-in">Visual Studio add-in</a> to make it easier to handle the custom build steps for moc and ui files.</p>richardwbWed, 02 Dec 2009 12:42:00 -0800tag:www.setnode.com,2009-12-02:blog/qt-46-has-prebuilt-binaries-for-visual-studio/Qt 4.6 is out, compiling it with MSVChttp://www.setnode.com/blog/qt-46-is-out-compiling-it-with-msvc/<p>Qt 4.6 has been released (with some <a href="http://doc.trolltech.com/4.6/qt4-6-intro.html">new features</a>) so I've taken the opportunity to make sure my <a href="http://www.setnode.com/blog/compile-qt-45-for-visual-studio-using-your-multi-core-processor/">instructions on how to compile Qt with Visual Studio</a> are still accurate. The additional steps on how to take advantage of your multi-core processor (using <code>jom</code>) still work, as well.</p> <p><em>[Edit: Qt 4.6 actually has <a href="http://www.setnode.com/blog/qt-46-has-prebuilt-binaries-for-visual-studio/">prebuilt binaries/libraries</a> for Visual Studio 2008, which is preferable to spending hours building Qt]</em></p> <p>I've made a note in the article but I'll repeat it here because it's a major time-saver: you should delete, from your Qt folder, these instances of <code>mocinclude.tmp</code>:</p> <div class="codehilite"><pre>\Qt\2009.05\qt\src\3rdparty\webkit\WebCore\tmp\moc\debug_shared\mocinclude.tmp \Qt\2009.05\qt\src\3rdparty\webkit\WebCore\tmp\moc\release_shared\mocinclude.tmp \Qt\2009.05\qt\src\script\tmp\moc\debug_shared\mocinclude.tmp \Qt\2009.05\qt\src\script\tmp\moc\release_shared\mocinclude.tmp </pre></div> <p>Deleting the first two <code>mocinclude.tmp</code> files will prevent a <code>LNK2019</code> error while building Webkit, while deleting the last two (which are new in Qt 4.6, as far as I can tell) will prevent an <code>Error: Unknown interface</code> while trying to build <code>qscriptextensionplugin.h</code>.</p>richardwbWed, 02 Dec 2009 01:39:00 -0800tag:www.setnode.com,2009-12-02:blog/qt-46-is-out-compiling-it-with-msvc/An update on building Boost with MSVC (still with dual/quad/multi-core action)http://www.setnode.com/blog/an-update-on-building-boost-with-msvc-still-with-dual-quad-multi-core-action/<p>I've noticed that in recent versions of Boost (1.39.0 and newer) there is a way to do a <a href="http://www.boost.org/doc/libs/release/more/getting_started/windows.html#or-simplified-build-from-source">"Simplified Build from Source"</a> if you're using Microsoft Visual Studio. Here are the steps as I like to write them:</p> <ol> <li> <p><a href="http://www.boost.org/users/download/">Download</a> the latest version of Boost and extract it to some location (we'll assume <code>D:\Boost\</code>), making sure to maintain the directory structure.</p> </li> <li> <p>In a command prompt, navigate to your Boost library folder (<code>D:\Boost\boost_1_41_0\</code>) and then use this command, which builds your very own copy of Boost Jam (a build system):</p> <div class="codehilite"><pre>&gt; bootstrap </pre></div> </li> <li> <p>Now, in the same command prompt, enter this command, where N is the number of processors/cores you have available for compiling (for example, <code>-j4</code> if you have a quad-core processor):</p> <div class="codehilite"><pre>&gt; bjam.exe -jN </pre></div> </li> <li> <p>Wait.</p> </li> <li> <p>After the build completes you will have a <code>stage</code> subdirectory (<code>D:\Boost\boost_1_41_0\stage\</code>) which will contain a <code>lib</code> subdirectory, containing the compiled libraries.</p> </li> </ol> <p>This simplified process removes the need to get a copy of Boost Jam, which, as trivial as it sounds, really does make a big difference to the friendliness of the entire procedure. It also reduces the number of necessary arguments to zero (or one, if you consider multi-core a necessity), although there are some situations where you may still need the older arguments (in which case I refer you to my previous <a href="http://www.setnode.com/blog/building-boost-now-with-dual-quad-multi-core-action/">entry on the subject</a>).</p>richardwbThu, 19 Nov 2009 02:05:00 -0800tag:www.setnode.com,2009-11-19:blog/an-update-on-building-boost-with-msvc-still-with-dual-quad-multi-core-action/SteveStreeting.com's great series of articles about distributed version control systemshttp://www.setnode.com/blog/stevestreetingcoms-great-series-of-articles-about-distributed-version-control-systems/<p>Steve Streeting (the man behind <a href="http://www.ogre3d.org">OGRE</a>, a 3D graphics engine) has been writing about his experiments with distributed version control systems, particularly <a href="http://en.wikipedia.org/wiki/Mercurial">Mercurial</a> and <a href="http://en.wikipedia.org/wiki/Git_(software)">Git</a>. In particular, his <a href="http://www.stevestreeting.com/2009/11/06/dvcs-score-card/">latest blog post</a> contains a summary of his experiences with the two version control systems and is probably the most in-depth article I've read on the topic. </p> <p>The most interesting portions of the article (and <a href="http://www.stevestreeting.com/tag/dvcs/">his prior posts</a>) are the ones which talk directly about managing the OGRE source within each of the two <abbr title="distributed version control systems">DVCSs</abbr>. OGRE is not a small project and it's very illuminating to read about what parts of a (distributed) version control system are important to a larger project, as this is stuff you may not personally experience until it's too late to change your mind.</p> <p>For my own personal projects I use <a href="http://en.wikipedia.org/wiki/Subversion_(software)">Subversion</a> (<a href="http://tortoisesvn.tigris.org/">TortoiseSVN</a> is a great piece of software) and I'm not in any particular rush to switch over to a <abbr title="distributed version control system">DVCS</abbr> just yet. It's simple, straightforward and fits well with my workflow. For larger projects, especially ones where you're collaborating with people across the Internet, I'd give some serious thought to using a <abbr title="distributed version control system">DVCS</abbr> and reading about other people's experiences is extremely helpful.</p> <p><em>[Edit: I ended up switching about a year after this post to Mercurial for my personal projects.]</em></p>richardwbSat, 07 Nov 2009 00:43:00 -0800tag:www.setnode.com,2009-11-07:blog/stevestreetingcoms-great-series-of-articles-about-distributed-version-control-systems/Windows Sidebar Gadgetshttp://www.setnode.com/blog/windows-sidebar-gadgets/<p>Windows Vista and Windows 7 provides what they call Windows (Sidebar) Gadgets (the Sidebar moniker is removed in Windows 7). These gadgets do the same thing as similar products from Yahoo (formerly known as Konfabulator) and Apple (the Dashboard), providing small amounts of functionality and information within easy reach.</p> <p>The Windows Live Gallery is a perfect example of how not to make a download center. If you take a look at the Sidebar gadgets category, most are of rather poor quality, and a fair number of the good ones use plagiarized skins and/or code.</p> <p>There's no community presence on a site like that, and without a community to help deter poor behavior I think the free-for-all atmosphere makes it hard for the good submissions to float to the top. <a href="http://www.deviantart.com/">deviantART</a> is a great example of a site that does the right stuff; their Sidebar gadgets section is cleaner and easier to use.</p> <p>Anyway, I bring this up because there are some gadgets on <del>The Hobby Lounge</del> which you won't find on deviantART and unfortunately exist in a plagiarized state on the Windows Live Gallery. I was in the process of updating some of my older gadgets from this site and it took me a surprisingly long time to find the website again, even though I knew exactly what I was looking for. My google-fu is usually pretty decent so I figure I'll make a note of it here for myself and maybe help them get noticed a bit more.</p> <p><em>[Edit: The Hobby Lounge is now unfortunately defunct.]</em></p>richardwbMon, 12 Oct 2009 11:57:00 -0700tag:www.setnode.com,2009-10-12:blog/windows-sidebar-gadgets/Optimization switches and Visual Studio 2008http://www.setnode.com/blog/optimization-switches-and-visual-studio-2008/<p>In a <a href="http://www.setnode.com/blog/dont-spend-time-micromanaging-optimization-options-in-visual-c/">previous</a> entry I noted that you generally do not need to micromanage your optimization switches. </p> <p>However, in Visual Studio 2008 (both with and without SP1) there is a bug where the default optimization switch, <code>/O2</code>, is <em>not applied</em> even when shown in the IDE under <code>Configuration Properties-&gt;C/C++-&gt;Optimization</code>.</p> <p>This happens when you select <code>&lt;inherit from parent or project defaults&gt;</code>. Instead, you want to explicitly set <code>Maximize Speed (/O2)</code> (it will show up in bold when explicitly set). You should also verify that the <code>/O2</code> flag is being applied by viewing the command line (<code>Configuration Properties-&gt;C/C++-&gt;Command Line</code>).</p> <p>There is more about this bug on <a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=383764">Microsoft Connect</a>, where it's also noted that this bug will be fixed in Visual Studio 2010.</p>richardwbFri, 02 Oct 2009 15:29:00 -0700tag:www.setnode.com,2009-10-02:blog/optimization-switches-and-visual-studio-2008/Right-click context menus with Qthttp://www.setnode.com/blog/right-click-context-menus-with-qt/<p>Getting right-clicks to popup a context menu is pretty straightforward in Qt. There are just a couple of things to watch out for...</p> <p>First, there are several ways to tell Qt you want a context menu. One approach is to subclass the widget and override the <code>QWidget::contextMenuEvent()</code> event handler. However, I think the easiest approach is to call <code>setContextMenuPolicy(Qt::CustomContextMenu)</code> on the widget you want, and then connect the <code>customContextMenuRequested()</code> signal to the appropriate slot:</p> <div class="codehilite"><pre><span class="c1">// myWidget is any QWidget-derived class</span> <span class="n">myWidget</span><span class="o">-&gt;</span><span class="n">setContextMenuPolicy</span><span class="p">(</span><span class="n">Qt</span><span class="o">::</span><span class="n">CustomContextMenu</span><span class="p">);</span> <span class="n">connect</span><span class="p">(</span><span class="n">myWidget</span><span class="p">,</span> <span class="n">SIGNAL</span><span class="p">(</span><span class="n">customContextMenuRequested</span><span class="p">(</span><span class="k">const</span> <span class="n">QPoint</span><span class="o">&amp;</span><span class="p">)),</span> <span class="k">this</span><span class="p">,</span> <span class="n">SLOT</span><span class="p">(</span><span class="n">ShowContextMenu</span><span class="p">(</span><span class="k">const</span> <span class="n">QPoint</span><span class="o">&amp;</span><span class="p">)));</span> </pre></div> <p>Next, note that the <code>const QPoint&amp; pos</code> parameter in the <code>customContextMenuRequested()</code> signal is <a href="http://doc.trolltech.com/4.5/qwidget.html#customContextMenuRequested">normally in widget coordinates</a>. However, also note that classes which inherit from <code>QAbstractScrollArea</code><sup id="fnref:viewportclasses"><a class="footnote-ref" href="#fn:viewportclasses" rel="footnote">1</a></sup> instead use the coordinates of their <code>viewport()</code>. Either way, you will need to map these coordinates to global coordinates using <code>mapToGlobal()</code>.</p> <p>Finally, simply either <code>popup()</code> or <code>exec()</code> your <code>QMenu</code>. Remember that <code>popup()</code> is non-blocking, so if you wish to use that, make sure your <code>QMenu</code> is created on the heap (or some other way of guaranteeing that the QMenu's lifetime outlasts the scope of the function)!</p> <div class="codehilite"><pre><span class="kt">void</span> <span class="n">MyClass</span><span class="o">::</span><span class="n">ShowContextMenu</span><span class="p">(</span><span class="k">const</span> <span class="n">QPoint</span><span class="o">&amp;</span> <span class="n">pos</span><span class="p">)</span> <span class="c1">// this is a slot</span> <span class="p">{</span> <span class="c1">// for most widgets</span> <span class="n">QPoint</span> <span class="n">globalPos</span> <span class="o">=</span> <span class="n">myWidget</span><span class="o">-&gt;</span><span class="n">mapToGlobal</span><span class="p">(</span><span class="n">pos</span><span class="p">);</span> <span class="c1">// for QAbstractScrollArea and derived classes you would use:</span> <span class="c1">// QPoint globalPos = myWidget-&gt;viewport()-&gt;mapToGlobal(pos);</span> <span class="n">QMenu</span> <span class="n">myMenu</span><span class="p">;</span> <span class="n">myMenu</span><span class="p">.</span><span class="n">addAction</span><span class="p">(</span><span class="s">&quot;Menu Item 1&quot;</span><span class="p">);</span> <span class="c1">// ...</span> <span class="n">QAction</span><span class="o">*</span> <span class="n">selectedItem</span> <span class="o">=</span> <span class="n">myMenu</span><span class="p">.</span><span class="n">exec</span><span class="p">(</span><span class="n">globalPos</span><span class="p">);</span> <span class="k">if</span> <span class="p">(</span><span class="n">selectedItem</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// something was chosen, do stuff</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">// nothing was chosen</span> <span class="p">}</span> <span class="p">}</span> </pre></div> <div class="footnote"> <hr /> <ol> <li id="fn:viewportclasses"> <p>Examples include <code>QTreeWidget</code>, <code>QTreeView</code>, <code>QListWidget</code>, <code>QListView</code>, <code>QTableWidget</code>, <code>QTableView</code>, <code>QTextEdit</code>, <code>QPlainTextEdit</code>, and <code>QMdiArea</code>.&#160;<a class="footnote-backref" href="#fnref:viewportclasses" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p> </li> </ol> </div>richardwbThu, 23 Jul 2009 20:47:00 -0700tag:www.setnode.com,2009-07-23:blog/right-click-context-menus-with-qt/Consolas is a poor choice for web usehttp://www.setnode.com/blog/consolas-is-a-poor-choice-for-web-use/<p><a href="http://en.wikipedia.org/wiki/Consolas">Consolas</a>, with <a href="http://en.wikipedia.org/wiki/ClearType">ClearType</a> enabled, is a gorgeous font, and is my preferred monospaced font. However, take a look at it without ClearType (there's a sample image on the linked Wikipedia article)---those jaggies hurt.</p> <p>That's why you shouldn't define Consolas in your style sheets. You can't know/assume that everyone who views your webpage will have ClearType on (or at least some form of font-smoothing), and those who don't have it enabled will suffer through text that looks as though it were drawn freehand with a mouse.</p> <p>Instead, unless you are going for a specific effect such as trying to mimic old <a href="http://en.wikipedia.org/wiki/Terminal_(font)">terminals</a>, keep your <code>font-family</code> for <code>&lt;pre&gt;</code> and <code>&lt;code&gt;</code> elements short and to the point. I personally use</p> <div class="codehilite"><pre><span class="nt">font-family</span><span class="o">:</span> <span class="s2">&quot;Lucida Console&quot;</span><span class="o">,</span> <span class="s2">&quot;Monaco&quot;</span><span class="o">,</span> <span class="s2">&quot;DejaVu Sans Mono&quot;</span><span class="o">,</span> <span class="nt">monospace</span><span class="o">;</span> </pre></div> <p>which is usually enough to keep Courier (+ New) out of the way. If someone is missing all of these fonts they'll likely have a decent enough substitute.</p>richardwbMon, 06 Jul 2009 15:22:00 -0700tag:www.setnode.com,2009-07-06:blog/consolas-is-a-poor-choice-for-web-use/Compile Qt 4.5 for Visual Studio, using your multi-core processorhttp://www.setnode.com/blog/compile-qt-45-for-visual-studio-using-your-multi-core-processor/<p>If you want to use Qt 4.5 with Visual Studio you'll need to compile it yourself. The instructions are simple, and fairly well documented on <a href="http://www.google.com/search?hl=en&amp;q=compile+qt+visual+studio">various blogs and websites</a>. Essentially: <em>(read steps 7 and on for multi-threading information)</em></p> <p><em>[Edit: These steps still apply for Qt 4.6, but Qt 4.6 actually has <a href="http://www.setnode.com/blog/qt-46-has-prebuilt-binaries-for-visual-studio/">prebuilt binaries/libraries</a> for Visual Studio 2008 which I highly suggest looking at instead]</em></p> <ol> <li> <p><strong>This step is important.</strong> You will potentially save some time by deleting these <code>mocinclude.tmp</code> files:</p> <div class="codehilite"><pre>\Qt\2009.05\qt\src\3rdparty\webkit\WebCore\tmp\moc\debug_shared\mocinclude.tmp \Qt\2009.05\qt\src\3rdparty\webkit\WebCore\tmp\moc\release_shared\mocinclude.tmp \Qt\2009.05\qt\src\script\tmp\moc\debug_shared\mocinclude.tmp \Qt\2009.05\qt\src\script\tmp\moc\release_shared\mocinclude.tmp </pre></div> <p>Deleting the first two <code>mocinclude.tmp</code> files will prevent a LNK2019 error from building Webkit, while deleting the last two (which are present in Qt 4.6) will prevent <code>Error: Unknown interface</code> from occurring while trying to build <code>qscriptextensionplugin.h</code>. If you're missing any of them don't fret, it's actually a good thing.</p> </li> <li> <p>Using a <em>Visual Studio Command Prompt</em>, navigate to your Qt folder (I'll use <code>D:\Coding\Qt\2009.05</code> in this example).</p> </li> <li> <p>Go to the Qt folder inside there (e.g. <code>D:\Coding\Qt\2009.05\qt</code>). It's the one that contains <code>configure.exe</code>.</p> </li> <li> <p>Enter the following command, changing <code>win32-msvc2008</code> to <code>win32-msvc2005</code> if necessary.</p> <div class="codehilite"><pre>&gt; configure -opensource -shared -ltcg -no-qt3support -platform win32-msvc2008 </pre></div> </li> <li> <p>What this does is fairly self explanatory. The <code>-shared</code> switch will make sure that Qt is configured for dynamic linking (even though that's usually the default option there's no guarantee). We need to specify the <code>-ltcg</code> switch to turn on <em>Link Time Code Generation</em>. LTCG is off by default since, in combination with a statically built Qt, it will make linking very slow for any projects that use Qt. However, if we configure Qt for dynamic linking this won't be an issue.</p> </li> <li> <p>You can add or remove switches as desired (try <code>configure help</code>) but I find most of the defaults suitable. Sure, you may not need OpenGL (or SQL or Phonon or...) support right now, but it's a separate module anyway and you're already compiling the rest of Qt.</p> </li> <li> <p><strong>All you need to do now is run <code>nmake</code>...<em>but wait</em>.</strong></p> </li> <li> <p>Do you have a dual-core or quad-core processor or can take advantage of multi-threaded compilation? Get the <code>jom</code> tool instead. There's some info about <code>jom</code> in this <a href="http://labs.trolltech.com/blogs/2009/03/27/speeding-up-visual-c-qt-builds/">Qt Labs Blogs article</a>. You can download the latest version of <code>jom</code> from <a href="ftp://ftp.qt.nokia.com/jom/">ftp://ftp.qt.nokia.com/jom/</a> (<code>jom.zip</code> should be just fine).</p> </li> <li> <p>Use <code>jom</code> by simply unzipping and running it in the same directory as <code>configure</code> (which is still the same as before, <code>D:\Coding\Qt\2009.05\qt</code>).</p> <div class="codehilite"><pre>&gt; jom </pre></div> </li> <li> <p>Happily build Qt much faster. For example, on my machine (a Core 2 Quad) it took an hour for the build to complete.</p> </li> <li> <p>Unless you really enjoy manually handling custom build steps, don't forget to get the <a href="http://www.qtsoftware.com/downloads/visual-studio-add-in">Qt Visual Studio Add-In</a>. After installing it make sure that it's aware of the location of your Qt installation (<code>Qt-&gt;Qt Options</code>) and then use <code>File-&gt;New-&gt;Project...</code> and select one of the Qt templates to get started.</p> </li> </ol>richardwbThu, 25 Jun 2009 20:28:00 -0700tag:www.setnode.com,2009-06-25:blog/compile-qt-45-for-visual-studio-using-your-multi-core-processor/#include Guidelineshttp://www.setnode.com/blog/include-guidelines/<p>This is mostly for my own reference, but here are some of the guidelines I like to follow when it comes to <code>#include</code>s in C++. Given <code>foo.cpp</code> and <code>foo.h</code>:</p> <ul> <li> <p><code>foo.h</code> should include everything it mentions and no more. For example, if you use <code>boost::random</code> in the implementation, don't <code>#include &lt;boost/random.hpp&gt;</code> in <code>foo.h</code>.</p> </li> <li> <p><code>foo.cpp</code> should also include everything it mentions and no more.</p> </li> <li> <p><code>foo.cpp</code>'s first include should be <code>#include "foo.h"</code>.</p> </li> <li> <p>Precompiled headers, if used, should be specified in <code>foo.cpp</code> only and will need to be the first <code>#include</code> (<code>#include "foo.h"</code> will then be the second).</p> </li> <li> <p>Except for the above two exceptions, the order I like to follow for <code>#include</code>s is:</p> <ol> <li>Headers from your own project (generally of the form <code>#include "baz.h"</code>)</li> <li>Headers from non-standard libraries (such as Qt)</li> <li>Standard libraries (I include Boost in here because I use it so pervasively)</li> <li>Platform headers (like <code>#include &lt;windows.h&gt;</code>)</li> </ol> </li> <li> <p>Within each of the above groups try to alphabetically order the <code>#include</code>s if at all possible.</p> </li> <li> <p>Forward declare whenever you can get away with it.</p> </li> </ul>richardwbMon, 22 Jun 2009 19:20:00 -0700tag:www.setnode.com,2009-06-22:blog/include-guidelines/The difference between Qt::Key_Enter and Qt::Key_Returnhttp://www.setnode.com/blog/the-difference-between-qt-key-enter-and-qt-key-r/<p>It's specified in the <a href="http://doc.trolltech.com/4.5/qt.html#Key-enum">documentation</a>, though in a slightly subtle manner. Essentially, <code>Qt::Key_Enter</code> is the keypad Enter, while <code>Qt::Key_Return</code> is the "regular" Enter, the one which you normally use while typing.</p>richardwbWed, 10 Jun 2009 10:48:00 -0700tag:www.setnode.com,2009-06-10:blog/the-difference-between-qt-key-enter-and-qt-key-r/Visual Studio 2010 sounds pretty neat so farhttp://www.setnode.com/blog/visual-studio-2010-sounds-pretty-neat-so-far/<p>I'm a very big fan of the Visual Studio IDE (I think it's the best around, for any platform). However, Microsoft has historically put less of a emphasis on the C++ portion and the past couple of versions have had only minor bullet points on the C++ side.</p> <p>I think they've wizened up a bit and the next Visual C++, 2010, has some notable improvements in store (C++0x support, for one). They've also put a lot of work into completely reworking their C++ IntelliSense engine. There's not much for me to say, really, as they have a great <a href="http://blogs.msdn.com/vcblog/default.aspx">blog</a>. I'll just highlight some of the articles I found the most interesting, which coincidentally all focus on IntelliSense:</p> <ul> <li><a href="http://blogs.msdn.com/vcblog/archive/2009/01/27/dev10-is-just-the-beginning.aspx">A bit of history about the current IntelliSense engine, FEACP</a></li> <li><a href="http://blogs.msdn.com/vcblog/archive/2009/03/10/testing-vc-compiler-and-intellisense.aspx">Just how do they test it anyway?</a></li> <li><a href="http://blogs.msdn.com/vcblog/archive/2009/05/27/rebuilding-intellisense.aspx">Details about the upcoming engine</a></li> <li><a href="http://blogs.msdn.com/vcblog/archive/2009/06/01/c-gets-squiggles.aspx">Squiggles.</a></li> </ul>richardwbTue, 09 Jun 2009 10:04:00 -0700tag:www.setnode.com,2009-06-09:blog/visual-studio-2010-sounds-pretty-neat-so-far/Qt: staticMetaObject is not a member of...http://www.setnode.com/blog/qt-staticmetaobject-is-not-a-member-of/<p>Just got this error message while compiling a tiny class that derives from <code>QTreeWidgetItem</code>:</p> <div class="codehilite"><pre>error C2039: &#39;staticMetaObject&#39; : is not a member of &#39;QTreeWidgetItem&#39; </pre></div> <p>What this is saying is that <code>QTreeWidgetItem</code> does not inherit from <code>QObject</code>, meaning that your own, singly-inherited class also does not inherit from <code>QObject</code>. Inheriting from <code>QObject</code> is <a href="http://doc.trolltech.com/qobject.html#Q_OBJECT">one of the prerequisites</a> to using the <code>Q_OBJECT</code> macro, which, if you're anything like me, you automatically insert into any Qt GUI related class.</p> <p>If you're not using any of the meta object stuff in your subclass, such as signals/slots or properties, just take out the <code>Q_OBJECT</code> macro. If you need to use signals and slots, you'll need to make your subclass multiply-inherit from <code>QObject</code> as well. If you take this route, remember that "<a href="http://doc.trolltech.com/4.5/moc.html">Multiple Inheritance Requires QObject to Be First</a>", otherwise you'll get either the same error as above, or something along the lines of "<code>YourClass</code> inherits from two QObject subclasses" from the moc.</p>richardwbFri, 29 May 2009 21:11:00 -0700tag:www.setnode.com,2009-05-29:blog/qt-staticmetaobject-is-not-a-member-of/Captchas shouldn't be the default defense against botshttp://www.setnode.com/blog/captchas-shouldnt-be-the-default-defense-against-b/<p><a href="http://en.wikipedia.org/wiki/Captcha">Captchas</a> are useful to prevent bots or similarly automated activities from occurring. However, they're not perfect and many of them can be broken with a targeted attack. In a sort of arms race fashion, captchas get more and more intricate, but some take this a bit too far and aren't really even human solvable.</p> <p>In any case, large sites have to have some way to separate bots from humans, and captchas may be the only solution. It's still an arms race, but at least the large sites have the resources to throw at it.</p> <p>What about the small sites? Your blog about your cat? Your forum for fellow gum-chewers? Do you really need (or want) a captcha for these types of sites? Unfortunately, what happens is a crawler stumbles upon your site, notices it uses some popular blog or forum application it knows about, and attempts to register so it can subsequently flood your site with spam. If you use a popular application, such as <a href="http://www.phpbb.com/">phpBB3</a> (for the sake of argument), once the generic, built-in captcha gets broken, all non-customized phpBB3 sites are vulnerable. So a spammer just needs to try to break this one particular captcha and suddenly they've unlocked the ability to spam millions of forums. It provides the volume that spammers need to make spam work.</p> <p>What I suggest instead is that the default mode of operation for a forum (or any application, really) should be to ask a simple question upon registration, with both the answer and question provided by the person who is running the site:</p> <blockquote> <p>Q: What is my cat's name?<br /> A: Fluffy </p> <p>Q: Which of the following is a brand of gum? Oreos, Jellybeans, Trident, Snickers<br /> A: Trident </p> </blockquote> <p>Incidentally, yes/no type questions should be disallowed, as the answers ('yes' and 'no') would be common enough to automate.</p> <p>Now, spamming your forum requires actual human intervention. Obviously this sort of approach will fail if you have a large or popular site, but if you own such a site you already know you have to take more steps to protect your site.</p> <p>One potential problem is I could see lists of questions/answers being hand-generated and passed around, but this could be mitigated by expiring questions/answers after some time. If you're feeling particularly clever you could even flag the old answer as being a 'bot-answer', which might work well in concert with an <a href="http://en.wikipedia.org/wiki/Akismet">Akismet</a> type service:</p> <blockquote> <p>Q: How old is my cat?<br /> A: Fluffy <em>(hello, bot!)</em> </p> </blockquote> <p>Anyway, I feel that captchas are a bit of dead end in terms of anti-spam measures for small sites. Small sites are not typical targets for spammers, as the reward is not worth the effort. However, if all these small sites are protected by the same captcha, breaking that captcha gives that spammer access to <em>(small-sites &#215; millions)</em>, which <em>is</em> worth the effort.</p>richardwbThu, 21 May 2009 15:17:00 -0700tag:www.setnode.com,2009-05-21:blog/captchas-shouldnt-be-the-default-defense-against-b/More thoughts on Qt 4.5http://www.setnode.com/blog/more-thoughts-on-qt-45/<p>I've been using Qt 4.5 for a couple more weeks now and I've had a few more thoughts on the framework.</p> <ul> <li>I don't know if I could handle using the plain Win32 API for GUI ever again</li> <li>Even with Qt's "parent handles the deletion of its children" memory management system it's still easier to use (and reason about) <code>shared_ptr</code> or another smart pointer, as long as you're not working with widgets or similar GUI elements. If you're working with GUI elements, Qt's memory management works perfectly and makes sense.</li> <li>You can assume that any <code>addWidget()</code>-like function will take ownership unless explicitly stated otherwise. I still wish they would just say straight out that "this function takes ownership".</li> <li>In my opinion the documentation would be much improved for newcomers if they had a "Qt Best Practices" section. You can get a sense of how things should be structured if you look at their sample programs, but there's a lot to go through.</li> <li>Other than those two nitpicks, the documentation is consistently quite good.</li> <li>I would suggest that you avoid using the <a href="http://doc.qtsoftware.com/4.5/containers.html">Qt containers</a> and instead favor the standard C++ containers whenever possible. There's less to learn, and most C++ programmers will have a firm grasp of the containers in the <code>std</code> namespace. Some Qt functions do return <a href="http://doc.trolltech.com/4.5/qstringlist.html"><code>QStringList</code></a> or some other Qt container, in which case you may as well just leave it in the container you get it in.</li> <li>On the other hand, if you're going to use Qt, you may as well use <a href="http://doc.trolltech.com/4.5/qstring.html"><code>QString</code></a> everywhere. It's used extensively through the Qt framework, so you won't be able to avoid it. It's a pretty decent string library anyway, with plenty of useful functions, and it handles Unicode cleanly in my experience.</li> <li><a href="http://doc.trolltech.com/4.5/qtextedit.html"><code>QTextEdit</code></a> isn't particularly performant, particularly when you resize it and it has to perform lots of word wrap calculations. Use <a href="http://doc.trolltech.com/4.5/qplaintextedit.html"><code>QPlainTextEdit</code></a> if you can.</li> </ul>richardwbThu, 07 May 2009 16:35:00 -0700tag:www.setnode.com,2009-05-07:blog/more-thoughts-on-qt-45/A really quick boost::random guidehttp://www.setnode.com/blog/a-really-quick-boost-random-guide/<p>This is a really short and quick guide on how to use <code>boost::random</code>. The best place to start is, as always, the <a href="http://www.boost.org/doc/libs/release/libs/random/index.html">documentation</a>, but Boost also provides a <a href="http://www.boost.org/doc/libs/release/libs/random/random_demo.cpp">simple sample program</a> that covers the library in a good "how to get started" fashion.</p> <p>What I'm about to write here is even shorter and less detailed -- it's just the basic code needed to generate some random numbers.</p> <div class="codehilite"><pre><span class="c1">// Initialize a random number generator.</span> <span class="c1">// Boost provides a bunch of these, note that some of them are not meant</span> <span class="c1">// for direct user usage and you should instead use a specialization (for </span> <span class="c1">// example, don&#39;t use linear_congruential and use minstd_rand or </span> <span class="c1">// minstd_rand0 instead)</span> <span class="c1">// This constructor seeds the generator with the current time.</span> <span class="c1">// As mentioned in Boost&#39;s sample program, time(0) is not a great seed,</span> <span class="c1">// but you can probably get away with it for most situations.</span> <span class="c1">// Consider using more precise timers such as gettimeofday on *nix or</span> <span class="c1">// GetTickCount/timeGetTime/QueryPerformanceCounter on Windows.</span> <span class="n">boost</span><span class="o">::</span><span class="n">mt19937</span> <span class="n">randGen</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">time</span><span class="p">(</span><span class="mi">0</span><span class="p">));</span> <span class="c1">// Now we set up a distribution. Boost provides a bunch of these as well.</span> <span class="c1">// This is the preferred way to generate numbers in a certain range.</span> <span class="c1">// In this example we initialize a uniform distribution between 0 and the max</span> <span class="c1">// value that an unsigned char can hold (255 for most architectures)</span> <span class="n">boost</span><span class="o">::</span><span class="n">uniform_int</span><span class="o">&lt;&gt;</span> <span class="n">uInt8Dist</span><span class="p">(</span><span class="mi">0</span><span class="p">,</span> <span class="n">std</span><span class="o">::</span><span class="n">numeric_limits</span><span class="o">&lt;</span><span class="kt">unsigned</span> <span class="kt">char</span><span class="o">&gt;::</span><span class="n">max</span><span class="p">());</span> <span class="c1">// Finally, declare a variate_generator which maps the random number</span> <span class="c1">// generator and the distribution together. This variate_generator</span> <span class="c1">// is usable like a function call.</span> <span class="n">boost</span><span class="o">::</span><span class="n">variate_generator</span><span class="o">&lt;</span> <span class="n">boost</span><span class="o">::</span><span class="n">mt19937</span><span class="o">&amp;</span><span class="p">,</span> <span class="n">boost</span><span class="o">::</span><span class="n">uniform_int</span><span class="o">&lt;&gt;</span> <span class="o">&gt;</span> <span class="n">GetRand</span><span class="p">(</span><span class="n">randGen</span><span class="p">,</span> <span class="n">uInt8Dist</span><span class="p">);</span> <span class="c1">// Generate a random number</span> <span class="kt">int</span> <span class="n">aRandomNumber</span> <span class="o">=</span> <span class="n">GetRand</span><span class="p">();</span> </pre></div>richardwbWed, 06 May 2009 20:03:00 -0700tag:www.setnode.com,2009-05-06:blog/a-really-quick-boost-random-guide/Namespaces are one honking great ideahttp://www.setnode.com/blog/namespaces-are-one-honking-great-idea/<p>The title of this post comes from the last line of <em><a href="http://www.python.org/dev/peps/pep-0020/">The Zen of Python</a></em>.</p> <p>It applies to C++ too: namespaces are great. Namespaces let the <a href="http://www.boost.org/">Boost</a> folks contain all sorts of widely varying libraries without having to worry about naming collisions in user code. Namespaces let you mix multiple libraries easily and safely. Namespaces let you group sets of related free functions together, without needing a class. Namespaces also let you work around one thing I've always found a bit unusual with enums: the way they don't have their own scope.</p> <div class="codehilite"><pre><span class="k">enum</span> <span class="n">ValidValues</span> <span class="p">{</span> <span class="n">Value1</span><span class="p">,</span> <span class="n">Value2</span> <span class="p">};</span> </pre></div> <p>This ends up declaring <code>Value1</code> and <code>Value2</code> in the underlying scope. What I like to do is wrap the enum in a namespace:</p> <div class="codehilite"><pre><span class="k">namespace</span> <span class="n">ValidValues</span> <span class="p">{</span> <span class="k">enum</span> <span class="n">Enum</span> <span class="p">{</span> <span class="n">Value1</span><span class="p">,</span> <span class="n">Value2</span> <span class="p">};</span> <span class="p">}</span> </pre></div> <p>This sticks <code>Value1</code> and <code>Value2</code> in the <code>ValidValues</code> namespace. The only disadvantage is declaring a variable of this enum type gets a bit silly and inconsistent. For example:</p> <div class="codehilite"><pre><span class="n">ValidValues</span> <span class="n">var</span> <span class="o">=</span> <span class="n">Value1</span><span class="p">;</span> <span class="c1">// error, ValidValues is a namespace, Value1 is undefined</span> <span class="n">ValidValues</span><span class="o">::</span><span class="n">Enum</span> <span class="n">var</span> <span class="o">=</span> <span class="n">Value1</span><span class="p">;</span> <span class="c1">// error, Value1 is undefined</span> <span class="n">ValidValues</span><span class="o">::</span><span class="n">Enum</span> <span class="n">var</span> <span class="o">=</span> <span class="n">ValidValues</span><span class="o">::</span><span class="n">Value1</span><span class="p">;</span> <span class="c1">// okay</span> </pre></div> <p>This is yet another area where C++0x will offer its own solution, in this case, <a href="http://en.wikipedia.org/wiki/C%2B%2B0x#Strongly_typed_enumerations">strongly typed enumerations</a>.</p>richardwbWed, 29 Apr 2009 09:17:00 -0700tag:www.setnode.com,2009-04-29:blog/namespaces-are-one-honking-great-idea/Right aligning a button in a QToolBarhttp://www.setnode.com/blog/right-aligning-a-button-in-a-qtoolbar/<p>Sometimes you will want to add a right-aligned button to a <code>QToolBar</code>. The first thing that probably comes to mind is to add a <code>QSpacerItem</code> to the toolbar, but that won't work as <code>QSpacerItem</code> is not a child of <code>QWidget</code>, so you can't use the <code>addWidget()</code> member of <code>QToolBar</code>. Instead, make a basic <code>QWidget</code>, set its <code>sizePolicy</code> to <code>Expanding</code>, and add that widget to your <code>QToolBar</code>. For example:</p> <div class="codehilite"><pre><span class="n">QWidget</span><span class="o">*</span> <span class="n">spacer</span> <span class="o">=</span> <span class="k">new</span> <span class="n">QWidget</span><span class="p">();</span> <span class="n">spacer</span><span class="o">-&gt;</span><span class="n">setSizePolicy</span><span class="p">(</span><span class="n">QSizePolicy</span><span class="o">::</span><span class="n">Expanding</span><span class="p">,</span> <span class="n">QSizePolicy</span><span class="o">::</span><span class="n">Expanding</span><span class="p">);</span> <span class="c1">// toolBar is a pointer to an existing toolbar</span> <span class="n">toolBar</span><span class="o">-&gt;</span><span class="n">addWidget</span><span class="p">(</span><span class="n">spacer</span><span class="p">);</span> <span class="n">toolBar</span><span class="o">-&gt;</span><span class="n">addAction</span><span class="p">(</span><span class="s">&quot;Right-aligned button&quot;</span><span class="p">);</span> </pre></div> <p>If you end up using a lot of these spacers you could even create a subclass.</p>richardwbThu, 23 Apr 2009 08:32:00 -0700tag:www.setnode.com,2009-04-23:blog/right-aligning-a-button-in-a-qtoolbar/Qt 4.5http://www.setnode.com/blog/qt-45/<p><a href="http://www.qtsoftware.com/products/">Qt</a> is a well known cross platform framework. It's probably most well known as the framework on which <a href="http://www.kde.org/">KDE</a> is written.</p> <p>Anyway, over the weekend I experimented with it a bit, and in terms of C++ GUI development it's a breath of fresh air. It approaches the ease of use of the .net GUI facilities, which is great for a language with no built in introspection abilities. The "moc" preprocessor that Qt requires (that lets them do things such as signals and slots) you to run on your source files is still a bit weird, but it's really not as bad as it seems.</p> <p>The Qt framework is also impressively comprehensive, making it very easy to code applications directly against Qt, instead of coding against a particular OS or a particular compiler.</p> <p>The style of the framework itself is more traditional than the common notion of modern C++, having more of an emphasis on subclassing and overriding virtual functions than on generic algorithms. The memory management system is definitely foreign: they encourage you to allocate on the heap, yet there are very few <code>delete</code> statements. The way it works is that <code>QObject</code>s (Qt's base class) accept a pointer to a parent in their constructor, which makes that particular <code>QObject</code> a child of the parent. When the parent is deleted, it takes care of deleting all its children. It's a change from RAII, for sure.</p> <p>It also takes a couple of hours to compile Visual Studio compatible versions of the various components, so don't do it as a last minute thing.</p>richardwbMon, 20 Apr 2009 09:16:00 -0700tag:www.setnode.com,2009-04-20:blog/qt-45/Porting a Winsock application to Linux...select(2) is not as simple as MSDN makes it seemhttp://www.setnode.com/blog/porting-a-winsock-application-to-linuxselect2-is-n/<p>I'm in the middle of porting bits of a Winsock application to Linux. Luckily when I first wrote the networking bits I had made an effort to write it in a somewhat cross platform manner. As a result, I stuck to <code>select()</code>, <code>send()</code>, <code>recv()</code>, and all the other function calls that Winsock provides that are close to the <a href="http://en.wikipedia.org/wiki/Berkeley_sockets">Berkeley socket interface</a>. Things go pretty smoothly, although for some reason there's this really weird pause when connecting that didn't exist before...</p> <p>Finally I hit a point where, for some reason, I couldn't establish a connection to the server and it just times out. That's really strange, so I threw good old debug statements all over the place and find out that this <code>select()</code> call is not doing much of a select:</p> <div class="codehilite"><pre>if (select(0, &amp;rdset, &amp;wtset, &amp;errset, &amp;tv) &gt; 0) </pre></div> <p>Notice the 0? <a href="http://msdn.microsoft.com/en-us/library/ms740141(VS.85).aspx">MSDN</a> states that it is:</p> <blockquote> <p><code>nfds</code><br /> Ignored. The nfds parameter is included only for compatibility with Berkeley sockets.</p> </blockquote> <p>Then I check the <a href="http://linux.die.net/man/2/select">equivalent docs</a> on the Linux side of things:</p> <blockquote> <p><code>nfds</code> is the highest-numbered file descriptor in any of the three sets, plus 1.</p> </blockquote> <p>Well, if I set <code>nfds</code> to 0, <code>select()</code> won't be doing very much selecting! Windows has <code>FD_SETSIZE</code> at 64 by default, and it ignores <code>nfds</code> and just checks whatever descriptors are in the <code>fd_set</code>s that you pass to it. Linux considers sockets and files the same thing, and thus has a much higher <code>FD_SETSIZE</code> (1024 and 4096 seem to be common). You don't want <code>select()</code> checking 4096 descriptors, so you set nfds to the highest file descriptor you want it to check, plus one. (As an aside, setting nfds to <code>FD_SETSIZE</code> is a bad idea.)</p> <div class="codehilite"><pre>if (select(my_socket + 1, &amp;rdset, &amp;wtset, &amp;errset, &amp;tv) &gt; 0) </pre></div> <p>Where <code>my_socket</code> is an appropriate file descriptor (such as the one returned by <code>socket()</code>). This works just fine in Windows too, since it ignores the <code>nfds</code> parameter.</p> <p>Armed with this newfound knowledge, I go and fix all the other <code>select()</code> statements in my code, which ends up fixing the weird pause as well. Effectively, without a proper <code>nfds</code> value, <code>select()</code> just acts as a timer and blocks until the specified amount of time has elapsed.</p>richardwbFri, 10 Apr 2009 17:54:00 -0700tag:www.setnode.com,2009-04-10:blog/porting-a-winsock-application-to-linuxselect2-is-n/All AJAX sites need a fancy indeterminate progress indicator...http://www.setnode.com/blog/all-ajax-sites-need-a-fancy-indeterminate-progress/<p><a href="http://www.ajaxload.info/">Ajaxload</a> is a neat little site that generates those throbbers/spinning wheels that are in vogue nowadays. Your website/application won't be complete without one, after all.</p>richardwbSun, 05 Apr 2009 20:22:00 -0700tag:www.setnode.com,2009-04-05:blog/all-ajax-sites-need-a-fancy-indeterminate-progress/PNG has a well designed magic number (or FourCC)http://www.setnode.com/blog/png-has-a-well-designed-magic-number-or-fourcc/<p>Even with all the XML floating around, binary formats still have their place. It's good practice to place an identifier at the beginning of the binary file, so that the file type can be determined even in the absence of a proper file extension.</p> <p>The simplest route to take is to just stuff some plain text there:</p> <div class="codehilite"><pre>[M Y F I L E][rest of file] </pre></div> <p>However, consider following the design of the PNG magic number, described in detail in <a href="http://www.libpng.org/pub/png/book/chapter08.html">the PNG book</a>. With some really neat design they are able to quickly detect some common forms of corruption caused by an incompatible transfer mechanism. In that case your identifier may look like:</p> <div class="codehilite"><pre>[\211 M Y F I L E \r \n \032 \n][rest of file] </pre></div> <p>With an identifier like this many common forms of transfer corruption can be quickly identified, and you can spit out a simple "corrupt file" message instead of trying to read a broken file.</p>richardwbFri, 03 Apr 2009 17:20:00 -0700tag:www.setnode.com,2009-04-03:blog/png-has-a-well-designed-magic-number-or-fourcc/Don't forget about copy constructors and the copy assignment operatorhttp://www.setnode.com/blog/dont-forget-about-copy-constructors-and-the-copy-assignment-operator/<p>Something that I've always found handy to do is to decide, right away, what the copy semantics of a particular class are. Generally it turns out that it makes no sense (or is a lot of work) to allow copying, in which case the standard approach is to define the copy constructor and assignment operator as <code>private</code>.</p> <p>An alternative approach and one that I think is a bit more self-documenting, is to inherit from <a href="http://www.boost.org/doc/libs/1_38_0/libs/utility/utility.htm#Class_noncopyable"><code>boost::noncopyable</code></a>. This achieves the same effect and makes it immediately obvious that the class will not allow copying.</p> <div class="codehilite"><pre><span class="k">class</span> <span class="nc">MyClass</span> <span class="o">:</span> <span class="n">boost</span><span class="o">::</span><span class="n">noncopyable</span> <span class="p">{</span> <span class="p">};</span> </pre></div> <p>The most correct way to use <code>boost::noncopyable</code> is to inherit it privately, since inheriting it publicly could let people do really funny stuff like:</p> <div class="codehilite"><pre><span class="kt">void</span> <span class="nf">stuff</span><span class="p">(</span><span class="k">const</span> <span class="n">boost</span><span class="o">::</span><span class="n">noncopyable</span><span class="o">&amp;</span> <span class="n">obj</span><span class="p">);</span> </pre></div> <p><a href="http://groups.google.com/group/comp.lang.c++/browse_thread/thread/830d8840c2b86114">(more details here)</a></p>richardwbFri, 03 Apr 2009 12:30:00 -0700tag:www.setnode.com,2009-04-03:blog/dont-forget-about-copy-constructors-and-the-copy-assignment-operator/A RapidXML gotchahttp://www.setnode.com/blog/a-rapidxml-gotcha/<p>I just spent a couple of hours trying to track down why I was seemingly losing data values while modifying nodes in the DOM. It's spelled out in the documentation, but it definitely threw me for a loop (I would consider this behavior surprising). Basically, RapidXML gives you the ability to assign/modify the value of a node and it also likes to create data nodes when you parse a document. When printing, the data node takes precedence over the value.</p> <p>When you create a document from scratch this likely won't bite you, but when you parse an existing document and neglect to supply the <code>parse_no_data_nodes</code> flag, the parser creates data nodes. If you try to update your values with the <code>value()</code> function, it works just fine (and you can even pull it back out without any problems), but when you use the <code>print()</code> function, the data node (which you haven't updated) will show up instead.</p> <p>What made this even more difficult to track down was how <code>value()</code> will return the first data node it finds if there isn't a value yet, so it really does seem like you have a value already. I've updated my <a href="http://www.setnode.com/blog/quick-notes-on-how-to-use-rapidxml/">prior RapidXML entry</a> to include the <code>parse_no_data_nodes</code> flag, which may save someone some time down the road.</p>richardwbThu, 26 Mar 2009 13:00:00 -0700tag:www.setnode.com,2009-03-26:blog/a-rapidxml-gotcha/shared_ptr is great...but sometimes auto_ptr is actually better!http://www.setnode.com/blog/shared-ptr-is-greatbut-sometimes-auto-ptr-is-actua/<p>Modern C++ programming benefits greatly from smart pointers. Smart pointers automate the error-prone process of making sure you have a matching number of <code>new</code> and <code>delete</code> statements. There's even one included in the C++ standard library: <code>std::auto_ptr</code>.</p> <p>It's not a true general purpose smart pointer, however. For one, it has somewhat unusual transfer-of-ownership semantics:</p> <div class="codehilite"><pre><span class="n">std</span><span class="o">::</span><span class="n">auto_ptr</span><span class="o">&lt;</span><span class="n">MyClass</span><span class="o">&gt;</span> <span class="n">a</span><span class="p">(</span><span class="k">new</span> <span class="n">MyClass</span><span class="p">());</span> <span class="n">std</span><span class="o">::</span><span class="n">auto_ptr</span><span class="o">&lt;</span><span class="n">MyClass</span><span class="o">&gt;</span> <span class="n">b</span> <span class="o">=</span> <span class="n">a</span><span class="p">;</span> <span class="c1">// a now points to nothing!</span> </pre></div> <p>This also makes it dangerous to use in containers, as described in <a href="http://www.gotw.ca/publications/using_auto_ptr_effectively.htm"><em>Using auto_ptr Effectively</em></a>. On the other hand, <code>shared_ptr</code> (which will be available in the next C++ standard, C++0x, and is now available in the <a href="http://www.boost.org/doc/libs/release/libs/smart_ptr/shared_ptr.htm">Boost libraries</a>) is a reference counting smart pointer. It keeps track of the number of references to a particular object, and when there are no more references, it deletes the object. This is safe to use in containers. In fact, you can use <code>shared_ptr</code> pretty much everywhere and you will never have to worry about manually releasing memory again (cycles and threading are pretty much the only major problems).</p> <p>However, while <code>shared_ptr</code> is a great general purpose smart pointer, <code>auto_ptr</code> has its uses. If you have a function that involves transfer-of-ownership semantics (whether receiving or giving), why not use the smart pointer that perfectly captures those requirements? The 'sources' (creates and then gives away ownership) and 'sinks' (takes ownership) described in the <a href="http://www.gotw.ca/publications/using_auto_ptr_effectively.htm"><em>Using auto_ptr Effectively</em></a> article is a prime example of this. Instead of using comments to specify that the caller of a function must manage the lifetime of the returned object, <code>auto_ptr</code> forces them to manage it (and if they don't, it'll clean itself up anyway). <code>shared_ptr</code> will likely work just as well, but it doesn't capture the semantics.</p> <p>Another noteworthy reason to use <code>auto_ptr</code> when the semantics are suitable is that while <code>auto_ptr</code> can give away ownership to <code>shared_ptr</code>, <code>shared_ptr</code> cannot give away ownership to <code>auto_ptr</code> or another smart pointer (there is no <code>release()</code> function in <code>shared_ptr</code>).</p> <p><code>auto_ptr</code> is <a href="http://www.informit.com/guides/content.aspx?g=cplusplus&amp;seqNum=400">on its way to deprecation</a>, but we haven't even seen C++0x yet, so I wouldn't worry too much about it. Its replacement, <code>unique_ptr</code>, will have the same transfer-of-ownership semantics, just implemented in a much safer way, so it'd be worth the effort to get used to using the right smart pointer for the job.</p> <p>Speaking of which, do you know what <code>scoped_ptr</code> is?</p>richardwbSat, 21 Mar 2009 18:04:00 -0700tag:www.setnode.com,2009-03-21:blog/shared-ptr-is-greatbut-sometimes-auto-ptr-is-actua/Don't spend time micromanaging optimization options in Visual C++http://www.setnode.com/blog/dont-spend-time-micromanaging-optimization-options-in-visual-c/<p>It's surprisingly common to see people ask what the best Visual C++ optimization options are for their C++ code.</p> <p>The best answer is to profile and benchmark.</p> <p>Failing that, it's pretty simple. Use <code>/O2</code> to optimize for speed, and <code>/O1</code> to optimize for size. That's (almost) it. If you have a large program you will probably benefit more from optimizing for size:</p> <blockquote> <p>Generally speaking, small applications should be compiled with /O2, and large applications should be compiled with /O1 because very large applications can end up putting a lot of stress on the instruction cache of the processor, and this can lead to worse performance. To minimize this, use /O1 to reduce the amount of "code bloat" introduced by the optimizer from certain transformations such a loop unrolling or selection of larger, faster sequences of code. [<a href="http://msdn.microsoft.com/en-us/library/aa290055.aspx">MSDN</a>]</p> </blockquote> <p>But what about <em>Enable Intrinsic Functions</em> (<code>/Oi</code>), <em>Omit Frame Pointers</em> (<code>/Oy</code>), etc.?</p> <p>Check out the <a href="http://msdn.microsoft.com/en-us/library/8f8h5cxt.aspx">documentation</a> for <code>/O2</code> and <code>/O1</code>:</p> <ul> <li><code>/O1</code> (Minimize Size) : Equivalent to /Og /Os /Oy /Ob2 /Gs /GF /Gy</li> <li><code>/O2</code> (Maximize Speed) : Equivalent to /Og /Oi /Ot /Oy /Ob2 /Gs /GF /Gy</li> </ul> <p>They are already all specified. Yes, the property pages say <em>Disabled</em> or <em>No</em>, but what they really mean is <em>Default</em>.</p> <p>The only general optimization I'm aware of that doesn't fall in this category is <em>Whole Program Optimization</em> (<code>/GL</code>), which also requires <em>Link Time Code Generation</em> (<code>/LTCG</code>).</p> <p>Finally, what about <em>Full Optimization</em> (<code>/Ox</code>)? </p> <blockquote> <p>In general, /O2 should be preferred over /Ox and /O1 over /Oxs. [<a href="http://msdn.microsoft.com/en-us/library/59a3b321.aspx">MSDN</a>]</p> </blockquote> <p>[Edit: Note that there is an IDE bug in Visual Studio 2008 which may affect whether or not optimizations are applied. <a href="http://www.setnode.com/blog/optimization-switches-and-visual-studio-2008/">I write more about it here.</a>]</p>richardwbSat, 14 Mar 2009 14:37:00 -0700tag:www.setnode.com,2009-03-14:blog/dont-spend-time-micromanaging-optimization-options-in-visual-c/Several compilation options I use with C++ projects in Visual Studiohttp://www.setnode.com/blog/several-compilation-options-i-use-with-c-project/<p>These are compilation options that I typically enable for any C++ projects in Visual Studio. They should go in the project's property settings, under <em>Configuration Properties</em>-&gt;<em>C/C++</em>-&gt;<em>Command Line</em>, in the <em>Additional options</em> textbox. They are listed here exactly as they should be entered in that box (equal signs and all).</p> <ul> <li><code>/MP</code> : This enables multi-process compilation, which can provide a significant speed boost on the multi-core processor you likely have in your development (or build) machine. As the MSDN documentation states, it is not compatible with the <em>Enable Minimal Rebuild</em> option, which, depending on the situation, may negate any performance advantage this switch has. Disabling minimal rebuild is not as bad as it sounds<sup id="fnref:minimalrebuild"><a class="footnote-ref" href="#fn:minimalrebuild" rel="footnote">1</a></sup> and in my projects I've found that using <code>/MP</code> confers a significant improvement in compilation time. You definitely want to enable it for <em>Release</em> builds, at least. <a href="http://msdn.microsoft.com/en-us/library/bb385193.aspx">Reference</a>.</li> <li><code>/D_CRT_SECURE_NO_WARNINGS</code> : This switch disables the warnings that Visual Studio spits out if you use any of the <strong>C</strong> <strong>R</strong>un<strong>T</strong>ime functions that Microsoft has provided secure replacements for (such as <code>strncpy</code>). This isn't necessarily a bad idea, but their safe functions are not part of the standard and are thus non-portable. <a href="http://msdn.microsoft.com/en-us/library/8ef0s5kh.aspx">Reference</a>.</li> <li><code>/D_SCL_SECURE_NO_WARNINGS</code> : Just like the switch above, only for the <strong>S</strong>tandard <strong>C</strong>++ <strong>L</strong>ibrary (anything in the <code>std</code> namespace). <a href="http://msdn.microsoft.com/en-us/library/aa985974.aspx">Reference</a>.</li> <li><code>/D_SECURE_SCL=0</code> : Disables checked iterators. Disabling this feature can improve performance when using iterators, at the expense of less protection against unsafe iterator use. Generally there isn't too much of a performance difference (a Visual C++ lead states that they measured about a 6% difference in <a href="http://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=105752">this feedback / bug page</a>) so it may be worth leaving it on most of the time. <a href="http://msdn.microsoft.com/en-us/library/aa985896.aspx">Reference</a>.</li> </ul> <p>Note that <code>/D_CRT_SECURE_NO_<em>WARNINGS</em></code> and <code>/D_SCL_SECURE_NO_<em>WARNINGS</em></code> are <code>/D_CRT_SECURE_NO_<em>DEPRECATE</em></code> and <code>/D_SCL_SECURE_NO_<em>DEPRECATE</em></code>, respectively, in versions prior to Visual Studio 2008.</p> <div class="footnote"> <hr /> <ol> <li id="fn:minimalrebuild"> <p>Disabling Minimal Rebuild does not mean that the whole project gets rebuilt every time, just that Visual Studio uses a "was this .cpp/.h modified?" approach instead of trying to determine if the exact changes you made warrant a recompile.&#160;<a class="footnote-backref" href="#fnref:minimalrebuild" rev="footnote" title="Jump back to footnote 1 in the text">&#8617;</a></p> </li> </ol> </div>richardwbThu, 12 Mar 2009 16:39:00 -0700tag:www.setnode.com,2009-03-12:blog/several-compilation-options-i-use-with-c-project/Stop wasting time stepping into functions you don't care about in Microsoft Visual Studio (C++)http://www.setnode.com/blog/stop-wasting-time-stepping-into-functions-you-dont/<p>The Visual Studio debugger is amazingly useful. However, you soon learn to sigh the moment you come into contact with something like this:</p> <div class="codehilite"><pre><span class="n">boost</span><span class="o">::</span><span class="n">scoped_ptr</span><span class="o">&lt;</span><span class="n">Startup</span><span class="o">&gt;</span> <span class="n">dlg</span><span class="p">(</span> <span class="k">new</span> <span class="n">Startup</span><span class="p">(</span><span class="n">settings</span><span class="o">-&gt;</span><span class="n">GetWindowPosition</span><span class="p">()));</span> </pre></div> <p>You want to step into the <code>Startup</code> constructor, but there is a lot of stuff in your way. </p> <ol> <li>First you will step into <code>shared_ptr::operator-&gt;</code> (did I mention that <code>settings</code> was a <code>shared_ptr</code>?).</li> <li>Then you will step into <code>GetWindowPosition()</code>.</li> <li>Then into <code>operator new</code>.</li> <li>And then into your <code>Startup</code> constructor. Yes!</li> <li>And finally you'll finish with the <code>scoped_ptr</code> constructor if you so choose.</li> </ol> <p>If you've done this a lot you've probably gotten really good at the <em>Step Out</em> shortcut (Shift-F11).</p> <p>Well, here are two alternatives!</p> <p>First, while program execution is paused, right-click anywhere in the source window and look for the <em>Step Into Specific</em> item. You can select any of these functions to instantly step inside.</p> <p>Alternatively, there is a special undocumented (and unsupported) registry key that you can use to specify functions that you always want to skip. Navigate to <code>HKLM\SOFTWARE\Microsoft\VisualStudio\9.0\NativeDE\StepOver</code> (users of a 64-bit variant of Windows will want to check <code>HKLM\SOFTWARE\Wow6432Node\Microsoft\...</code> instead) and add some string values like this example:</p> <blockquote> <p>Name: 50 (priority, higher values have greater priority)<br /> Value: <code>std\:\:.*=NoStepInto</code></p> <p>Name: 60<br /> Value: <code>operator new=NoStepInto</code></p> <p>Name: 70<br /> Value: <code>boost\:\:.*=NoStepInto</code></p> </blockquote> <p>The backslashes are necessary because <code>:</code> (colon) is a special character in <a href="http://msdn.microsoft.com/en-us/library/2k3te2cs(VS.80).aspx">Visual Studio regex</a>. You sometimes see two backslashes used in other examples, this is only necessary if you are directly editing a <code>.reg</code> file (which I don't recommend). These rules will adjust the behaviour of the <em>Step-Into</em> command and make it skip anything from the <code>std</code> or <code>boost</code> namespaces, as well as the basic <code>operator new</code>. It will still step into an overloaded <code>operator new</code>, so don't fear. There are more details on <a href="http://blogs.msdn.com/andypennell/archive/2004/02/06/69004.aspx">this blog post</a>, as well as <a href="http://groups.google.com/group/microsoft.public.vsnet.debugging/msg/26addb1b539883e8">microsoft.public.vsnet.debugging</a>.</p> <p>One more thing: you can combine these two approaches. Say that you've added a skip for the entire <code>boost</code> namespace, but you decide you really want to take a peek inside one particular line and see exactly what is happening to your parameters. Pause execution on that line, and then right-click and use <em>Step Into Specific</em>. This is still the same list as before and it works the same as before, regardless of any NoStepInto rules.</p>richardwbMon, 09 Mar 2009 17:58:00 -0700tag:www.setnode.com,2009-03-09:blog/stop-wasting-time-stepping-into-functions-you-dont/Boost.Thread triggers warning C4103 in Microsoft Visual Studiohttp://www.setnode.com/blog/boostthread-triggers-warning-c4103-in-microsoft-vi/<p>Got a whole mess of warnings when I moved some of my includes around, particularly this one: <code>#include &lt;boost/thread.hpp&gt;</code></p> <div class="codehilite"><pre>abi_prefix.hpp(19) : warning C4103: &#39;d:\\boost\\boost_1_38_0\\boost\\config\\abi_prefix.hpp&#39; : alignment changed after including header, may be due to missing #pragma pack(pop) </pre></div> <p>Some experimentation reveals that including <code>thread.hpp</code> before <code>winsock2.h</code> triggers all these warnings. The simple solution is to just move <code>#include &lt;boost/thread.hpp&gt;</code> down below <code>#include &lt;winsock2.h&gt;</code>.</p>richardwbMon, 02 Mar 2009 17:28:00 -0800tag:www.setnode.com,2009-03-02:blog/boostthread-triggers-warning-c4103-in-microsoft-vi/Building Boost (now with dual/quad/multi-core action!)http://www.setnode.com/blog/building-boost-now-with-dual-quad-multi-core-action/<p><em>Update: More recent versions of Boost (1.39.0 and later) have a simpler build process, which I've <a href="http://www.setnode.com/blog/an-update-on-building-boost-with-msvc-still-with-dual-quad-multi-core-action/">written about here</a>.</em></p> <p>Steps to build the non-header-only Boost libraries on Windows, such as <code>Boost.Thread</code> and <code>Boost.Regex</code>, using Microsoft Visual Studio:</p> <ol> <li> <p><a href="http://www.boost.org/users/download/">Download</a> the latest version of Boost and extract it to some location, say, <code>D:\Boost\</code>, making sure to maintain the directory structure</p> </li> <li> <p><a href="http://www.boost.org/users/download/">Download</a> the latest version of Boost Jam (you want the ntx86 binaries) and extract it to some location (probably the same as above), again making sure to maintain the directory structure</p> </li> <li> <p>Your directory structure should now consist of <code>D:\Boost\boost_1_38_0\</code> and <code>D:\Boost\boost-jam-3.1.17-1-ntx86\</code></p> </li> <li> <p>Make sure you have lots of hard drive space (at least 5GB)</p> </li> <li> <p>In a command prompt, navigate to your Boost library folder (<code>D:\Boost\boost_1_38_0\</code>) and then use this command (read further down if you want details about what these arguments are doing):</p> <div class="codehilite"><pre>&gt; ..\boost-jam-3.1.17-1-ntx86\bjam.exe --toolset=msvc --build-type=complete stage </pre></div> </li> <li> <p>If you have a dual/quad/many-core processor or can otherwise take advantage of parallel jobs, also add the <code>-jN</code> switch, where <code>N</code> is the number of jobs to run at a time (e.g. <code>bjam.exe -j4 --toolset=msvc</code>).</p> </li> <li> <p>And wait. This will take a very long time.</p> </li> <li> <p>After it completes you will have a <code>stage</code> subdirectory (<code>D:\Boost\boost_1_38_0\stage\</code>) which will contain a <code>lib</code> subdirectory, containing the compiled libraries. You may move these anywhere you wish.</p> </li> <li> <p>You will also have a <code>bin.v2</code> subdirectory which was used for temporary files. You may delete this folder to reclaim some hard drive space.</p> </li> </ol> <p>More details:</p> <p><code>--toolset=msvc</code> : tells Boost Jam to compile with Microsoft Visual Studio.</p> <p><code>--build-type=complete</code> : notes that you want every possible combination built (Debug/Release, Multi/Single threaded, Static/Shared).</p> <p><code>stage</code> : a build target which builds the compiled libraries to the stage directory (which you can set with <code>--stagedir=&lt;STAGEDIR&gt;</code>). Contrast this with the <code>install</code> target, which builds the compiled libraries, but <em>also</em> copies the header-only libraries to a particular location. This is generally an unnecessary step since you've already extracted the Boost headers somewhere already. Look inside the <code>Jamroot</code> file inside your Boost folder for more details.</p>richardwbMon, 02 Mar 2009 16:27:00 -0800tag:www.setnode.com,2009-03-02:blog/building-boost-now-with-dual-quad-multi-core-action/Quick notes on how to use RapidXMLhttp://www.setnode.com/blog/quick-notes-on-how-to-use-rapidxml/<p>There's a C++ XML library called <a href="http://rapidxml.sourceforge.net/">RapidXML</a> which is perfect for most non-enterprise uses of XML. I wouldn't call this a tutorial, but I hope this ends up helping someone. The documentation isn't very explicit on how to output an XML declaration, for example.</p> <p>How to create your XML from scratch and then output this XML into a string, with an XML declaration:</p> <div class="codehilite"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span> <span class="nt">&lt;rootnode</span> <span class="na">version=</span><span class="s">&quot;1.0&quot;</span> <span class="na">type=</span><span class="s">&quot;example&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;childnode/&gt;</span> <span class="nt">&lt;/rootnode&gt;</span> </pre></div> <div class="codehilite"><pre><span class="k">using</span> <span class="k">namespace</span> <span class="n">rapidxml</span><span class="p">;</span> <span class="n">xml_document</span><span class="o">&lt;&gt;</span> <span class="n">doc</span><span class="p">;</span> <span class="c1">// xml declaration</span> <span class="n">xml_node</span><span class="o">&lt;&gt;*</span> <span class="n">decl</span> <span class="o">=</span> <span class="n">doc</span><span class="p">.</span><span class="n">allocate_node</span><span class="p">(</span><span class="n">node_declaration</span><span class="p">);</span> <span class="n">decl</span><span class="o">-&gt;</span><span class="n">append_attribute</span><span class="p">(</span><span class="n">doc</span><span class="p">.</span><span class="n">allocate_attribute</span><span class="p">(</span><span class="s">&quot;version&quot;</span><span class="p">,</span> <span class="s">&quot;1.0&quot;</span><span class="p">));</span> <span class="n">decl</span><span class="o">-&gt;</span><span class="n">append_attribute</span><span class="p">(</span><span class="n">doc</span><span class="p">.</span><span class="n">allocate_attribute</span><span class="p">(</span><span class="s">&quot;encoding&quot;</span><span class="p">,</span> <span class="s">&quot;utf-8&quot;</span><span class="p">));</span> <span class="n">doc</span><span class="p">.</span><span class="n">append_node</span><span class="p">(</span><span class="n">decl</span><span class="p">);</span> <span class="c1">// root node</span> <span class="n">xml_node</span><span class="o">&lt;&gt;*</span> <span class="n">root</span> <span class="o">=</span> <span class="n">doc</span><span class="p">.</span><span class="n">allocate_node</span><span class="p">(</span><span class="n">node_element</span><span class="p">,</span> <span class="s">&quot;rootnode&quot;</span><span class="p">);</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">append_attribute</span><span class="p">(</span><span class="n">doc</span><span class="p">.</span><span class="n">allocate_attribute</span><span class="p">(</span><span class="s">&quot;version&quot;</span><span class="p">,</span> <span class="s">&quot;1.0&quot;</span><span class="p">));</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">append_attribute</span><span class="p">(</span><span class="n">doc</span><span class="p">.</span><span class="n">allocate_attribute</span><span class="p">(</span><span class="s">&quot;type&quot;</span><span class="p">,</span> <span class="s">&quot;example&quot;</span><span class="p">));</span> <span class="n">doc</span><span class="p">.</span><span class="n">append_node</span><span class="p">(</span><span class="n">root</span><span class="p">);</span> <span class="c1">// child node</span> <span class="n">xml_node</span><span class="o">&lt;&gt;*</span> <span class="n">child</span> <span class="o">=</span> <span class="n">doc</span><span class="p">.</span><span class="n">allocate_node</span><span class="p">(</span><span class="n">node_element</span><span class="p">,</span> <span class="s">&quot;childnode&quot;</span><span class="p">);</span> <span class="n">root</span><span class="o">-&gt;</span><span class="n">append_node</span><span class="p">(</span><span class="n">child</span><span class="p">);</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">xml_as_string</span><span class="p">;</span> <span class="c1">// watch for name collisions here, print() is a very common function name!</span> <span class="n">print</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">xml_as_string</span><span class="p">),</span> <span class="n">doc</span><span class="p">);</span> <span class="c1">// xml_as_string now contains the XML in string form, indented</span> <span class="c1">// (in all its angle bracket glory)</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">xml_no_indent</span><span class="p">;</span> <span class="c1">// print_no_indenting is the only flag that print() knows about</span> <span class="n">print</span><span class="p">(</span><span class="n">std</span><span class="o">::</span><span class="n">back_inserter</span><span class="p">(</span><span class="n">xml_no_indent</span><span class="p">),</span> <span class="n">doc</span><span class="p">,</span> <span class="n">print_no_indenting</span><span class="p">);</span> <span class="c1">// xml_no_indent now contains non-indented XML</span> </pre></div> <p><br /><br /> Parsing and traversing an XML document like this one:</p> <div class="codehilite"><pre><span class="cp">&lt;?xml version=&quot;1.0&quot; encoding=&quot;utf-8&quot;?&gt;</span> <span class="nt">&lt;rootnode</span> <span class="na">version=</span><span class="s">&quot;1.0&quot;</span> <span class="na">type=</span><span class="s">&quot;example&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;childnode</span> <span class="na">entry=</span><span class="s">&quot;1&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;evendeepernode</span> <span class="na">attr1=</span><span class="s">&quot;cat&quot;</span> <span class="na">attr2=</span><span class="s">&quot;dog&quot;</span><span class="nt">/&gt;</span> <span class="nt">&lt;evendeepernode</span> <span class="na">attr1=</span><span class="s">&quot;lion&quot;</span> <span class="na">attr2=</span><span class="s">&quot;wolf&quot;</span><span class="nt">/&gt;</span> <span class="nt">&lt;/childnode&gt;</span> <span class="nt">&lt;childnode</span> <span class="na">entry=</span><span class="s">&quot;2&quot;</span><span class="nt">&gt;</span> <span class="nt">&lt;/childnode&gt;</span> <span class="nt">&lt;/rootnode&gt;</span> </pre></div> <div class="codehilite"><pre><span class="kt">void</span> <span class="nf">traverse_xml</span><span class="p">(</span><span class="k">const</span> <span class="n">std</span><span class="o">::</span><span class="n">string</span><span class="o">&amp;</span> <span class="n">input_xml</span><span class="p">)</span> <span class="p">{</span> <span class="c1">// (input_xml contains the above XML)</span> <span class="c1">// make a safe-to-modify copy of input_xml</span> <span class="c1">// (you should never modify the contents of an std::string directly)</span> <span class="n">vector</span><span class="o">&lt;</span><span class="kt">char</span><span class="o">&gt;</span> <span class="n">xml_copy</span><span class="p">(</span><span class="n">input_xml</span><span class="p">.</span><span class="n">begin</span><span class="p">(),</span> <span class="n">input_xml</span><span class="p">.</span><span class="n">end</span><span class="p">());</span> <span class="n">xml_copy</span><span class="p">.</span><span class="n">push_back</span><span class="p">(</span><span class="sc">&#39;\0&#39;</span><span class="p">);</span> <span class="c1">// only use xml_copy from here on!</span> <span class="n">xml_document</span><span class="o">&lt;&gt;</span> <span class="n">doc</span><span class="p">;</span> <span class="c1">// we are choosing to parse the XML declaration</span> <span class="c1">// parse_no_data_nodes prevents RapidXML from using the somewhat surprising</span> <span class="c1">// behavior of having both values and data nodes, and having data nodes take</span> <span class="c1">// precedence over values when printing</span> <span class="c1">// &gt;&gt;&gt; note that this will skip parsing of CDATA nodes &lt;&lt;&lt;</span> <span class="n">doc</span><span class="p">.</span><span class="n">parse</span><span class="o">&lt;</span><span class="n">parse_declaration_node</span> <span class="o">|</span> <span class="n">parse_no_data_nodes</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">xml_copy</span><span class="p">[</span><span class="mi">0</span><span class="p">]);</span> <span class="c1">// alternatively, use one of the two commented lines below to parse CDATA nodes, </span> <span class="c1">// but please note the above caveat about surprising interactions between </span> <span class="c1">// values and data nodes (also read http://www.setnode.com/blog/a-rapidxml-gotcha/)</span> <span class="c1">// if you use one of these two declarations try to use data nodes exclusively and</span> <span class="c1">// avoid using value()</span> <span class="c1">//doc.parse&lt;parse_declaration_node&gt;(&amp;xml_copy[0]); // just get the XML declaration</span> <span class="c1">//doc.parse&lt;parse_full&gt;(&amp;xml_copy[0]); // parses everything (slowest)</span> <span class="c1">// since we have parsed the XML declaration, it is the first node</span> <span class="c1">// (otherwise the first node would be our root node)</span> <span class="n">string</span> <span class="n">encoding</span> <span class="o">=</span> <span class="n">doc</span><span class="p">.</span><span class="n">first_node</span><span class="p">()</span><span class="o">-&gt;</span><span class="n">first_attribute</span><span class="p">(</span><span class="s">&quot;encoding&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">();</span> <span class="c1">// encoding == &quot;utf-8&quot;</span> <span class="c1">// we didn&#39;t keep track of our previous traversal, so let&#39;s start again</span> <span class="c1">// we can match nodes by name, skipping the xml declaration entirely</span> <span class="n">xml_node</span><span class="o">&lt;&gt;*</span> <span class="n">cur_node</span> <span class="o">=</span> <span class="n">doc</span><span class="p">.</span><span class="n">first_node</span><span class="p">(</span><span class="s">&quot;rootnode&quot;</span><span class="p">);</span> <span class="n">string</span> <span class="n">rootnode_type</span> <span class="o">=</span> <span class="n">cur_node</span><span class="o">-&gt;</span><span class="n">first_attribute</span><span class="p">(</span><span class="s">&quot;type&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">();</span> <span class="c1">// rootnode_type == &quot;example&quot;</span> <span class="c1">// go straight to the first evendeepernode</span> <span class="n">cur_node</span> <span class="o">=</span> <span class="n">cur_node</span><span class="o">-&gt;</span><span class="n">first_node</span><span class="p">(</span><span class="s">&quot;childnode&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">first_node</span><span class="p">(</span><span class="s">&quot;evendeepernode&quot;</span><span class="p">);</span> <span class="n">string</span> <span class="n">attr2</span> <span class="o">=</span> <span class="n">cur_node</span><span class="o">-&gt;</span><span class="n">first_attribute</span><span class="p">(</span><span class="s">&quot;attr2&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">();</span> <span class="c1">// attr2 == &quot;dog&quot;</span> <span class="c1">// and then to the second evendeepernode</span> <span class="n">cur_node</span> <span class="o">=</span> <span class="n">cur_node</span><span class="o">-&gt;</span><span class="n">next_sibling</span><span class="p">(</span><span class="s">&quot;evendeepernode&quot;</span><span class="p">);</span> <span class="n">attr2</span> <span class="o">=</span> <span class="n">cur_node</span><span class="o">-&gt;</span><span class="n">first_attribute</span><span class="p">(</span><span class="s">&quot;attr2&quot;</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">value</span><span class="p">();</span> <span class="c1">// now attr2 == &quot;wolf&quot;</span> <span class="p">}</span> </pre></div> <p>[Edit: Thanks to Michele Tavella for catching a silly bug on my part!]<br /> [Edit: Thanks to Wei for noting that <code>parse_no_data_nodes</code> will skip over CDATA nodes]<br /> [Edit: Thanks to remo for catching a typo]</p> <p>Thanks for the comments everyone! I'm glad to help out where I can, but please do note that I check this blog rather infrequently at this point in time and will often not respond for days, if not weeks. If you have a question to which you need an answer within a reasonable time frame, I'd recommend using Stack Overflow. On the other hand, if you have corrections and/or suggestions, please continue to leave them here and I'll address them as they come up. Thanks again!</p>richardwbFri, 27 Feb 2009 21:11:00 -0800tag:www.setnode.com,2009-02-27:blog/quick-notes-on-how-to-use-rapidxml/Remember that users do not read!http://www.setnode.com/blog/remember-that-users-do-not-read/<p>Users do not read anything they are not interested in. This is <a href="http://www.codinghorror.com/blog/archives/000114.htm">well</a> <a href="http://www.joelonsoftware.com/uibook/chapters/fog0000000062.html">known</a> and mentioned by many others.</p> <p>You might not agree, or think that only a small percentage of users don't read. After all, <em>you</em> read. You <em>love</em> to read! Unfortunately, you don't count. You're a programmer, you better love reading!</p> <p>I had absorbed this information before, but there is a definite difference between knowledge and experience. A couple of weeks ago I witnessed first-hand evidence that users do not read. I introduced a friend (who is the same age as I am and computer literate, uses Facebook and instant messaging, comfortable with Microsoft Office, etc.) to a computer game. This game, like most casual games nowadays, has a friendly tutorial, with large (~48pt) colorful fonts and a very gradual learning curve. The first thing the tutorial does is put up five lines of text which is maybe two sentences worth of information. All five lines are promptly ignored and the cursor heads straight for the "<em>Next</em>" button.</p> <p>Well, that's okay, there's nothing important in that dialog anyway.</p> <p><em>Next</em>; <em>next</em>; <em>next</em>. The next three dialogs are skipped. The last dialog happens to contain important information on the more subtle points of the game.</p> <p>This starts to drive me nuts, as I always eagerly soak up any bits of information a game throws at me. I want to play it to the best of my ability, after all. It hit me then: my friend just wanted to play and have fun. These dialogs were getting in the way! However, the game is entirely possible to play and enjoy without knowing every little intricate detail --- it's a 'casual' game after all.</p> <p>All good software is like this. You should be able to dive in and use the program without reading anything. Your power users---the ones who use your program everyday---will know it's advantageous to learn as many shortcuts and tips as possible, so they can complete their tasks faster. They are the ones who might end up reading the information you throw at them (though it's still not a certainty). Your occasional user, on the other hand, wants to get their task done as soon as possible, because they have other things to do. You may assume they will not read anything you throw at them that is over two sentences long.</p> <p>The most surprising thing to me was that those game dialogs were not close to being long. They were well under the "typical-users-see-nothing-past-this-word" limit and they still didn't get read. To me that implies that the only words you can assume will always get read are the words on the buttons themselves. Is your software still usable if all your explanatory text is missing?</p> <p>Perhaps, since users read the text on buttons, you could somehow associate explanatory text with a button? I suspect the new <a href="http://msdn.microsoft.com/en-us/library/aa511299.aspx">Task Dialogs</a> in Windows Vista were developed with this in mind: they use massive buttons and associate explanatory text with a button. It's unfortunate that they weren't introduced earlier, as the main reason you so often see simple "Yes / No" or "OK / Cancel" dialogs in Windows applications is they are really simple to code:</p> <div class="codehilite"><pre><span class="n">MessageBox</span><span class="p">(</span><span class="n">hWnd</span><span class="p">,</span> <span class="s">&quot;Isn&#39;t this easy?&quot;</span><span class="p">,</span> <span class="s">&quot;Yet Another Windows Application&quot;</span><span class="p">,</span> <span class="n">MB_YESNO</span><span class="p">);</span> </pre></div> <p>A task dialog type affair (pre-Vista), on the other hand, requires separate templates for each dialog or creating an indirect dialog (on the fly, with lots of simple but tedious math). Both of these approaches take infinitely longer to write.</p> <p>If you really care about usability, though, perhaps it's time well spent.</p>richardwbWed, 25 Feb 2009 14:42:00 -0800tag:www.setnode.com,2009-02-25:blog/remember-that-users-do-not-read/lighttpd tipshttp://www.setnode.com/blog/lighttpd-tips/<p><a href="http://www.lighttpd.net/">lighttpd</a> is a web server that is optimized for speed. It is particularly adept at serving static content. Since most web hosts provide Apache and most web applications assume you are running on Apache (which is why web hosts provide Apache and why web applications assume you use Apache and why web hosts provide Apache and ...) it can take a bit more effort to find lighttpd documentation.</p> <p>Some little things that I have picked up for lighttpd:</p> <p>lighttpd version:</p> <div class="codehilite"><pre>&gt; lighttpd -v </pre></div> <p>lighttpd version and supported features: <em>(note: that is a capital V)</em></p> <div class="codehilite"><pre>&gt; lighttpd -V </pre></div> <p><br /></p> <p>Using Apache to forward requests to lighttpd? Lighttpd will see that all incoming requests have the IP of the Apache proxy. There is a module <a href="http://redmine.lighttpd.net/projects/lighttpd/wiki/DocsModExtForward"><code>mod_extforward</code></a> which will extract a real IP from the <code>X-Forwarded-For</code> header. Add these lines in the appropriate locations to your <code>lighttpd.conf</code> file:</p> <div class="codehilite"><pre><span class="k">server.modules</span> <span class="o">=</span> <span class="p">(</span> <span class="k">...</span> <span class="c1"># (other modules)</span> <span class="s2">&quot;mod_extforward&quot;</span><span class="p">,</span> <span class="c1"># change x-forwarded-for IPs into real IPs, </span> <span class="c1"># load after mod_accesslog</span> <span class="p">)</span> <span class="k">extforward.forwarder</span> <span class="o">=</span> <span class="p">(</span> <span class="s2">&quot;127.0.0.1&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;trust&quot;</span> <span class="c1"># where 127.0.0.1 is the IP address of the proxy</span> <span class="p">)</span> </pre></div> <p><br /></p> <p>You can use variables in <code>lighttpd.conf</code>:</p> <div class="codehilite"><pre><span class="k">server.username</span> <span class="o">=</span> <span class="s2">&quot;myusername&quot;</span> <span class="c1"># lighttpd configuration option</span> <span class="k">var.basedir</span> <span class="o">=</span> <span class="s2">&quot;/users/home/&quot;</span> <span class="o">+</span> <span class="k">server.username</span> <span class="c1"># declares a variable called &lt;em&gt;basedir&lt;/em&gt;</span> <span class="k">server.document-root</span> <span class="o">=</span> <span class="k">basedir</span> <span class="o">+</span> <span class="s2">&quot;/www/&quot;</span> <span class="c1"># equal to &lt;em&gt;/users/home/myusername/www/&lt;/em&gt;</span> </pre></div> <p><br /></p> <p>Set a different <code>server.document-root</code> depending on the host:</p> <div class="codehilite"><pre><span class="nb">$HTTP</span><span class="p">[</span><span class="s2">&quot;host&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;www.example.org&quot;</span> <span class="p">{</span> <span class="k">server.document-root</span> <span class="o">=</span> <span class="k">basedir</span> <span class="o">+</span> <span class="s2">&quot;/www/www.example.org/&quot;</span> <span class="c1"># basedir is our variable</span> <span class="p">}</span> </pre></div> <p><br /></p> <p>Redirect people to a single canonical web address (in this example <code>http://example.org/blog/candy-is-yummy</code> will redirect to <code>http://www.example.org/blog/candy-is-yummy</code>):</p> <div class="codehilite"><pre><span class="c1"># make sure to include the mod_redirect module</span> <span class="nb">$HTTP</span><span class="p">[</span><span class="s2">&quot;host&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;example.org&quot;</span> <span class="p">{</span> <span class="c1"># if host matches &quot;example.org&quot; then...</span> <span class="k">url.redirect</span> <span class="o">=</span> <span class="p">(</span> <span class="c1"># if the URL matches ^/(.*)$</span> <span class="s2">&quot;^/(.*)$&quot;</span> <span class="o">=&gt;</span> <span class="s2">&quot;http://www.example.org/$1&quot;</span> <span class="c1"># redirect to http://www.example.org/$1</span> <span class="p">)</span> <span class="c1"># where $1 is what was captured by the</span> <span class="p">}</span> <span class="c1"># the parenthesis (.*)</span> </pre></div> <p><code>^/(.*)$</code> is an example of a <a href="http://en.wikipedia.org/wiki/Regular_expression">regular expression</a>. Specifically, lighttpd uses <a href="http://en.wikipedia.org/wiki/Perl_Compatible_Regular_Expressions"><abbr title="Perl Compatible Regular Expressions">PCRE</abbr></a>. Instead of equality, <code>==</code>, you can also test for inequality with <code>!=</code>. If you want to use regular expressions in the match conditional, you can use <code>=~</code> and <code>!~</code> for equality and inequality respectively (this is useful for paths):</p> <div class="codehilite"><pre><span class="c1"># make sure to include the mod_access module</span> <span class="nb">$HTTP</span><span class="p">[</span><span class="s2">&quot;host&quot;</span><span class="p">]</span> <span class="o">==</span> <span class="s2">&quot;www.example.org&quot;</span> <span class="p">{</span> <span class="k">server.document-root</span> <span class="o">=</span> <span class="k">basedir</span> <span class="o">+</span> <span class="s2">&quot;/www/www.example.org/&quot;</span> <span class="nb">$HTTP</span><span class="p">[</span><span class="s2">&quot;url&quot;</span><span class="p">]</span> <span class="o">=~</span> <span class="s2">&quot;^/private/&quot;</span> <span class="p">{</span> <span class="c1"># if url starts with /private then...</span> <span class="k">url.access-deny</span> <span class="o">=</span> <span class="p">(</span><span class="s2">&quot;&quot;</span><span class="p">)</span> <span class="c1"># deny access to URLs that end with &quot;&quot;</span> <span class="p">}</span> <span class="c1"># (i.e. deny access to all URLs)</span> <span class="p">}</span> </pre></div> <p>If you use the regexp conditionals remember that many symbols have a special meaning. The '<code>.</code>' (period) is a common example, as it has the special meaning of "match any single character". You can <a href="http://en.wikipedia.org/wiki/Escape_character">escape</a> it by prepending a backslash: '<code>\.</code>'</p>richardwbMon, 09 Feb 2009 16:32:00 -0800tag:www.setnode.com,2009-02-09:blog/lighttpd-tips/What is duck typing?http://www.setnode.com/blog/what-is-duck-typing/<p>I found that when I started dabbling in Python that it was a bit hard to get a grasp on what duck typing actually is. You hear that it achieves polymorphism without inheritance, but that really explains very little. I have a C++/Java/C# background and it took a bit of time before that wonderful epiphany came, where all of a sudden I seemed to get a good grasp on what the concept actually is.</p> <p>From the <a href="http://en.wikipedia.org/wiki/Duck_typing">Duck typing article on Wikipedia</a> we find that the term comes from the phrase "<em>If it walks like a duck and quacks like a duck, I would call it a duck.</em>"</p> <p>That makes perfect sense now, but it definitely didn't help further my understanding when I first came across it.</p> <p>Perhaps the best way to explain would be with some code. I'm using Java here because it's wordy enough that it's understandable even if you don't know the syntax. For this "real world" example we will be designing that ever so classic "real world application of object oriented programming": the hierarchy of vehicles.</p> <p>So suppose we have an existing <code>Driver</code> class that will drive our vehicles for us, as long as we provide the <code>gas()</code>, <code>brake()</code>, <code>turnLeft()</code> and <code>turnRight()</code> methods. In Java this would likely be expressed as an interface:</p> <div class="codehilite"><pre><span class="kd">public</span> <span class="kd">interface</span> <span class="nc">IDriveable</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">gas</span><span class="o">();</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">brake</span><span class="o">();</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">turnLeft</span><span class="o">();</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">turnRight</span><span class="o">();</span> <span class="o">}</span> </pre></div> <p>And then we would have a class that implements that interface, for example:</p> <div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Car</span> <span class="kd">implements</span> <span class="n">IDriveable</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">gas</span><span class="o">()</span> <span class="o">{</span> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&quot;Vroom vroom&quot;</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">brake</span><span class="o">()</span> <span class="o">{</span> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&quot;Screeeechhhh!&quot;</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">turnLeft</span><span class="o">()</span> <span class="o">{</span> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&quot;Left&quot;</span><span class="o">);</span> <span class="o">}</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">turnRight</span><span class="o">()</span> <span class="o">{</span> <span class="n">System</span><span class="o">.</span><span class="na">out</span><span class="o">.</span><span class="na">println</span><span class="o">(</span><span class="s">&quot;Right&quot;</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </pre></div> <p>And the <code>Driver</code> class would be similar to:</p> <div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Driver</span> <span class="o">{</span> <span class="kd">public</span> <span class="kt">void</span> <span class="nf">drive</span><span class="o">(</span><span class="n">IDriveable</span> <span class="n">vehicle</span><span class="o">)</span> <span class="o">{</span> <span class="n">vehicle</span><span class="o">.</span><span class="na">gas</span><span class="o">();</span> <span class="n">vehicle</span><span class="o">.</span><span class="na">turnLeft</span><span class="o">();</span> <span class="n">vehicle</span><span class="o">.</span><span class="na">brake</span><span class="o">();</span> <span class="o">}</span> <span class="o">}</span> </pre></div> <p>And the main class:</p> <div class="codehilite"><pre><span class="kd">public</span> <span class="kd">class</span> <span class="nc">Start</span> <span class="o">{</span> <span class="kd">public</span> <span class="kd">static</span> <span class="kt">void</span> <span class="nf">main</span><span class="o">(</span><span class="n">String</span><span class="o">[]</span> <span class="n">args</span><span class="o">)</span> <span class="o">{</span> <span class="n">Car</span> <span class="n">c</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Car</span><span class="o">();</span> <span class="n">Driver</span> <span class="n">d</span> <span class="o">=</span> <span class="k">new</span> <span class="n">Driver</span><span class="o">();</span> <span class="n">d</span><span class="o">.</span><span class="na">drive</span><span class="o">(</span><span class="n">c</span><span class="o">);</span> <span class="o">}</span> <span class="o">}</span> </pre></div> <p>Sample output:</p> <div class="codehilite"><pre>Vroom vroom Left Screeeechhhh! </pre></div> <p>This is standard OOP stuff, where as long as our class implements the <code>IDriveable</code> interface, it'll be driveable by the <code>Driver</code> class. If the class does not implement that interface, the code will not even compile.</p> <p>If we bring duck typing into the picture, things change. Instead of having a defined interface (<code>IDriveable</code>) which must be implemented, all we require is that a given class implements the specific methods needed. There is no strict interface. In Python our code would look like:</p> <div class="codehilite"><pre><span class="k">class</span> <span class="nc">Car</span><span class="p">:</span> <span class="k">def</span> <span class="nf">gas</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;Vroom vroom&quot;</span> <span class="k">def</span> <span class="nf">brake</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;Screeeechhhh!&quot;</span> <span class="k">def</span> <span class="nf">turnLeft</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;Left&quot;</span> <span class="k">def</span> <span class="nf">turnRight</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;Right&quot;</span> <span class="k">class</span> <span class="nc">Driver</span><span class="p">:</span> <span class="k">def</span> <span class="nf">drive</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">vehicle</span><span class="p">):</span> <span class="n">vehicle</span><span class="o">.</span><span class="n">gas</span><span class="p">()</span> <span class="n">vehicle</span><span class="o">.</span><span class="n">turnLeft</span><span class="p">()</span> <span class="n">vehicle</span><span class="o">.</span><span class="n">brake</span><span class="p">()</span> <span class="n">c</span> <span class="o">=</span> <span class="n">Car</span><span class="p">()</span> <span class="n">d</span> <span class="o">=</span> <span class="n">Driver</span><span class="p">()</span> <span class="n">d</span><span class="o">.</span><span class="n">drive</span><span class="p">(</span><span class="n">c</span><span class="p">)</span> </pre></div> <p>Which produces the same output as above.</p> <p>Let's add a new class to the Python code:</p> <div class="codehilite"><pre><span class="k">class</span> <span class="nc">Pencil</span><span class="p">:</span> <span class="k">def</span> <span class="nf">gas</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;Scribble scribble&quot;</span> <span class="k">def</span> <span class="nf">turnLeft</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;Left pencil turn?&quot;</span> <span class="c"># note that turnRight is missing!</span> <span class="k">def</span> <span class="nf">brake</span><span class="p">(</span><span class="bp">self</span><span class="p">):</span> <span class="k">print</span> <span class="s">&quot;PUT YOUR PENCILS DOWN&quot;</span> </pre></div> <p>Although <code>Pencil</code> having these methods makes absolutely no sense, we could pass this to the <code>drive()</code> method and there will be no errors. Yep, even though <code>Pencil</code> doesn't implement <code>turnRight()</code>, because <code>turnRight()</code> is never called, all this code will run, error free!</p> <p>We have a <code>Pencil</code> that can <code>gas()</code>, <code>turnLeft()</code>, and <code>brake()</code>, just like a <code>Car</code>. What is the difference between them, as far as this code is concerned? None!</p> <p>This is what duck typing is. If a class acts like another class, it can substitute for that class. There's no need for there to be strictly defined relationships between classes.</p>richardwbTue, 27 Jan 2009 14:12:00 -0800tag:www.setnode.com,2009-01-27:blog/what-is-duck-typing/MapVirtualKey(), GetKeyNameText(), and a story of how to get proper names for the arrow keyshttp://www.setnode.com/blog/mapvirtualkey-getkeynametext-and-a-story-of-how-to/<p>So let's say you are currently storing and using virtual key codes to handle keyboard input for a game. You decide to let your users customize their keys, so you go ahead and write some key configuration code. This requires that you map virtual key codes to key names.</p> <p>Luckily, Windows provides some functions that do exactly what you want! Essentially you use <code>MapVirtualKey()</code> to get a scancode for that key and then pass that scancode (left-shifted by 16) into <code>GetKeyNameText()</code>.</p> <p>Some minutes later you finish your code and you go to test it. You hit the A key and you see 'A'. The 5 key outputs '5'. Even the Backspace key outputs 'Backspace'. It works as expected.</p> <p>Then you hit one of the arrow keys and your code spits out 'Num 8'. It's right yet it's wrong.</p> <p><a href="http://blogs.msdn.com/michkap/archive/2006/08/29/729476.aspx">Michael Kaplan has a blog entry</a> that describes a recent update to the <code>MapVirtualKeyEx()</code> call:</p> <blockquote> <p>MAPVK_VK_TO_VSC_EX:</p> <p><strong>Windows Vista and later</strong>: The uCode parameter is a virtual-key code and is translated into a scan code. If it is a virtual-key code that does not distinguish between left- and right-hand keys, the left-hand scan code is returned. If the scan code is an extended scan code, the high byte of the uCode value can contain either 0xe0 or 0xe1 to specify the extended scan code. If there is no translation, the function returns 0.</p> </blockquote> <p>Unfortunately this doesn't help much as Windows XP is still used by a majority of users. However, this does imply that the current <code>MapVirtualKey[Ex]()</code> call does not specify the extended scan code. So if we just set the extended bit for some characters we may end up with a function similar to this:</p> <div class="codehilite"><pre><span class="n">std</span><span class="o">::</span><span class="n">string</span> <span class="n">GetKeyName</span><span class="p">(</span><span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">virtualKey</span><span class="p">)</span> <span class="p">{</span> <span class="kt">unsigned</span> <span class="kt">int</span> <span class="n">scanCode</span> <span class="o">=</span> <span class="n">MapVirtualKey</span><span class="p">(</span><span class="n">virtualKey</span><span class="p">,</span> <span class="n">MAPVK_VK_TO_VSC</span><span class="p">);</span> <span class="c1">// because MapVirtualKey strips the extended bit for some keys</span> <span class="k">switch</span> <span class="p">(</span><span class="n">virtualKey</span><span class="p">)</span> <span class="p">{</span> <span class="k">case</span> <span class="n">VK_LEFT</span>: <span class="k">case</span> <span class="n">VK_UP</span>: <span class="k">case</span> <span class="n">VK_RIGHT</span>: <span class="k">case</span> <span class="n">VK_DOWN</span>: <span class="c1">// arrow keys</span> <span class="k">case</span> <span class="n">VK_PRIOR</span>: <span class="k">case</span> <span class="n">VK_NEXT</span>: <span class="c1">// page up and page down</span> <span class="k">case</span> <span class="n">VK_END</span>: <span class="k">case</span> <span class="n">VK_HOME</span>: <span class="k">case</span> <span class="n">VK_INSERT</span>: <span class="k">case</span> <span class="n">VK_DELETE</span>: <span class="k">case</span> <span class="n">VK_DIVIDE</span>: <span class="c1">// numpad slash</span> <span class="k">case</span> <span class="n">VK_NUMLOCK</span>: <span class="p">{</span> <span class="n">scanCode</span> <span class="o">|=</span> <span class="mh">0x100</span><span class="p">;</span> <span class="c1">// set extended bit</span> <span class="k">break</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="kt">char</span> <span class="n">keyName</span><span class="p">[</span><span class="mi">50</span><span class="p">];</span> <span class="k">if</span> <span class="p">(</span><span class="n">GetKeyNameText</span><span class="p">(</span><span class="n">scanCode</span> <span class="o">&amp;</span><span class="n">lt</span><span class="p">;</span><span class="o">&amp;</span><span class="n">lt</span><span class="p">;</span> <span class="mi">16</span><span class="p">,</span> <span class="n">keyName</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">keyName</span><span class="p">))</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">return</span> <span class="n">keyName</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="k">return</span> <span class="s">&quot;[Error]&quot;</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> </pre></div>richardwbSat, 20 Dec 2008 14:50:00 -0800tag:www.setnode.com,2008-12-20:blog/mapvirtualkey-getkeynametext-and-a-story-of-how-to/std::map access violation (or not)http://www.setnode.com/blog/std-map-access-violation-or-not/<p>I just spent some time tracking down this fun little bug:</p> <p>I use a mix of <tt class="docutils literal"><span class="pre">std::map</span></tt> and <tt class="docutils literal">Boost.Function</tt> to reduce the ugliness of the Windows message loop. Everything is working just fine, until I make a couple of changes and all of a sudden one of my <tt class="docutils literal"><span class="pre">std::map</span></tt>s is throwing an exception in the destructor:</p> <div class="highlight"><pre>Access violation reading location 0xccccccd4. </pre></div> <p>In this code in <tt class="docutils literal">xtree</tt>:</p> <div class="highlight"><pre><span class="cp">#if _HAS_ITERATOR_DEBUGGING</span> <span class="kt">void</span> <span class="nf">_Orphan_ptr</span><span class="p">(</span><span class="n">_Myt</span><span class="o">&amp;</span> <span class="n">_Cont</span><span class="p">,</span> <span class="n">_Nodeptr</span> <span class="n">_Ptr</span><span class="p">)</span> <span class="k">const</span> <span class="p">{</span> <span class="c1">// orphan iterators with specified node pointers</span> <span class="n">_Lockit</span> <span class="n">_Lock</span><span class="p">(</span><span class="n">_LOCK_DEBUG</span><span class="p">);</span> <span class="n">const_iterator</span> <span class="o">**</span><span class="n">_Pnext</span> <span class="o">=</span> <span class="p">(</span><span class="n">const_iterator</span> <span class="o">**</span><span class="p">)</span><span class="o">&amp;</span><span class="n">_Cont</span><span class="p">.</span><span class="n">_Myfirstiter</span><span class="p">;</span> <span class="k">while</span> <span class="p">(</span><span class="o">*</span><span class="n">_Pnext</span> <span class="o">!=</span> <span class="mi">0</span><span class="p">)</span> <span class="p">{</span> <span class="k">if</span> <span class="p">((</span><span class="o">*</span><span class="n">_Pnext</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">_Ptr</span> <span class="o">==</span> <span class="n">_Myhead</span> <span class="hll"> <span class="o">||</span> <span class="n">_Ptr</span> <span class="o">!=</span> <span class="mi">0</span> <span class="o">&amp;&amp;</span> <span class="p">(</span><span class="o">*</span><span class="n">_Pnext</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">_Ptr</span> <span class="o">!=</span> <span class="n">_Ptr</span><span class="p">)</span> </span> <span class="p">{</span> <span class="n">_Pnext</span> <span class="o">=</span> <span class="p">(</span><span class="n">const_iterator</span> <span class="o">**</span><span class="p">)</span><span class="o">&amp;</span><span class="p">(</span><span class="o">*</span><span class="n">_Pnext</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">_Mynextiter</span><span class="p">;</span> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span> <span class="c1">// orphan the iterator</span> <span class="p">(</span><span class="o">*</span><span class="n">_Pnext</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">_Mycont</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span> <span class="o">*</span><span class="n">_Pnext</span> <span class="o">=</span> <span class="p">(</span><span class="n">const_iterator</span> <span class="o">*</span><span class="p">)(</span><span class="o">*</span><span class="n">_Pnext</span><span class="p">)</span><span class="o">-&gt;</span><span class="n">_Mynextiter</span><span class="p">;</span> <span class="p">}</span> <span class="p">}</span> <span class="p">}</span> <span class="cp">#endif </span><span class="cm">/* _HAS_ITERATOR_DEBUGGING */</span><span class="cp"></span> </pre></div> <p>Of course, that is suspiciously close to <tt class="docutils literal">0xcccccccc</tt>, which is used by the debugging runtimes to mark uninitalized stack. (This will be important later.) In any case I go through the usual debugging motions, making sure I'm not putting anything funny into my map container and that values inside the container are what they should be.</p> <p>So, what was the cause of this bug? It was a result of the change I was making earlier; this is the original code:</p> <div class="highlight"><pre><span class="n">LVITEM</span> <span class="n">itemText</span><span class="p">;</span> <span class="n">ZeroMemory</span><span class="p">(</span><span class="o">&amp;</span><span class="n">itemText</span><span class="p">,</span> <span class="k">sizeof</span><span class="p">(</span><span class="n">itemText</span><span class="p">));</span> <span class="n">itemText</span><span class="p">.</span><span class="n">cchTextMax</span> <span class="o">=</span> <span class="n">MAX_PATH</span><span class="p">;</span> <span class="kt">char</span> <span class="n">buff</span><span class="p">[</span><span class="n">MAX_PATH</span><span class="p">];</span> <span class="n">itemText</span><span class="p">.</span><span class="n">pszText</span> <span class="o">=</span> <span class="n">buff</span><span class="p">;</span> <span class="n">SendMessage</span><span class="p">(</span><span class="n">listViewHandle</span><span class="p">,</span> <span class="n">LVM_GETITEMTEXT</span><span class="p">,</span> <span class="n">index</span><span class="p">,</span> <span class="k">reinterpret_cast</span><span class="o">&lt;</span><span class="n">LPARAM</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">itemText</span><span class="p">));</span> </pre></div> <p>And I changed it to use the <tt class="docutils literal">ListView_GetItemText</tt> macro, which is far more succinct:</p> <div class="highlight"><pre><span class="kt">char</span> <span class="n">itemText</span><span class="p">[</span><span class="n">MAX_PATH</span><span class="p">];</span> <span class="n">ListView_GetItemText</span><span class="p">(</span><span class="n">listViewHandle</span><span class="p">,</span> <span class="n">index</span><span class="p">,</span> <span class="mi">0</span><span class="p">,</span> <span class="n">itemText</span><span class="p">,</span> <span class="n">_countof</span><span class="p">(</span><span class="n">itemText</span><span class="p">));</span> </pre></div> <p>No problem yet, right? Ready for the punchline?</p> <p><em>I left this line in at the bottom:</em></p> <div class="highlight"><pre><span class="n">SendMessage</span><span class="p">(</span><span class="n">listViewHandle</span><span class="p">,</span> <span class="n">LVM_GETITEMTEXT</span><span class="p">,</span> <span class="n">index</span><span class="p">,</span> <span class="k">reinterpret_cast</span><span class="o">&lt;</span><span class="n">LPARAM</span><span class="o">&gt;</span><span class="p">(</span><span class="o">&amp;</span><span class="n">itemText</span><span class="p">));</span> </pre></div> <p>For those lucky folks who aren't familiar with all the wonderful intricacies of Windows programming:</p> <p><tt class="docutils literal">SendMessage()</tt> is a magical &quot;do all&quot; function that sends a message to a particular window, with <tt class="docutils literal">WPARAM</tt> and <tt class="docutils literal">LPARAM</tt> values tagging along. In this case, we're sending a message of <tt class="docutils literal">LVM_GETITEMTEXT</tt> to the control denoted by <tt class="docutils literal">listViewHandle</tt>. The MSDN documentation for <tt class="docutils literal">LVM_GETITEMTEXT</tt> states that it wants <tt class="docutils literal">WPARAM</tt> and <tt class="docutils literal">LPARAM</tt> to be:</p> <blockquote> <div class="line-block"> <div class="line">WPARAM : iItem - Index of the list-view item</div> <div class="line"><strong>LPARAM : pitem - Pointer to an LVITEM structure.</strong></div> </div> </blockquote> <p>My <tt class="docutils literal">LPARAM</tt>, <tt class="docutils literal">itemText</tt>, is no longer an <tt class="docutils literal">LVITEM</tt> structure (it is now a char array of size <tt class="docutils literal">MAX_PATH</tt>). There is absolutely no way that the <tt class="docutils literal">LVM_GETITEMTEXT</tt> code can know that I've made a colossal (yet tiny!) mistake, so I assume that it dutifully casts <tt class="docutils literal">itemText</tt> into an <tt class="docutils literal">LVITEM</tt> structure and does the right stuff with horrendously wrong data. Tada, stack corrupted.</p> <p>Notice that the source of this bug appears nowhere near an <tt class="docutils literal"><span class="pre">std::map</span></tt>. It is, in fact, in a different function (and a different class and a different file...) entirely! This is why memory corruption errors are one of the most feared bugs around.</p> <p>Conclusion: if <tt class="docutils literal"><span class="pre">std::map</span></tt> is dying in <tt class="docutils literal">clear()</tt> (or ever, frankly), you may very well be doing something bad, memory wise.</p> richardwbSat, 11 Oct 2008 18:42:00 -0700tag:www.setnode.com,2008-10-11:blog/std-map-access-violation-or-not/Proctors in Calgaryhttp://www.setnode.com/blog/proctors-in-calgary/<p>"Proctor" is the fancy word for those people who administer exams and tests. If you're taking distance education courses, you may need to find one. I had to find a proctor a year ago to make up for an exam I missed, and it took some time to figure out how to even begin. (A search for "calgary proctors" did not bring up very much...)</p> <p>I finally found some information on proctors by calling the librarians at the <a href="http://newcpl.calgarypubliclibrary.com/Branches.aspx?id=2">Castell Central Library</a>. So...my tip for finding a proctor is to call the library in your city.</p> <p>In case there are any other Calgarians who need a proctor, here’s some information on proctors from <strong>2005</strong>, along with per exam proctor fees:</p> <table><tbody><tr> <td>Athabasca University</td> <td>(403) 263-6465</td> <td>$40</td> </tr><tr> <td>University of Calgary</td> <td>(403) 220-5524</td> <td>$80</td> </tr><tr> <td>SAIT</td> <td>(403) 210-4283</td> <td>$50</td> </tr><tr> <td>Rocky Mountain College</td> <td>(403) 284-5100</td> <td>$20</td> </tr></tbody></table>richardwbTue, 11 Jul 2006 16:24:00 -0700tag:www.setnode.com,2006-07-11:blog/proctors-in-calgary/Linksys BEFSR81 disconnectshttp://www.setnode.com/blog/linksys-befsr81-disconnects/<p>For the longest time I had this constant problem with my router, a Linksys BEFSR81 (the 8-port version of the BEFSR41) constantly disconnecting the computers connected to it. It wasn’t the Internet connection going down, since I had a computer that was directly connected to the modem as well, and it never had any problems.</p> <p>So of course when troubleshooting something like a router, you go and get the latest firmware. No luck there. I also tried resetting the router, restoring default settings, changing the ports used on the back, and so on.</p> <p>Finally, I tried giving one computer DMZ access (I’m not forgetting about the security concerns raised by doing this). It worked. No more disconnections for that computer, and for now, I’m satisfied.</p> <p>Posting this in case it comes in handy for anyone else experiencing disconnection problems.</p> <p>[2008 Addendum: The only real solution to this problem is to get a better router. The BEFSR81 is at least 7 years old now.]</p>richardwbTue, 11 Jul 2006 12:46:00 -0700tag:www.setnode.com,2006-07-11:blog/linksys-befsr81-disconnects/University of Waterloo cheershttp://www.setnode.com/blog/university-of-waterloo-cheers/<p>Here are some cheers from the University of Waterloo Math orientation (which I went through 4 years ago). These include such classics as <em>Math Rocks</em>, <em>The Biggest Tie</em>, <em>How's the Tie</em>, and <em>Water Water Water</em>. I'm not sure why, but my personal favorite is <em>The Biggest Tie</em>.</p> <blockquote> <h3><em>Math Rocks</em></h3> <p>M-A<br /> M-A-T<br /> M-A-T-H<br /> Math Rocks! </p> <p>Say it loud<br /> Say it big<br /> Let it boil in your blood, feel it zag as you zig<br /> We survive<br /> All the knocks<br /> We have pride when we cheer and we think Math Rocks! </p> </blockquote> <p>One group chants the first verse while the other group chants the second verse, at the same time. The chants should converge on the phrase "Math Rocks!".</p> <blockquote> <h3><em>The Biggest Tie</em></h3> <p>The biggest tie<br /> I ever saw<br /> Was hanging from<br /> The MC wall </p> <p>I looked at it<br /> And then I knew<br /> I wanted to be<br /> A Mathie too </p> <p>I stole the tie<br /> It made me laugh<br /> Because it's true<br /> That I love Math </p> <p>And so began<br /> My new journey<br /> To be part of<br /> Math faculty </p> <p>My school is sweet<br /> SWEET LIKE A FOX!<br /> Because I know<br /> UW Math Rocks </p> </blockquote> <p>Sung to the tune and style of The Littlest Worm, The Princess Pat, or I Met a Bear.</p> <blockquote> <h3><em>Water Water Water</em></h3> <p>Water water water!<br /> Loo loo loo!<br /> Water water water!<br /> Loo loo loo!<br /> Water!<br /> Loo!<br /> Water!<br /> Loo!<br /> Water water water!<br /> Loo loo loo! </p> </blockquote> <p>One group (typically the orientation leaders) starts the cheer by yelling "Water water water!". The other group then replies with "Loo loo loo!". It continues in this fashion until the end of the cheer.</p> <p>There are more Math cheers in the <del>Math Handbook</del> <a href="http://www.orientation.math.uwaterloo.ca/2008/cheers/">Math Orientation 2008 guide</a>.</p>richardwbSun, 30 Apr 2006 17:23:00 -0700tag:www.setnode.com,2006-04-30:blog/university-of-waterloo-cheers/