{"id":6493,"date":"2007-03-16T10:52:00","date_gmt":"2007-03-16T10:52:00","guid":{"rendered":"https:\/\/blogs.msdn.microsoft.com\/vbteam\/2007\/03\/16\/coding-a-euchre-game-part-4-tooltips-and-menus-matt-gertz\/"},"modified":"2024-07-05T14:49:19","modified_gmt":"2024-07-05T21:49:19","slug":"coding-a-euchre-game-part-4-tooltips-and-menus-matt-gertz","status":"publish","type":"post","link":"https:\/\/devblogs.microsoft.com\/vbteam\/coding-a-euchre-game-part-4-tooltips-and-menus-matt-gertz\/","title":{"rendered":"Coding a Euchre Game, Part 4: Tooltips and Menus (Matt Gertz)"},"content":{"rendered":"<h2><font size=\"5\"><font color=\"#365f91\"><font face=\"Cambria\">Coding a Euchre Game, <span>Part 4: Tooltips and Menus<\/span><\/font><\/font><\/font><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Menus and tooltips are so incredibly important to applications, and yet implementing them sometimes seems to be arcane magic.<span>&nbsp; <\/span>In this post, I\u2019m going to do my best to demystify them.<\/font><\/p>\n<h2><font face=\"Cambria\" color=\"#4f81bd\" size=\"4\">Menus<\/font><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">To add a menu, you simply drag a MenuStrip control from the toolbox to your form.<span>&nbsp; <\/span>As with the Timer control from the last post, the control will end up in the grey area at the bottom of the form; however, there will also be a visible component at the top of the form.<span>&nbsp; <\/span>Use the former to change the name of the control, but mostly you\u2019ll be working with the visual instance at the top.<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Now, if you wanted to quickly add a whole set of standard menu items such as File, Edit, Tools, etc., you could click on the smart tag in the upper-right corner of the menustrip and choose \u201cInsert Standard Menu Items,\u201d thus populating the menu with those menus automatically.<span>&nbsp; <\/span>However, we don\u2019t want standard menus for this game, as most of the menu items would not be relevant.<span>&nbsp; <\/span>Instead, place your cursor in the editbox on the menustrip and type \u201c&amp;VBEuchre.\u201d<span>&nbsp; <\/span>This creates a Drop-down menu called <b><u>V<\/u>BEuchre<\/b>. Note how the ampersand (&amp;) forces the following character to be underlined!<span>&nbsp; <\/span>That\u2019s the character that will automatically be used when navigating with the ALT key.<span>&nbsp; <\/span>You can also add commands under the \u201cVBEuchre\u201d menu item by typing into the edit boxes.<span>&nbsp; <\/span>You can specify ALT mnemonics using the ampersand character, or can assign key shortcuts by selecting the menu item and setting its various ShortcutKey properties.<span>&nbsp; <\/span>You can even define secondary tiers of menus, though we won\u2019t be doing that for this game.&nbsp; The attached picture shows what menu-editing looks like.<\/font><\/p>\n<p class=\"MsoNormal\" align=\"center\"><span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Adding command handlers to menu items is identical to adding them to any other control \u2013 just double-click them to create the handler and then add your code to it.<span>&nbsp; <\/span>For \u201cNew Game,\u201d this Is very simple:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> NewGameToolStripMenuItem_Click(<span>ByVal<\/span> sender _<\/span><\/p>\n<p class=\"MsoNormal\"><span>As<\/span><span> System.Object, <span>ByVal<\/span> e <span>As<\/span> System.EventArgs) _<\/span><\/p>\n<p class=\"MsoNormal\"><span>Handles<\/span><span> NewGameToolStripMenuItem.Click<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>NewGame()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">NewGame() then has to check to see if a game is already under way, and pops up a \u201cDo you want to quit your current game?\u201d messagebox if so:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Sub<\/span> NewGame()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> GameStarted = <span>True<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> MessageBox.Show(<span>My<\/span>.Resources.Command_New,_<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span><span>My<\/span>.Resources.Command_NewTitle, MessageBoxButtons.OKCancel, _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span>MessageBoxIcon.Question, MessageBoxDefaultButton.Button2) &lt;&gt; _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span>Windows.Forms.DialogResult.OK <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> InvokedOnce = <span>False<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>NewGameInvoked()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Else<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; NewGameInvoked is already on the stack.<span>&nbsp; <\/span>We don&#8217;t want to recurse into it.<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Throw back up to that method so it can restart itself.<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>newEuchre = <span>True<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">Note that<span>&nbsp;my variables&nbsp;<\/span>\u201cGameStarted\u201d and \u201cInvokedOnce\u201d are checking two different things.<span>&nbsp; <\/span>\u201cGameStarted\u201d means that play is actually happening.<span>&nbsp; <\/span>\u201cInvokedOnce\u201d is simply a re-entrancy check \u2013 the gameplay might not have started yet, but the user might nevertheless be involved in other code in NewGameInvoked such as setting the options or whatever.<span>&nbsp; <\/span>(In other words, if GameStarted is True, then InvokedOnce must be True, but the converse is not necessarily true.)<span>&nbsp; <\/span>The \u201cnewEuchre\u201d variable will be used exactly like the \u201cexitEuchre\u201d variable from the previous post \u2013 it causes the timer to be turned off and an exception to be thrown to start a new game, so those methods now become:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> TableSleep()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>StopPumpingMessagesDuringPause = <span>False<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>EuchreTimer.Start()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>While<\/span> StopPumpingMessagesDuringPause = <span>False<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Application.DoEvents()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>While<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> exitEuchre = <span>True<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Throw<\/span> <span>New<\/span> EuchreException(<span>&#8220;ExitGame&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> newEuchre = <span>True<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Throw<\/span> <span>New<\/span> EuchreException(<span>&#8220;NewGame&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Private<\/span> <span>Sub<\/span> NewGameInvoked()<\/span><\/p>\n<p class=\"MsoNormal\"><span>Begin: <span>Try<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Do<\/span> <span>While<\/span> exitEuchre = <span>False<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span>&#8216; (this is where the game actually happens \u2013 <\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp; <\/span>I\u2019ve omitted the actual code for brevity\u2019s sake)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Loop<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Catch<\/span> ex <span>As<\/span> EuchreException<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Reset the flag and let it go back through to<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>&#8216; the loop to restart the game<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> ex.Message = <span>&#8220;NewGame&#8221;<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>newEuchre = <span>False<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>GoTo<\/span> Begin<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> ex.Message = <span>&#8220;ExitGame&#8221;<\/span> <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>exitEuchre = <span>False<\/span> <\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&#8216; Do nothing; fall through and exit the application<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Try<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Sub<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">I usually detest using GoTo statements, actually, but in this case it made sense to do so.<\/font><\/font><\/span><\/p>\n<h2><span><font size=\"4\"><font color=\"#4f81bd\"><font face=\"Cambria\">Tooltips<\/font><\/font><\/font><\/span><\/h2>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Tooltips are another control which get dragged to the form but are acted upon in the grey area.<span>&nbsp; <\/span>The only changes that need to be made to its properties are changing the name and setting AlwaysShow to True.<span>&nbsp; <\/span>It seems counterintuitive, but you only need one tooltip per form.<span>&nbsp; <\/span>This is because the tooltip keeps a list of what each control\u2019s tooltip should be.<span>&nbsp; <\/span>(This is where many people get confused \u2013 they expect the tooltip to be a property on each control, but that\u2019s not the way it works.)<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">To set a tooltip for a control is a very simple thing.<span>&nbsp; <\/span>Recall that the labels which represent the places where cards can go on the table are referenced in an array called TableTopCards.<span>&nbsp;&nbsp; <\/span>Let\u2019s pretend that a card is face down and we want to set a tooltip for it.<span>&nbsp; <\/span>The tooltip string is in the resource manager and is named CARDNAME_BACK.<span>&nbsp; <\/span>We would then set the tooltip like this:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>EuchreTooltip.SetToolTip(<span>Me<\/span>.TableTopCards(player, slot), _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>My<\/span><span>.Resources.CARDNAME_BACK)<\/span><\/p>\n<p class=\"MsoNormal\"><span>&nbsp;<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">And we could clear it like this<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span>EuchreTooltip.SetToolTip(<span>Me<\/span>.TableTopCards(player, slot), _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>Nothing<\/span><span>)<\/span><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/p>\n<p class=\"MsoNormal\"><font face=\"Calibri\" size=\"3\">Most of the tooltips resource string names in Euchre need to be constructed based on the name and suit of the card, are are thus referenced similar to the image resource names I presented several posts ago.<span>&nbsp; <\/span>However, there\u2019s a catch:<span>&nbsp; <\/span>If the Right Bower or Left Bower (the Jack of the trump suit or the Jack in the suit of the same color as the trump suit) are involved, then I want the tooltip to call them Bowers instead of their actual name, so that the user remembers that they are trump cards.<span>&nbsp; <\/span>So, we add a method in EuchreCard thusly:<\/font><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>Public<\/span> <span>Function<\/span> GetDisplayStringResourceName(<span>Optional<\/span> <span>ByVal<\/span> TrumpSuit _<\/span><\/p>\n<p class=\"MsoNormal\"><span>As<\/span><span> Suits = Suits.NoSuit) <span>As<\/span> <span>String<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> State = States.FaceUp <span>OrElse<\/span> Table.PeekAtOtherCards = <span>True<\/span> _<\/span><\/p>\n<p class=\"MsoNormal\"><span>OrElse<\/span><span> Table.SelectingDealer <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Dim<\/span> FileName <span>As<\/span> <span>New<\/span> StringBuilder()<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> TrumpSuit &lt;&gt; Suits.NoSuit <span>AndAlso<\/span> _<\/span><\/p>\n<p class=\"MsoNormal\"><span>(<span>Me<\/span>.GetValue(TrumpSuit) = Values.LeftBower _<\/span><\/p>\n<p class=\"MsoNormal\"><span>OrElse<\/span><span> <span>Me<\/span>.GetValue(TrumpSuit) = Values.RightBower) <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>If<\/span> <span>Me<\/span>.GetValue(TrumpSuit) = Values.RightBower <span>Then<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>FileName.Append(<span>&#8220;CARDNAMERightBower&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> FileName.ToString<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<\/span><span>Else<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>FileName.Append(<span>&#8220;CARDNAMELeftBower&#8221;<\/span>)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> FileName.ToString<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Else<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>FileName.AppendFormat(<span>&#8220;CARDNAME{0}Of{1}&#8221;<\/span>, Rank, Suit)<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> FileName.ToString<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Else<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>Return<\/span> <span>&#8220;CARDNAME_BACK&#8221;<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>If<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp; <\/span><span>End<\/span> <span>Function<\/span><\/span><\/p>\n<p class=\"MsoNormal\"><span><font face=\"Calibri\" size=\"3\">&nbsp;<\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">And now we use the resulting string as follows to set the tooltip for an arbitrary card at position \u201ci\u201d in the player\u2019s hand:<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <\/span>EuchreTooltip.SetToolTip(<\/span><\/p>\n<p class=\"MsoNormal\"><span>Me<\/span><span>.TableTopCards(EuchrePlayer.Seats.Player, i), _<\/span><\/p>\n<p class=\"MsoNormal\"><span><span>&nbsp;<\/span><span>My<\/span>.Resources.ResourceManager.GetString( _<\/span><\/p>\n<p class=\"MsoNormal\"><span>Players(EuchrePlayer.Seats.Player).CardsHeldThisHand(i _<\/span><\/p>\n<p class=\"MsoNormal\"><span>).GetDisplayStringResourceName))<\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\"><span>&nbsp;<\/span><\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">That\u2019s it for today.<span>&nbsp; <\/span>Next time, we\u2019ll discuss modality and user controls.<span>&nbsp; <\/span>Until then\u2026<\/font><\/font><\/span><\/p>\n<p class=\"MsoNormal\"><span><font size=\"3\"><font face=\"Calibri\">&#8211;Matt&#8211;*<\/font><\/font><\/span><\/p>\n<p><a href=\"https:\/\/devblogs.microsoft.com\/wp-content\/uploads\/sites\/7\/2019\/02\/EuchreMenuEdit.jpg\">EuchreMenuEdit.jpg<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Coding a Euchre Game, Part 4: Tooltips and Menus Menus and tooltips are so incredibly important to applications, and yet implementing them sometimes seems to be arcane magic.&nbsp; In this post, I\u2019m going to do my best to demystify them. Menus To add a menu, you simply drag a MenuStrip control from the toolbox to [&hellip;]<\/p>\n","protected":false},"author":258,"featured_media":8818,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[22,195],"tags":[101,165],"class_list":["post-6493","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-matt-gertz","category-visual-basic","tag-matt-gertz","tag-vb2005"],"acf":[],"blog_post_summary":"<p>Coding a Euchre Game, Part 4: Tooltips and Menus Menus and tooltips are so incredibly important to applications, and yet implementing them sometimes seems to be arcane magic.&nbsp; In this post, I\u2019m going to do my best to demystify them. Menus To add a menu, you simply drag a MenuStrip control from the toolbox to [&hellip;]<\/p>\n","_links":{"self":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6493","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/users\/258"}],"replies":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/comments?post=6493"}],"version-history":[{"count":0,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/posts\/6493\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media\/8818"}],"wp:attachment":[{"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/media?parent=6493"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/categories?post=6493"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/devblogs.microsoft.com\/vbteam\/wp-json\/wp\/v2\/tags?post=6493"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}