tag:blogger.com,1999:blog-60523743102294689062024-02-18T19:23:51.833-08:00Tricks, tips for Code LoversDennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.comBlogger96125tag:blogger.com,1999:blog-6052374310229468906.post-79809521687937186712010-06-19T06:00:00.000-07:002010-06-19T06:01:04.919-07:00How to remove AV Security Suite<h1><a href="http://www.spywarevoid.com/remove-av-security-suite-avsecurity-suite-removal-help.html" target="_blank">How to remove AV Security Suite</a></h1>remove procedure:<br /><br />1. Press power button to restart computer.<br />2. when window appears, ctrl+alt+delete to get task manager<br />3. remove the process:<br /><span>[random string]tssd.exe <br /><br />4.Edit host file under </span> WINDOWS\system32\drivers\etc. to block following sites:<br /><span>127.0.0.1 <a href="http://antispyprogtool.net/" target="_blank">antispyprogtool.net</a><br />127.0.0.1 <a href="http://antimalwaresecurity.net/" target="_blank">antimalwaresecurity.net</a><br />127.0.0.1 <a href="http://antispyware-guard.net/" target="_blank">antispyware-guard.net</a><br />127.0.0.1 <a href="http://threatremover.net/" target="_blank">threatremover.net</a><br />127.0.0.1 <a href="http://antispywareprog.net/" target="_blank">antispywareprog.net</a><br />127.0.0.1 <a href="http://antispantispycastle.com/" target="_blank">antispantispycastle.com</a><br /><br />5. remove registries like:<br /></span><span>HKEY_CURRENT_USER\Software\<wbr>avsoft<br /> HKEY_CURRENT_USER\Software\<wbr>avsuite<br />HKEY_LOCAL_MACHINE\SOFTWARE\<wbr>avsoft<br />HKEY_LOCAL_MACHINE\SOFTWARE\<wbr>avsuite<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Internet Explorer\Download "RunInvalidSignatures" = "1"<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Internet Explorer\PhishingFilter "Enabled" = "0"<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Windows\<wbr>CurrentVersion\Internet Settings "ProxyOverride" = ""<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Windows\<wbr>CurrentVersion\Internet Settings "ProxyServer" = "http=<a href="http://127.0.0.1:1041/" target="_blank">127.0.0.1:1041</a>"<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Windows\<wbr>CurrentVersion\Policies\<wbr>Associations "LowRiskFileTypes" = ".exe"<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Windows\<wbr>CurrentVersion\Policies\<wbr>Attachments "SaveZoneInformation" = "1"<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Windows\<wbr>CurrentVersion\Run "ouferdbubtdve"<br />HKEY_LOCAL_MACHINE\SOFTWARE\<wbr>Microsoft\Windows\<wbr>CurrentVersion\Run "ouferdbubtdve"<br />HKEY_CURRENT_USER\Software\<wbr>Microsoft\Windows\<wbr>CurrentVersion\Internet Settings "ProxyEnable" = "1" <br /><br />6. Remove folder and files:<br /></span><span>%Documents and Settings%\[UserName]\Local Settings\Application Data\[random string]\[random string]tssd.exe<br /> %Documents and Settings%\[UserName]\Local Settings\Application Data\[random string]\[random string].exe </span>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-88978996201872507532010-06-19T05:51:00.000-07:002010-06-19T05:52:51.580-07:00How to Display Chinese on Windows Mobile?<div class="im"> <h3> <a href="http://hongjun.blogspot.com/2007/12/how-to-display-chinese-on-windows.html" target="_blank">How to Display Chinese on Windows Mobile?</a><a style="text-decoration: none;" href="http://www.facebook.com/sharer.php?u=http%3A%2F%2Fhongjun.blogspot.com%2F2007%2F12%2Fhow-to-display-chinese-on-windows.html&t=hongjun%27s%20Personal%20Blog%3A%20How%20to%20Display%20Chinese%20on%20Windows%20Mobile%3F&src=sp" name="1294ff0827a5b558_1294e0c6921abc49_fb_share" rel="nofollow" type="button_count" target="_blank"><span><span><span><br /></span></span><span><span></span></span></span></a></h3> <div> </div> <p> </p> It's kinda weird as to why Microsoft does not enable displaying of 2nd language e.g. Traditional/Simplified Chinese other than English on a English Windows Mobile OS. They have done it easily on all Server/Desktop Windows and it shouldn't be too difficult to activate it on a Windows Mobile.<br /><br />To unlock and allow Chinese display on Windows Mobile, you can perform the below steps. Please note that the below is tested on Windows Mobile 6.0. However, I believe it will work on Windows Mobile 5.0 as well.<br /><br />1. <u>Download PHM Registry Editor</u><br /><br />Windows Mobile does not come together readily with a Registry Editor. Do not ask me the reason as to why the decision was made like this/that because I don't know why. Nevertheless, there is a freeware downloadable from the Internet that provides us with a GUI to "mess" with the registry. Download and install <a href="http://www.freewarepocketpc.net/ppc-download-phm-registry-editor-v0-70.html" target="_blank">PHM Registry Editor<img style="border: 0pt none ; margin: 0pt ! important; padding: 1px 0pt 0pt; max-height: 2000px; max-width: 2000px; min-width: 0px; font-style: normal; font-weight: normal; font-family: "trebuchet ms",arial,helvetica,sans-serif; float: none; line-height: normal; background-color: transparent; width: 14px; min-height: 12px; background-repeat: no-repeat; text-decoration: none; vertical-align: top; display: inline;" /></a> now. Perform a soft reset after installation.<br /><br />2. <u>Transfer font files from Desktop PC to Pocket PC</u><br /><br />Copy both <i>simsun.ttc</i> and <i>TAHOMA.TTF</i> from your Desktop PC's <i>C:\Windows\Fonts\</i> directory to Pocket PC's <i>\Windows\Fonts\</i> directory. If for whatever reason the 2 abovementioned font files are absent, do a search in the Internet and download them. Physical copying of font files from one OS to another will not pose any problems but I am not sure if there are any licensing issues.<br /><br />3. <u>Tweak Windows Mobile Registry</u><br /><br />The standard advice goes again, "Be careful when you mess with the registry". You will need <i>PHM Registry Editor</i> to assist you in changing the registry.<br /><br /></div><ol style="list-style-type: disc;"><li style="padding-bottom: 10px;">Add [<i>HKEY_LOCAL_MACHINE\Software\<wbr>Microsoft\FontPath</i>] key if it does not exist. <span style="background-color: rgb(255, 255, 102);">--dx: added</span><br /></li><li style="padding-bottom: 10px;">Add/Modify string value <i>"FontPath"="\Windows\Fonts"</i> to (i) key. Steps (i) and (ii) tell Windows Mobile the alternative font directory you are using other than the ones burnt onto the ROM. <span style="background-color: rgb(255, 255, 102);">--dx added</span><br /></li><li style="padding-bottom: 10px;">Go to [<i>HKEY_LOCAL_MACHINE\System\<wbr>GDI\SYSFNT</i>] and verify string value <i>"Nm"="Tahoma"</i>. Add/Modify where necessary. <span style="background-color: rgb(255, 255, 51);"> --dx: already there</span><br /></li><li style="padding-bottom: 10px;">Go to [<i>HKEY_LOCAL_MACHINE\Software\<wbr>Microsoft\FontLink\SystemLink</i>] and verify string value <i>"Tahoma"="\Windows\Fonts\<wbr>simsun.ttc,NSimSun"</i>. Add/Modify where necessary. Steps (iii) and (iv) link the system font with the Chinese font <i>simsun.ttc</i>. <span style="color: rgb(255, 255, 51);">-<span style="background-color: rgb(255, 255, 51);">-<span style="background-color: rgb(255, 255, 102); color: rgb(51, 51, 51);">dx: systemlink already there, added string value.</span></span></span><br /></li><li style="padding-bottom: 10px;">Go to [<i>HKEY_LOCAL_MACHINE\Software\<wbr>Microsoft\FontLink\SkipTable</i>] and verify string value <i>"Tahoma"="005c,00a5,007e,0391-<wbr>03c9,2026,2116,221a,25a0-25ff"</i><wbr>. Add/Modify where necessary. Since some system fonts have Unicode definitions that you do not want to use, this test will add a skip table to force the use of the linked font.<span style="background-color: rgb(255, 255, 51);"> --dx: no skiptable, so added both key and string</span><br /></li><div class="im"><li style="padding-bottom: 10px;">Do a soft reset and you are done.</li> </div></ol><p style="padding-bottom: 10px;">Hope it helps.</p>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-63513296249153483472010-06-11T08:01:00.002-07:002010-06-11T08:03:27.569-07:00TerminateProcess in WM6 (C++)BOOL KillAProcess(CString csName)<br />{<br /> BOOL bRetVal = TRUE;<br /> //HANDLE hPID;<br /><br /> HANDLE h_pro;<br /> HANDLE h_sna;<br /> PROCESSENTRY32 pe_sen = {0};<br /> bool lpFound = false;<br /> int result;<br /><br /> CString csMsg;<br /> CString cMethod = L"KillAProcess";<br /><br /> h_sna = CreateToolhelp32Snapshot(<div id=":k9" class="ii gt"><wbr>TH32CS_SNAPPROCESS|TH32CS_<wbr>SNAPNOHEAPS, 0);<br />//A snapshot tries to reserve 1MB of virtual memory. If it can't, or can't<br />//commit the first page (or n pages), then you'll get ERROR_NOT_ENOUGH_MEMORY<br />//and very important, to add the TH32CS_SNAPNOHEAPS, to limit the ammount of<br />//data the snapshot generates<br /><br /><br /> if ((HANDLE) -1 == h_sna)<br /> {<br /> DWORD lngResult = GetLastError();<br /> CString csError;<br /> csError.Format(L"<wbr>CreateToolhelp32Snapshot failed=%d",lngResult);<br /> AfxMessageBox(csError);<br /><br /> }<br /><br /> pe_sen.dwSize = sizeof(PROCESSENTRY32);<br /><br /> if (Process32First(h_sna, &pe_sen))<br /> {<br /> do<br /> {<br /> h_pro = OpenProcess (PROCESS_ALL_ACCESS, FALSE, pe_sen.th32ProcessID);<br /> CloseHandle (h_pro);<br /><br /> //AfxMessageBox(pe_sen.<wbr>szExeFile);<br /><br /> if (pe_sen.th32ProcessID != 0)<br /> {<br /> result = _tcscmp(pe_sen.szExeFile,<wbr>csName);<br /><br /> if(result==0)<br /> { <br /> //hPID = (HANDLE)pe_sen.th32ProcessID;<br /> lpFound = true;<br /> <br /> //start kill<br /> HANDLE hProcess = NULL;<br /> hProcess = ::OpenProcess(PROCESS_<wbr>TERMINATE, FALSE, pe_sen.th32ProcessID);<br />//********************<br /> //NOTE!!!!Have to have this Openprocess before TerminateProcess call to make it work.<br />//************************<br /> <br /> if (hProcess != NULL)<br /> {<br /> if (::TerminateProcess(hProcess, 0))<br /> {<br /> csMsg.Format(L"%s: killed %s", cMethod, csName);<br /> AfxMessageBox(csMsg);<br /> }<br /> else<br /> {<br /> csMsg.Format(L"%s: error terminating %s [0x%08x]", cMethod,<br /> csName, GetLastError());<br /> AfxMessageBox(csMsg);<br /> }<br /> }<br /> if (hProcess != NULL)<br /> {<br /> ::CloseHandle(hProcess);<br /> hProcess = NULL;<br /> }<br /><br /> break;<br /> }<br /> }<br /> } while (Process32Next(h_sna, &pe_sen));<br /> }else<br /> AfxMessageBox(L"Process32First failed");<br /><br /><br /> return bRetVal;<br />}</div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-21853792247672535152010-06-11T08:01:00.001-07:002010-06-11T08:01:19.902-07:00DWORD and HANDLE<div id=":ii" class="ii gt"><div><p>Win32:</p> <ul><li>DWORD 32 bit unsigned long</li><li>HANDLE void * (32 bit pointer)</li></ul> <p>Win64</p> <ul><li>DWORD 32 bit unsigned long</li><li>HANDLE void * (64 bit pointer)</li></ul> <p>DO NOT just assume you can cast one to the other. It will work for Win32 and break when you port it to Win64.</p><p><br /></p><p> <span>1</span> <span title="This answer is not useful (click again to undo)"></span> </p><div><p>If you're asking in the context of the Win32 API, then there is no substantive difference. A <code>HANDLE</code> is a 32-bit number, same as <code>DWORD</code>.</p> <p>If you're asking in some other context (you have tagged this <code>ansi-c</code> for a reason?) then you will need to explain what context that is.</p><p><br /></p><p>A HANDLE is a PVOID or a void* typedef, A DWORD is a uint32. Isn't a void* length depending from the memory architecture (eg. x86 & x64)?</p> </div> </div> </div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-43265979845026162592010-06-11T07:57:00.000-07:002010-06-11T08:05:14.534-07:00How to disable menu items in VC++How to disable a menu item in VC++?<br /><br />06/11/2010<br /><br />.h:<br /><br /> afx_msg void OnUpdateXXX(CCmdUI* pCmdUI);<br /><br />.cpp:<br /><br />ON_UPDATE_COMMAND_UI(ID_NEW_XX, OnUpdateXXX)<br /><br />void CXXXXXX::OnUpdateXXX(CCmdUI *pCmdUI)<br />{<br /><br /> pCmdUI->Enable(FALSE);<br /><br /> //pCmdUI->Enable(TRUE);<br /><br />}<br /><br />NOTE: the following doesnot work properly:<br /><br />CWnd* pParent = GetParent(); // This is a point to the window<br />CMenu* pMenu = pParent->GetMenu();<br />pMenu->EnableMenuItem(ID_NEW_WO , MF_GRAYED );<br /><br />Reason:<br />The effects of EnableMenuItem are preempted by the actions of the menu<br />update handlers. For example, if you use EnableMenuItem() to disable a<br />menu item, the default menu update handler will reenable it if an<br />ON_COMMAND macro is defined for that item. This, off course, negates<br />the effect of your attempt to disable it. To eanable or disable a menu<br />item, you should provide your own menu update handler and then use the<br />Enable() member function of CCmdUI.Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-50299119406232870232009-08-21T09:52:00.000-07:002009-08-21T09:53:08.849-07:00BeginUpdate() and EndUpdate() when populating ListView/TreeView<h3> <a href="http://moiashvin-tech.blogspot.com/2007/09/use-of-beginupdate-and-endupdate-when.html" target="_blank">Use of BeginUpdate() and EndUpdate() when populating ListView/TreeView</a> </h3> <div align="justify">Often a listview control in C# needs to be populated with large amount of data (bulky operations, for example, adding 1000 items). For every item added in the Listview, the control will redraw itself, thus greatly reduce the overall performance.<br /><br />However, using the two methods BeginUpdate() and EndUpdate() while performing these bulk operations gives significant advantage. A call to BeginUpdate() can be made before adding/deleting/clearing items. This will stop any paint messages being sent or processed. Once the operation is done, the EndUpdate() can then be called.<br /><br /></div><img style="margin: 0px auto 10px; display: block; text-align: center;" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEizQwBrcSL3X1R3iS5KfxWlAbzvXwm20FFn9TYCR2f9iykcMnaMSnaVCLkPvfPs1HmU71WksUKxgotD3UiYaHZz9cedI88DaDp732TNyZrHiN_J-9zHLMogSeMcB4yAGIWQZxArdOp6JZ4/s400/Listview1.gif" border="0" /><br />I have logged the time taken of the above code (i.e. adding 1000 items in a ListView for each button click) with and without the BeginUpdate/EndUpdate method calls using a test application.<br /><br /><img style="margin: 0px auto 10px; display: block; text-align: center;" alt="" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjfg8Z2xni6mu7K_MOCifEuUoyNYr7er_md8l4Cb-s3Ox9SLpMNsUAfm-D8oQ03BZ36gTotCDR8bG2hKx1075TVWY7mM-RpzaMEasm1cqhgYn029jUR3d2fixwvL-u5tbODlAOKYut73bU/s400/performance1.gif" border="0" /><br />The use BeginUpdate() and EndUpdate populates the control with a constant duration and much better performance. Amazing, isn't it?Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com1tag:blogger.com,1999:blog-6052374310229468906.post-34138174323920772872009-08-21T09:48:00.000-07:002009-08-21T09:49:02.917-07:00SuspendLayout and ResumeLayou<div style="text-align: left;"><b>SuspendLayout and ResumeLayout<br /><br /></b>The SuspendLayout and ResumeLayout are methods used in order to prevent conflict when events pertaining to placing and moving controls and setting their attributes are thrown.<br /><br />You would for instance perhaps like to add controls onto a panel or a window programatically .. what you must do is suspend the control you are adding other controls to and after you are done adding ,you then can resume your layout by calling the ResumeLayout method.<br /><br />say for example you have a panel and would like to add some controls to it here is how you would do it using a method :<br /><br /><span style="color:#008000;">private void AddSomeControls()<br />{<br /> // Suspend the panel layout and add two buttons.<br /> this.SuspendLayout();<br /> TextBox txtOne = new TextBox();<br /> txtOne.Location = new Point(10, 10);<br /> txtOne.Size = new Size(75, 25);<br /> txtOne.Text = "Textbox addded";<br /><br /> Button btnMyButton = new Button();<br /> btnMyButton.Location = new Point(90, 10);<br /> btnMyButton.Size = new Size(75, 25);<br /> btnMyButton.Text = "Just been Added";<br /> <br /> this.Controls.AddRange(new Control[]{txtOne, btnMyButton});<br /> this.ResumeLayout();<br />}</span></div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-4229222769542762222009-08-20T15:11:00.000-07:002009-08-20T15:12:38.790-07:00Always Ask for Reboot when installing Visual Studio .NET<a title="http://support.microsoft.com/kb/891402" href="http://support.microsoft.com/kb/891402" target="_blank">http://support.microsoft.com/<wbr>kb/891402</a>.<br /><span style="font-size:85%;"><br /></span><h1><span style="font-size:85%;">You receive a "Setup has detected that another program requires the computer to reboot" message when you install Visual Studio 2005 or Visual Studio .NET</span></h1><br />To resolve this issue, use one of the following methods.<div><a href="http://support.microsoft.com/kb/891402#top" target="_blank"><img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/uparrow.gif" alt="" />Back to the top</a></div> <h3>Method 1: Modify the Windows Registry</h3><ol><li>Click <strong>Start</strong>, click <strong>Run</strong>, type <span>regedit</span>, and then click <strong>OK</strong>.</li><li>Locate and then click the following registry key:<div>HKEY_LOCAL_MACHINE\System\<wbr>CurrentControlSet\Control\<wbr>Session Manager</div></li><li>In the right pane, right-click <strong>PendingFileRenameOperations</strong>, and then click <strong>Delete</strong>.<br /><br /><b>Note</b> If the <strong>PendingFileRenameOperations</strong> value does not exist, exit Registry Editor, and then use method 2.</li><li>Exit Registry Editor. Then, try to install Visual Studio 2005 or Visual Studio .NET again.</li></ol><div><a href="http://support.microsoft.com/kb/891402#top" target="_blank"><img src="http://support.microsoft.com/library/images/support/kbgraphics/public/en-us/uparrow.gif" alt="" />Back to the top</a></div><h3> Method 2: Install the Prerequisites components from the Visual Studio 2005 or Visual Studio .NET CD</h3><ol><li>Cancel the current installation.</li><li>Insert the Visual Studio 2005 or Visual Studio .NET Prerequisites CD into your CD drive.</li><li>Click <strong>Start</strong>, click <strong>Run</strong>, type <span><var>drive</var>:\setup.exe</span>, and then click <strong>OK</strong>.<br /><br />In this step, <var>drive</var> is the letter of your CD drive.</li><li>Click <strong>No</strong> when you receive the following message:<div>Visual Studio .NET Prerequisites Warning - Setup on CD1 should be used to launch Visual Studio 2005 or Visual Studio .NET Prerequisites setup so that only the necessary components are installed. Click Yes to exit and change CDs. Click No to install all available components.</div></li><li>After the installation of the Prerequisites components is complete, insert Visual Studio 2005 or Visual Studio .NET CD 1, and then install Visual Studio 2005 or Visual Studio .NET.</li></ol>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-59617068196787362782009-08-12T12:27:00.000-07:002009-08-12T12:28:02.623-07:00Localization of .Net applications<h1><a href="http://www.codeproject.com/Articles/35713/Localization-of-Net-applications.aspx" target="_blank"><span>Localization of .Net applications</span></a></h1><br /><p>These last days, I had the change to mess up with the Localization infrastructure inside Visual Studio 2008. I must realize it´s the first time I seriously get into this issue, and I´m impressed with the work done on it.</p> <p>When one needs to give an application multi-language support, the first temptation (as old-time programmers) is to build up some sort of tables with strings, each one for each language. That´s more or less what the Localization system will do, but with the following extra features:</p> <p><span style="font-size: 130%;"><strong>A comfortable visual editor </strong></span></p> <p>We have a comfortable visual editor to manage the string tables, like this one, giving you the chance to set comments to each entry.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjs8tugcRVQH5RF0_SGnArjRUi7ye9vdNlrqy5KjN77hrsD0K2dcDrlFAo5WfBlbyggu1Oas2RBNYlE4O5cjNH00Me9bpZBFDSVrqVI3NaOrbIcPdylQttdHFmZO0Gizm-BS7rpp3WzgAQ/s1600-h/55%5B6%5D.jpg" target="_blank"><img title="55" style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" alt="55" src="http://lh3.ggpht.com/_NiFMuxzz-JE/SXDQL47zATI/AAAAAAAAAcY/au2O7kSCZD8/55_thumb%5B4%5D.jpg?imgmax=800" border="0" width="691" height="310" /></a></p> <p><span style="font-size: 130%;"><strong>Culture infrastructure-ready</strong></span></p> <p>The system offers automatic integration with the Culture infrastructure of each application. To get more info about this, check:</p> <ul><li>System.Threading.Thread.<wbr>CurrentThread.CurrentCulture</li><li>System.Threading.Thread.<wbr>CurrentThread.CurrentUICulture</li></ul> <p>This gives you automatic support for different numbering and date formats, etc.</p> <p><strong><span style="font-size: 130%;">Integrated with the Visual Studio Designer</span></strong></p> <p>To start localizing, you just have to open the design view of a form or control and set the <em>Localizable </em>property of any form or control to <strong>True</strong> to generate the default resource (.resx) file. From then, each time you <a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgiHZWgdKG3mq5uYedTb1uisWugJ8V5WoeMa_AVKKbN7xjoVfkTRgzD10QptEfujQzJ7IFWLmin_3jv1Yqm3ERGhg11uKFK5SJppEYvtB56zut7g6-S4qWc01REGMsx15ckvyFy1iSjDag/s1600-h/51%5B5%5D.jpg" target="_blank"><img title="51" style="border-width: 0px; margin: 0px 10px 0px 0px; display: inline;" alt="51" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjbk768BqVOot2QmE1uFlDhLQqDBKzH6Mk0K3mERmZdV_UWIeeHAdwi2uoJC759pUIhDSOqeXF9cV8YJ3zbS13JoGuGsKgkSwasqRmZsv_bXv4Jl1Zu8yWZ7c-4AOcyGlXhV9zRPs5NSTs/?imgmax=800" align="removed"" border="0" width="214" height="94" /></a>select a new language in the combo (and change any property), a newer <strong>resX </strong>file is generated to reflect the change. Of course, all this files are perfectly managed by the Solution Explorer as a part of the form or the control. </p> <p>Once a form is localizable, each time we change the current language, the designer automatically updates the design view to show the appearance of the form or control in that language. ResX files are also maintained automatically. </p> <p><strong><span style="font-size: 130%;">Localization of the entire looking (not only texts)</span></strong></p> <p>You can make specific versions of each control or user interface for each language, including control positions, dimensions, colors, anything... </p> <p>This is specially relevant because many times is not enough with just replacing texts. The translation of a text may have a remarkable different length in other languages. In this case we would have to resize the label containing the string, and maybe relocate other controls in the form, as in the following picture, where you can see two version of the same form, for two different languages.</p> <p><a href="http://lh4.ggpht.com/_NiFMuxzz-JE/SXDQNi09-6I/AAAAAAAAAck/GXsNPRn-9u8/s1600-h/52%5B5%5D.jpg" target="_blank"><img title="52" style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" alt="52" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEj_IjkHBnIOVK3YEuR8sCzk2g05ZJM9XZGEck5VEUalJr0u3VixiQ6mv0Mrgf1LuI6FNCLz_veYRbHt0YbEcNyG_RANocCnN_r-kXJelYyNYpYZ4v2yg-HgeQKAp93lNNM_GIl2WuRBxSU/?imgmax=800" border="0" width="548" height="158" /></a> </p> <p><strong>Note: </strong>Text strings are saved directly in the resx files accompanying the Form1.cs class, but other properties, like dimensiones, locations, etc, are saved in other place. When you compile your solution, in the output directory you will find additional folders with culture-specific names, like “en-US”, etc. This folders will contain additional DLLs created automatically by VisualStudio, one for each localizable assembly. Inside this DLLs, you will find resources defining the appearance of the form´s controls.</p> <p><span style="font-size: 130%;"><strong>Additional String Tables</strong></span></p> <p>We have talked about resource files handled by the Designer to reflect the appearance changes of forms for different languages but, what happens with the message shown in a MessageBox? This is not something we can manage in a design view. </p> <p>A solution is to insert additional .resx files to the project. We can make them “embedded resources” and easily access them with the ResourceManager class directly, although I must tell you this is not the best solution (see next chapter). Of course, there´s no designer to handle this tables, so they will have to be maintained manually (using the visual editor). </p> <p>To include a complete collection of additional string tables, you can start with the default resx file (for the default language). Give it any name you like, for example: “<strong>LocalizedStrings.resx” </strong>(just click your project with the right button, and select “Add New item”, and then “Resource File” as the item type). Afterwards, you can add any other language version for that file, using the same name with the culture-specific string representation before the extension. Some examples:</p> <ul><li>LocalizedStrings.en-US.resx</li><li>LocalizedStrings.es-ES.resx</li><li>LocalizedStrings.fr-FR.resx</li><li>…</li></ul> <p><strong><span style="font-size: 130%;">Strongly-typed access to string tables</span></strong></p> <p>This is also a very important feature, because once you have your string table up and running, you need to get access to it from your code. You can do so directly through the <strong><em>ResourceManager.GetString() </em></strong>method, but this is definitely not a good idea. Mostly because you will have to give it the name of the entry you are looking for, in the form of a simple "string”. </p> <p>This means that you will have no Intellisense support (you will have to look the name of the properties in the table by yourself), and if any property name is changed later, there will be no compiling warning or error. This means that if you are not extremely careful for the rest of your application´s life, you won´t notice the mistake until runtime, and this is extremely bug-prone. </p> <p>The solution is to make a strongly-typed class, which includes code properties to access each entry in the table. Of course, it would be a non sense if we had to make them manually (it would be the same as accessing though the ResourceManager class). Thankfully VisualStudio includes a tool to take care of such task: the <strong><em>ResXFileCodeGenerator. </em></strong>To make VisualStudio invoke this tool, you will have to put it´s name (“<strong><em>ResXFileCodeGenerator</em></strong>”, without quotes) in the <strong><em>Custom Tool </em></strong>property <strong><u>of the default </u></strong>resx file. This is important: IN THE DEFAULT resx file. This means that, if you have LocalizedStrings.resx (with the default language, spanish for example), and LocalizedStrings.en-US.resx, you have to set the custom tool to the first one.</p> <p><a href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgK39SMrEldWbiMON3Z511fitE9KD77ifu9EM6kweUnW3iQjS-5H1sOgDOKiRZhH2YLE_nPF4pdKZO9metc9CJZLzWVyJbej7VDS49NL9bNwx_1UQR24m4Ja0J66BI8s3R94YT0O1IQhgg/s1600-h/53%5B4%5D.jpg" target="_blank"><img title="53" style="border-width: 0px; display: block; float: none; margin-left: auto; margin-right: auto;" alt="53" src="http://lh4.ggpht.com/_NiFMuxzz-JE/SXDQPtMpHII/AAAAAAAAAcw/5Eh1UyUr5Us/53_thumb%5B2%5D.jpg?imgmax=800" border="0" width="331" height="128" /></a></p> <p>When you do so, a new “.cs” file will be generated for you (below the resx file) containing the strongly-typed class. Though the maintenance of this class is automatic, you can force a refresh anytime you want by clicking the resx file with the right button and selecting <strong><em>“Run custom tool”</em></strong>. </p> <p>From now, you can access your strint table texts with Intellisensed, strongly-typed, in-code properteties like:</p> <p>“text = LocalizedStrings.<wbr>strWarningCaption”</p> <p><strong><span style="font-size: 130%;">APPENDIX A: Making an automatically-generated, strongly-typed class to be PUBLIC</span></strong></p> <p>By default, strongly-typed classes generated with the <strong><em>ResXFileCodeGenerator</em></strong> tool are <strong>INTERNAL</strong>. This means that they will only be accessible inside your assembly.</p> <p>To make one of this classes public, you cannot just change its code as it will be re-generated by the tool on next rebuild. You have to change the custom tool, selecting the <strong><em>PublicResXFileCodeGenerator</em></strong> instead of the previous one. It will make them public for you.</p> <p>You can also do this “double-clicking” your string table (to enter the visual editor view), and selecting the PUBLIC modifier in the upper part of the screen (this actually changes the custom tool as explained above).</p> <p>Well, it´s been long, but hope it helps someone. However, this is my first approach to Localization and therefore, for sure there will be people with deeper knowledge on this issue. Please feel free to complete (or correct) this tutorial with comments and suggestions. </p>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com1tag:blogger.com,1999:blog-6052374310229468906.post-89129335099349550072009-08-12T12:20:00.000-07:002009-08-12T12:21:18.947-07:00Tutorial: Visual Studio 2008 Obfuscating with Dotfuscator<strong>Tutorial: Visual Studio 2008 Obfuscating with Dotfuscator<br /><br /></strong>In this <div><span style="border-bottom: 1px solid rgb(153, 22, 22); color: rgb(153, 22, 22); text-decoration: underline; display: inline; background-color: transparent; font-size: 1em; padding-bottom: 1px; width: auto; margin-left: 0px; line-height: 1em;">tutorial</span> I'll teach you what Obfuscating is, why you should use it for your .NET products and how to do it with Dotfuscator. Dotfuscator comes with <span style="border-bottom: 1px solid rgb(153, 22, 22); color: rgb(153, 22, 22); text-decoration: underline; display: inline; background-color: transparent; font-size: 1em; padding-bottom: 1px; width: auto; margin-left: 0px; line-height: 1em;">Visual Studio</span> 2008 Professional Edition, if you don't have it you can still buy it as a standalone. Lets start by looking at what obfuscating is.<br /><br /><span style="font-size:130%;"><b>What is Obfuscating?</b></span><br />Obfuscated code is code intentionally (mostly) created hard to read, however, poor programming skills and/or little knowledge of standards can cause a programmer to create obfuscated code without even knowing it. There are some <span style="border-bottom: 1px solid rgb(153, 22, 22); color: rgb(153, 22, 22); text-decoration: underline; display: inline; background-color: transparent; font-size: 1em; padding-bottom: 1px; width: auto; margin-left: 0px; line-height: 1em;">languages</span> more prone to obfuscated code than others such as C and C++.<br /><br /><b> Example:</b><br /><div style="margin: 5px 20px 20px;"> <div style="margin-bottom: 2px;">Code:</div> <pre dir="ltr" style="border: 1px inset ; margin: 0px; padding: 6px; overflow: auto; width: 550px; height: 98px; text-align: left; font-family: Courier New,monospace;">double h[2]; int main(_, v) char *v; int _; { int a = 0; char f[32]; h[2%2] =<br /><br />219144411970696341534563910188<wbr>240261707095231701777609973207<wbr>59459436800394073<br />072125018704290409006721463388<wbr>339383036594392377406351605008<wbr>55813030357492372<br />682887858054616489605441589829<wbr>740433065995076650229152079883<wbr>597110973562880.0 00000; h[4%3] =<br /><br />1867980801.569119; switch (_) { case 0: break; default: main(0,(char *)h); break; } }</pre> </div><span style="font-size:130%;"><b>Why Obfuscate?</b></span><br />Obfuscating can make code very difficult to understand or even reverse engineer. <span style="border-bottom: 1px solid rgb(153, 22, 22); color: rgb(153, 22, 22); text-decoration: underline; display: inline; background-color: transparent; font-size: 1em; padding-bottom: 1px; width: auto; margin-left: 0px; line-height: 1em;">Programs</span> written in .NET or Java are easy to decompile to full <span style="border-bottom: 1px solid rgb(153, 22, 22); color: rgb(153, 22, 22); text-decoration: underline; display: inline; background-color: transparent; font-size: 1em; padding-bottom: 1px; width: auto; margin-left: 0px; line-height: 1em;">source code</span> as though the cracker is looking at the original code you wrote in your IDE. These reverse engineering programs are freely available on the internet making it easy for anyone to see your entire source code. While still readable, obfuscating makes the code harder to read creating some security for your applications.<br /><br /><span style="font-size:130%;"><b>Getting Started</b></span><br />In this tutorial we will be obfuscating a the Visual Studio 2008 C# program we created in this tutorial: <a href="http://forum.codecall.net/c-tutorials/6267-visual-studio-2008-c-hello-world-tutorial.html" target="_blank">http://forum.codecall.net/c-<wbr>tutorial...-tutorial.html</a>, however you can use whatever project you desire. We will use the debug build here.<br /><br /><b>Step 1<br /></b>Load Visual Studio 2008 (<span style="color:Navy;"><b>Start/Microsoft Visual Studio 2008/Microsoft Visual Studio 2008</b></span>). You don't have to select a project but VS2008 must be loaded before you can launch dotfuscator. <br /><br /><b>Step 2<br /></b>Load dofuscator (<b><span style="color:Navy;">Start/Microsoft Visual Studio 2008/Visual Studio Tools/Dotfuscator Community Edition</span></b>). If you do not have VS2008 loaded you will see an error:<br /><br /><a href="http://forum.codecall.net/images/Tutorials/dotfuscator/error.jpg" target="_blank"><img src="http://forum.codecall.net/images/Tutorials/dotfuscator/errorSmall.jpg" alt="" border="0" /></a><br /><br /><b>Step 3</b><br />You may be asked to Register. <span style="border-bottom: 1px solid rgb(153, 22, 22); color: rgb(153, 22, 22); text-decoration: underline; display: inline; background-color: transparent; font-size: 1em; padding-bottom: 1px; width: auto; margin-left: 0px; line-height: 1em;">Click</span> "No, I don't want to Register" or "Yes, Register Now", your option but this tutorial will not cover that. At the next screen, "Select Project Type", click "Create New Project" and press "OK".<br /><br /><a href="http://forum.codecall.net/images/Tutorials/dotfuscator/createProject.jpg" target="_blank"><img src="http://forum.codecall.net/images/Tutorials/dotfuscator/CreateProjectSmall.jpg" alt="" border="0" /></a><br /><br /><b>Step 4</b><br />Click "Browse and add assembly to list" icon (below Input Assemblies: - the open folder icon). Click Browse. Navigate to your project executable file. Using the C# Hello World project you will find it located in "My Documents/Visual Studio 2008/Projects/HelloWorld/<wbr>HelloWorld/bin/debug/<wbr>HelloWorld.exe". Click "OK".<br /><br /><a href="http://forum.codecall.net/images/Tutorials/dotfuscator/projectAdded.jpg" target="_blank"><table width="500"><tbody><tr><td width="20"> <img alt="" src="http://forum.codecall.net/images/statusicon/wol_error.gif" border="0" width="16" height="16" /></td><td>This image has been resized. Click this bar to view the full image. The original image is sized 600x430.</td> </tr></tbody></table><img src="http://forum.codecall.net/images/Tutorials/dotfuscator/projectAddedSmall.jpg" alt="" border="0" width="500" height="358" /></a><br /><br /><b>Step 5</b><br />Goto "<span style="color:black;"><b>File/Build</b></span> or press Ctrl+B. You will be asked to save your project, press "Yes". Enter "HelloWorldC#" or a suitable name for your project. You should see:<br /><br /><a href="http://forum.codecall.net/images/Tutorials/dotfuscator/buildComplete.jpg" target="_blank"><img src="http://forum.codecall.net/images/Tutorials/dotfuscator/buildCompleteSmall.jpg" alt="" border="0" /></a><br /><br /><b>Step 6</b><br />Your project has now been obfuscated. You can find the executable in "My Documents/Dotfuscated/<wbr>HelloWorld.exe". This is the executable you want to package in the installation file, however, you will want to use a build release instead of a debug release. Click on "Output" tab to see what was obfuscated:<br /><br /><a href="http://forum.codecall.net/images/Tutorials/dotfuscator/obfuscated.jpg" target="_blank"><table width="500"><tbody><tr><td width="20"> <img alt="" src="http://forum.codecall.net/images/statusicon/wol_error.gif" border="0" width="16" height="16" /></td><td>This image has been resized. Click this bar to view the full image. The original image is sized 600x430.</td> </tr></tbody></table><img src="http://forum.codecall.net/images/Tutorials/dotfuscator/obfuscatedSmall.jpg" alt="" border="0" width="500" height="358" /></a></div><br /> <div> <div> <div style="margin: 5px 20px 20px;"> <div style="margin-bottom: 2px;">Quote:</div> <table border="0" cellpadding="6" cellspacing="0" width="100%"> <tbody><tr> <td style="border: 1px inset ;"> <div> Originally Posted by <strong>afkhami</strong> <a href="http://forum.codecall.net/tutorials/6391-tutorial-visual-studio-2008-obfuscating-dotfuscator.html#post94475" rel="nofollow" target="_blank"><img title="View Post" src="http://forum.codecall.net/images/buttons/black/viewpost.gif" alt="View Post" border="0" /></a> </div> <div style="font-style: italic;">so how do you package your software protected with Dotfuscator?</div> </td> </tr> </tbody></table> </div>The Enhanced Community Edition will integrate with Visual Studio, letting you use the Dotfuscated project output for your Setup project's input.</div></div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-83688029488706035792009-07-31T08:07:00.000-07:002009-08-12T12:30:18.635-07:00How to send Emails with Gmail Account with Attachment<span style="color:DarkBlue;">First you need to change the settings in your Gmail account<br /><br />step 1: Login to your Gmail Account with from which you will be sending e-mails.<br /><br />step 2: Go to Gmail settings then click on Forwarding and POP/IMAP<br /><br />step 3: In IMAP Access Check Enable IMAP<br /><br />step 4: Then go to your application use below code<br /><br /></span><span style="color:DarkBlue;"><pre>void AttachFile(string attachmentFile)<br />{<br /> System.Net.Mail.MailAddress toAddress = new System.Net.Mail.MailAddress("<a href="mailto:your-reciving-email@gmail.com" target="_blank">y<wbr>our-reciving-email@gmail.com</a>")<wbr>;<br /><br /> System.Net.Mail.MailAddress fromAddress = new System.Net.Mail.MailAddress("<a href="mailto:fromAddress@yahoo.com" target="_blank">f<wbr>romAddress@yahoo.com</a>");<br /> System.Net.Mail.MailMessage mm = new System.Net.Mail.MailMessage(<wbr>fromAddress, toAddress);<br /><br /> mm.Subject = "Email Subject";<br /> System.Net.Mail.Attachment mailAttachment = new System.Net.Mail.Attachment(<wbr>printScreen);<br /> mm.Attachments.Add(<wbr>mailAttachment);<br /> mm.IsBodyHtml = true;<br /><br /> mm.BodyEncoding = System.Text.Encoding.UTF8;<br /> sendMail(mm);<br />}<br /><br /><span style="font-weight: bold;">NOTE1:</span><br />How do I specify multiple recipients? Printer Friendly<br />Because the<br />To, CC, and Bcc properties are MailAddress collections, to add<br />additional recipients, all we need to do is call .Add(...) on the<br />respective properties.<br /><br /><br />Below is an example that demonstrates adding multiple To, CC, and Bcc addresses.<br /><br />[ C# ]<br /><br />static void MultipleRecipients()<br />{<br />//create the mail message<br />MailMessage mail = new MailMessage();<br /><br /><br />//set the addresses<br />//to specify a friendly 'from' name, we use a different ctor<br />mail.From = new MailAddress("<a href="mailto:me@mycompany.com" target="_blank">me@mycompany.com</a>"</pre></span><div id=":1u4" class="ii gt"><wbr>, "Steve James");<br /><br />//since the To,Cc, and Bcc accept addresses, we can use the same technique as the From address<br />//since the To, Cc, and Bcc properties are collections, to add multiple addreses, we simply call .Add(...) multple times<br />mail.To.Add("<a href="mailto:you@yourcompany.com" target="_blank">you@yourcompany.<wbr>com</a>");<br />mail.To.Add("<a href="mailto:you2@yourcompany.com" target="_blank">you2@yourcompany.<wbr>com</a>");<br />mail.CC.Add("<a href="mailto:cc1@yourcompany.com" target="_blank">cc1@yourcompany.<wbr>com</a>");<br />mail.CC.Add("<a href="mailto:cc2@yourcompany.com" target="_blank">cc2@yourcompany.<wbr>com</a>");<br />mail.Bcc.Add("<a href="mailto:blindcc1@yourcompany.com" target="_blank">blindcc1@<wbr>yourcompany.com</a>");<br />mail.Bcc.Add("<a href="mailto:blindcc2@yourcompany.com" target="_blank">blindcc2@<wbr>yourcompany.com</a>");<br /><br />//set the content<br />mail.Subject = "This is an email";<br />mail.Body = "this is the body content of the email.";<br /><br />//send the message<br />SmtpClient smtp = new SmtpClient("127.0.0.1");<br />smtp.Send(mail);</div><span style="color:DarkBlue;"><pre><br />string sendMail(System.Net.Mail.<wbr>MailMessage mm)<br /> {<br /> try<br /> {<br /> string smtpHost = "<a href="http://smtp.gmail.com/" target="_blank">smtp.gmail.com</a>";<br /><br /> string userName = "<a href="mailto:your-email-address@gmail.com" target="_blank">your-email-address@gmail.com</a>"<wbr>;//sending Id<br /> string password = "your-password";<br /> System.Net.Mail.SmtpClient mClient = new System.Net.Mail.SmtpClient();<br /><br /> mClient.Port = 587;<br /> mClient.EnableSsl = true;<br /> mClient.UseDefaultCredentials = false;<br /> mClient.Credentials = new NetworkCredential(userName, password);<br /><br /> mClient.Host = smtpHost;<br /> mClient.DeliveryMethod = System.Net.Mail.<wbr>SmtpDeliveryMethod.Network;<br /> mClient.Send(mm);<br /> }<br /> catch (Exception ex)<br /><br /> {<br /> MessageBox.Show(ex.Message);<br /> } <br /> }</pre></span><span style="font-weight: bold;">NOTE2</span><br /><br />Have to replace \r\n with html line break "br"<br />in order to show paragraph and line breaks.<br /> string sNewBody = textBoxBody.Text.Replace("\r\<div id=":1ud" class="ii gt"><wbr>n", "<br />");<br /> //mm.Body = textBoxBody.Text;<br /> mm.Body = sNewBody;</div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-7637267808753507232009-07-27T12:47:00.001-07:002009-07-27T12:47:43.727-07:00Showing a Separate Tooltip for Each Item in a ListBox<div id=":d" class="ii gt"><h2><a href="http://www.codeproject.com/KB/combobox/ToolTipForListBox.aspx" target="_blank">http://www.codeproject.com/KB/<wbr>combobox/ToolTipForListBox.<wbr>aspx</a><br /></h2><h2>Introduction </h2> <p><code>ListBox </code>is a very common control used in Windows Forms. Most often we would need to show some information on each item in the <code>ListBox </code>when the user places the mouse pointer above that item. Sadly there is no straight forward way to do that. The reasons are:</p> <ol><li>There is no separate mouse hover event for individual items in the list.</li><li>As each item in the list is not a control (of course!!), we cannot set a tool tip for items of the list separately. A tooltip can be set only for the <code>ListBox </code>as such.</li></ol> <p>But don't give up!! If there is a will, there is a way…</p> <h2>Using the Code</h2> <p>The steps required are explained below:</p> <ol><li> <p>Drag and drop a ToolTip control into the form having the <code>ListBox</code>. I am calling it <code>ListToolTip</code>.</p> </li><li> <p>We have to know the ToolTip text for each item in the <code>ListBox</code>. I have an array of <code><span>string</span></code>s as items in the <code>ListBox</code>. So I maintain the ToolTip text for each item in another <code><span>string</span> </code>array. So if I know the index of the Item in the array of items, I can get the corresponding ToolTip text from the ToolTip array using the same index.</p> </li><li> <p>Create a handler for the Mouse Move event of the <code>ListBox</code>. Calculate the index of the item over which the mouse pointer is placed now. (This is the tricky part!!)</p> <ol type="a"><li> <p>Calculate the Offset of the item from the top of the list box. This can be obtained by dividing the Y coordinate of the house position by the height of each item. Height of each item is a property of the list box:</p> <div style="width: 100%;"><img width="9" height="9" /><span style="margin-bottom: 0pt;"> Collapse</span></div> <pre style="margin-top: 0pt;" lang="cs">itemIndex = e.Y / objListBox.ItemHeight; </pre> </li><li> <p>But the topmost item will not always be the first item in the list. If there is a scrollbar and user scrolls down, then the topmost item visible will change. This means that the index obtained above is not the index of the required item in the list of items. Fortunately <code>ListBox </code>has another property called <code>TopIndex</code>. If we add the <code>TopIndex </code>with the index obtained in the above step, then we will get the correct index.</p> <div style="width: 100%;"><img width="9" height="9" /><span style="margin-bottom: 0pt;"> Collapse</span></div> <pre style="margin-top: 0pt;" lang="cs">itemIndex += objListBox.TopIndex;</pre> </li></ol> </li><li> <p>Now we know the index of the item over which the mouse pointer is placed. Just take the Tooltip of that item from the Tooltip array and associate it with the ToolTip control. </p> <div style="width: 100%;"><img width="9" height="9" /><span style="margin-bottom: 0pt;"> Collapse</span></div> <pre style="margin-top: 0pt;" lang="cs"> <span>if</span> ((itemIndex >= <span>0</span>) && (itemIndex < m_arrItemToolTips.Length))<br />{<br /> ListToolTip.SetToolTip(<wbr>objListBox, m_arrItemToolTips[itemIndex]);<br /><br />}</pre> </li><li> <p>If the calculated index is out of the range of valid indexes, hide the ToolTip.</p> <div style="width: 100%;"><img width="9" height="9" /><span style="margin-bottom: 0pt;"> Collapse</span></div> <pre style="margin-top: 0pt;" lang="cs"> <span>else</span><br />{<br />ListToolTip.Hide(objListBox);<br />}</pre> </li></ol> <p>The entire code for the mouse move event handler is given below:</p> <div style="width: 100%;"><img width="9" height="9" /><span style="margin-bottom: 0pt;"> Collapse</span></div> <pre style="margin-top: 0pt;" lang="cs"><span>private</span> <span>void</span> ItemsListBox_MouseMove(<span>object</span> sender, MouseEventArgs e)<br /><br />{<br /> <span>try</span><br /> {<br /> ListBox objListBox = (ListBox)sender;<br /> <span>int</span> itemIndex = -1;<br /> <span>if</span> (m_arrItemToolTips != <span>null</span>)<br /><br /> {<br /> <span>if</span> (objListBox.ItemHeight != <span>0</span>)<br /> { <br /> itemIndex = e.Y / objListBox.ItemHeight;<br /><br /> itemIndex += objListBox.TopIndex;<br /> }<br /> <span>if</span> ((itemIndex >= <span>0</span>) && (itemIndex < m_arrItemToolTips.Length))<br /><br /> {<br /> ListToolTip.SetToolTip(<wbr>objListBox, m_arrItemToolTips[itemIndex]);<br /> }<br /> <span>else</span><br /> {<br /> ListToolTip.Hide(objListBox);<br /><br /> }<br /> }<br /> }<br /> <span>catch</span> (Exception ex)<br /> { <br /> }<br />}</pre> </div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-85652724158407513992009-07-16T08:07:00.000-07:002009-07-16T08:15:59.461-07:00C#: Resize An Image While Maintaining Aspect Ratio and Maximum Height<div class="im"><span style="font-size:100%;"><br />Function works, but need 2 changes:<br /><br />1. Set image properties, otherwise resized pics lose image information like date, camera type etc.<br />2. Need to specify image type when saving<br />// This allows us to resize the image. It prevents skewed images and<br />// also vertically long images caused by trying to maintain the aspect<br />// ratio on images who's height is larger than their width<br /><br /> public void ResizeImage(string OriginalFile, string NewFile, int NewWidth, int MaxHeight, bool OnlyResizeIfWider)<br /> {<br /> System.Drawing.Image FullsizeImage = System.Drawing.Image.FromFile(</span><wbr><span style="font-size:100%;">OriginalFile);<br /><br /><br /> // Prevent using images internal thumbnail<br /><br /> FullsizeImage.RotateFlip(</span><wbr><span style="font-size:100%;">System.Drawing.RotateFlipType.</span><wbr><span style="font-size:100%;">Rotate180FlipNone);<br /><br /> FullsizeImage.RotateFlip(</span><wbr><span style="font-size:100%;">System.Drawing.RotateFlipType.</span><wbr><span style="font-size:100%;">Rotate180FlipNone);<br /><br /><br /> if (OnlyResizeIfWider)<br /> {<br /> if (FullsizeImage.Width <= NewWidth) { NewWidth = FullsizeImage.Width; } } int NewHeight = FullsizeImage.Height * NewWidth / FullsizeImage.Width; if (NewHeight > MaxHeight)<br /> {<br /><br /> // Resize with height instead<br /><br /> NewWidth = FullsizeImage.Width * MaxHeight / FullsizeImage.Height;<br /><br /> NewHeight = MaxHeight;<br /> }</span><br /><br /> System.Drawing.Image NewImage = FullsizeImage.<wbr>GetThumbnailImage(NewWidth, NewHeight, null, IntPtr.Zero);<br /><br /></div><span style="font-size:130%;"><span style="font-weight: bold;"> //save all the photo properties</span><br /><span style="font-weight: bold;"> foreach (PropertyItem e in FullsizeImage.PropertyItems)</span><br /><span style="font-weight: bold;"> {</span><br /><span style="font-weight: bold;"> NewImage.SetPropertyItem(e);</span><br /><span style="font-weight: bold;"> }</span></span><br /> // Save resized picture<br /> NewImage.Save(NewFile, <span style="font-size:130%;"><span style="font-weight: bold;">ImageFormat.Jpeg</span></span>);<br /> // Clear handle to original file so that we can overwrite it if necessary<br /><br /> FullsizeImage.Dispose();<br /><br /><br /> }<h1><a href="http://snippets.dzone.com/posts/show/4336" target="_blank"></a></h1>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com1tag:blogger.com,1999:blog-6052374310229468906.post-80105138892645040922009-06-25T11:05:00.001-07:002009-06-25T11:05:39.524-07:00How to create button with picture(icon) and text for Window CE/MobileFor desktop program with full compact framework, it is very easy to create button with picture and text. Just drag the button from toolbox. Then choose the image from properties. But compact framework has no such properties for button.
<br />
<br />What we need to do is create our own customized button control like following (button.cs):
<br />
<br /> /*
<br />
<br /> Requirements: Microsoft Development Environment 2003 Version 7.1.3088
<br /> Microsoft .NET Framework Version 1.1.4322
<br />*/
<br />
<br />using System;
<br />using System.Collections;
<br />using System.ComponentModel;
<br />using System.Drawing;
<br />using System.Drawing.Drawing2D;
<br />using System.Data;
<br />using System.Windows.Forms;
<br />using System.Drawing.Imaging;
<br />
<br />// Assembly attribute that points to the run-time version of the assembly.
<br />// This attribute is needed for this control to function properly during design time.
<br />// When this control is added to the designer, the assembly indicated by
<br />// this attribute is added to the reference collection of the project.
<br />// The run-time assembly must be located in the reference path of the project,
<br />// and the design-time version must appear in the "designer reference path".
<br />
<br />//// The NETCFDESIGNTIME proprocessor variable is used to indicate whether the build is for a designer build or run-time device build.
<br />//// This lets you add device specific routines and also desktop requirements (such as design-time attributes) without needlessly increasing your footprint.
<br />//#if NETCFDESIGNTIME
<br />// [assembly: System.CF.Design.<div id=":6i" class="ii gt"><wbr>RuntimeAssemblyAttribute("<wbr>xxxxxxx, Version=2.1.0.0, Culture=neutral, PublicKeyToken=null")]
<br />//#endif
<br />
<br />namespace DJHome.SpecialButton
<br />{
<br /> /// <summary>
<br /> /// Button class.
<br /> /// </summary>
<br /> public class Button : System.Windows.Forms.Control
<br /> {
<br /> #region Component Designer generated code
<br />
<br /> /// <summary>
<br /> /// Clean up any resources being used.
<br /> /// </summary>
<br /> /// <param name="disposing">True to dispose of control.</param>
<br /> protected override void Dispose( bool disposing )
<br /> {
<br /> if( disposing )
<br /> {
<br /> if( components != null )
<br /> components.Dispose();
<br /> }
<br /> base.Dispose( disposing );
<br /> }
<br />
<br /> // Required method for Designer support - do not modify
<br /> // the contents of this method with the Code Editor.
<br /> private void InitializeComponent()
<br /> {
<br /> this.Paint += new System.Windows.Forms.<wbr>PaintEventHandler(this.<wbr>OnPaint);
<br /> }
<br />
<br /> #endregion
<br />
<br /> #region Constructors
<br />
<br /> /// <summary>
<br /> /// Constructor.
<br /> /// </summary>
<br /> public Button()
<br /> {
<br /> m_penBlack = new System.Drawing.Pen(Color.<wbr>Black);
<br /> m_penGray = new System.Drawing.Pen(Color.Gray)<wbr>;
<br /> m_penLightGray = new System.Drawing.Pen(Color.<wbr>Gainsboro);
<br /> m_penWhite = new System.Drawing.Pen(Color.<wbr>White);
<br />
<br /> // This call is required by the Windows.Forms Designer.
<br /> InitializeComponent();
<br /> }
<br />
<br /> #endregion
<br />
<br /> #region Enumerations
<br />
<br /> /// <summary>
<br /> /// Used to set the button style.
<br /> /// </summary>
<br /> public enum ButtonStyle
<br /> {
<br /> /// <summary>
<br /> /// Push button style.
<br /> /// </summary>
<br /> PushButton,
<br /> /// <summary>
<br /> /// Toggle button style.
<br /> /// </summary>
<br /> ToggleButton
<br /> }
<br />
<br /> /// <summary>
<br /> /// Used to set the vertical alignment of the text on the button.
<br /> /// </summary>
<br /> public enum TLocation
<br /> {
<br /> /// <summary>
<br /> /// Text at bottom of button.
<br /> /// </summary>
<br /> Bottom,
<br /> /// <summary>
<br /> /// Text at left of button.
<br /> /// </summary>
<br /> Left,
<br /> /// <summary>
<br /> /// Text at middle of button.
<br /> /// </summary>
<br /> Middle,
<br /> /// <summary>
<br /> /// Text at right of button.
<br /> /// </summary>
<br /> Right,
<br /> /// <summary>
<br /> /// Text at top of button.
<br /> /// </summary>
<br /> Top
<br /> }
<br />
<br /> #endregion
<br />
<br /> #region Variables
<br />
<br /> private System.ComponentModel.<wbr>Container components = null;
<br /> private Pen m_penBlack;
<br /> private Pen m_penGray;
<br /> private Pen m_penLightGray;
<br /> private Pen m_penWhite;
<br /> private Bitmap m_bitBackground = null;
<br /> private object m_oControlTag = false;
<br /> private Image m_imgDisabled = null;
<br /> private Image m_imgPressed = null;
<br /> private Image m_imgUnPressed = null;
<br /> private bool m_bPressed = false;
<br /> private ButtonStyle m_ButtonStyle = ButtonStyle.PushButton;
<br /> private TLocation m_textLocation = TLocation.Middle;
<br /> private string m_sText2 = "";
<br /> private Color m_textColor;
<br />
<br /> #endregion
<br />
<br /> #region Properties
<br />
<br /> // Store a bitmap that is created when the button gets the focus.
<br /> // Used to show the dotted lines when the button has the focus.
<br /> private Bitmap BitBackground
<br /> {
<br /> get
<br /> {
<br /> return m_bitBackground;
<br /> }
<br /> set
<br /> {
<br /> m_bitBackground = value;
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Get or set the tag for the control.
<br /> /// </summary>
<br /> public object ControlTag
<br /> {
<br /> get
<br /> {
<br /> return m_oControlTag;
<br /> }
<br /> set
<br /> {
<br /> m_oControlTag = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> #if NETCFDESIGNTIME
<br /> // These design time attributes affect appearance of this property in the property grid.
<br /> [Description("The image displayed when the button is in its disabled state."), Category("Custom Settings"), DefaultValue(null, "none")]
<br /> #endif
<br /> /// <summary>
<br /> /// Image to be displayed on the button when the button is disabled.
<br /> /// </summary>
<br /> public Image ImageDisabled
<br /> {
<br /> get
<br /> {
<br /> return m_imgDisabled;
<br /> }
<br /> set
<br /> {
<br /> m_imgDisabled = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> #if NETCFDESIGNTIME
<br /> // These design time attributes affect appearance of this property in the property grid.
<br /> [Description("The image displayed when the button is in its pressed state."), Category("Custom Settings"), DefaultValue(null, "none")]
<br /> #endif
<br /> /// <summary>
<br /> /// Image displayed on the button when the button is in the pressed state.
<br /> /// </summary>
<br /> public Image ImagePressed
<br /> {
<br /> get
<br /> {
<br /> return m_imgPressed;
<br /> }
<br /> set
<br /> {
<br /> m_imgPressed = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> #if NETCFDESIGNTIME
<br /> // These design time attributes affect appearance of this property in the property grid.
<br /> [Description("The image displayed when the button is in its unpressed state."), Category("Custom Settings"), DefaultValue(null, "none")]
<br /> #endif
<br /> /// <summary>
<br /> /// Image displayed on the button when the button is in the unpressed state.
<br /> /// </summary>
<br /> public Image ImageUnPressed
<br /> {
<br /> get
<br /> {
<br /> return m_imgUnPressed;
<br /> }
<br /> set
<br /> {
<br /> m_imgUnPressed = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> #if NETCFDESIGNTIME
<br /> // These design time attributes affect appearance of this property in the property grid.
<br /> [Description("True sets the button in the pushed state, false otherwise."),Category("Custom Settings"), DefaultValue(typeof(bool), "False")]
<br /> #endif
<br /> /// <summary>
<br /> /// Get or set the pressed stated of the button.
<br /> /// </summary>
<br /> public bool Pressed
<br /> {
<br /> get
<br /> {
<br /> return m_bPressed;
<br /> }
<br /> set
<br /> {
<br /> m_bPressed = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> #if NETCFDESIGNTIME
<br /> // These design time attributes affect appearance of this property in the property grid.
<br /> [Description("Set the button style to be push or toggle button."),Category("Custom Settings"), DefaultValue(typeof(<wbr>ButtonStyle), "PushButton")]
<br /> #endif
<br /> /// <summary>
<br /> /// Get or Set the button style.
<br /> /// </summary>
<br /> public ButtonStyle Style
<br /> {
<br /> get
<br /> {
<br /> return m_ButtonStyle;
<br /> }
<br /> set
<br /> {
<br /> m_ButtonStyle = value;
<br /> Pressed = false;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Set the text when changed.
<br /> /// </summary>
<br /> public override string Text
<br /> {
<br /> get
<br /> {
<br /> return base.Text;
<br /> }
<br /> set
<br /> {
<br /> base.Text = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> #if NETCFDESIGNTIME
<br /> // These design time attributes affect appearance of this property in the property grid.
<br /> [Description("The vertical location of the button text."),Category("Custom Settings"), DefaultValue(typeof(TLocation)<wbr>, "Middle")]
<br /> #endif
<br /> /// <summary>
<br /> /// Location where the text is to be displayed on the button.
<br /> /// </summary>
<br /> public TLocation TextLocation
<br /> {
<br /> get
<br /> {
<br /> return m_textLocation;
<br /> }
<br /> set
<br /> {
<br /> m_textLocation = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br />#if NETCFDESIGNTIME
<br /> // These design time attributes affect appearance of this property in the property grid.
<br /> [Description("The text for the second line."),Category("Custom Settings"), DefaultValue(typeof(string), "")]
<br />#endif
<br /> /// <summary>
<br /> /// Set the text when changed.
<br /> /// </summary>
<br /> public string Text2
<br /> {
<br /> get
<br /> {
<br /> return m_sText2;
<br /> }
<br /> set
<br /> {
<br /> m_sText2 = value;
<br /> this.Invalidate();
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Color of the text to be displayed.
<br /> /// </summary>
<br /> private Color TextColor
<br /> {
<br /> get
<br /> {
<br /> return this.m_textColor;
<br /> }
<br /> set
<br /> {
<br /> this.m_textColor = value;
<br /> }
<br /> }
<br />
<br /> #endregion
<br />
<br /> #region Functions
<br />
<br /> /// <summary>
<br /> /// Create a bitmap image.
<br /> /// </summary>
<br /> /// <param name="r">Rectangle.</param>
<br /> /// <returns>Returns a bitmap image.</returns>
<br /> private Bitmap CreateBitmap(Rectangle r)
<br /> {
<br /> Bitmap bit = new Bitmap(this.Width, this.Height);
<br /> Graphics g = Graphics.FromImage(bit);
<br />
<br /> // Fill the bitmap with the background color.
<br /> g.FillRectangle(new SolidBrush(this.BackColor), 0, 0, bit.Width, bit.Height);
<br />
<br /> // Set the pixels for the horizontal dashed lines.
<br /> for(int i = 5; i < r.Width - 4; i++)
<br /> {
<br /> bit.SetPixel(i, 4, Color.FromArgb(64, 64, 64));
<br /> i += 1;
<br /> }
<br /> for(int i = 6; i < r.Width - 4; i++)
<br /> {
<br /> bit.SetPixel(i, r.Height - 5, Color.FromArgb(64, 64, 64));
<br /> i += 1;
<br /> }
<br />
<br /> // Set the pixels for the vertical dashed lines.
<br /> for(int i = 5; i < r.Height - 3; i++)
<br /> {
<br /> bit.SetPixel(4, i, Color.FromArgb(64, 64, 64));
<br /> i += 1;
<br /> }
<br /> for(int i = 4; i < r.Height - 5; i++)
<br /> {
<br /> bit.SetPixel(r.Width - 5, i, Color.FromArgb(64, 64, 64));
<br /> i += 1;
<br /> }
<br />
<br /> return bit;
<br /> }
<br />
<br /> /// <summary>
<br /> /// Draw the text on the graphics object.
<br /> /// </summary>
<br /> /// <param name="e">PaintEventArgs.</<wbr>param>
<br /> /// <param name="r">Client rectangle.</param>
<br /> /// <param name="iImageWidth">Image width.</param>
<br /> private void DrawText(PaintEventArgs e, Rectangle r, int iImageWidth)
<br /> {
<br /> SizeF size = e.Graphics.MeasureString(this.<wbr>Text, this.Font);
<br /> SizeF size2 = e.Graphics.MeasureString(this.<wbr>Text2, this.Font);
<br /> int iGap = 2;
<br />
<br /> // Shift the text if the button is pressed.
<br /> if (Pressed)
<br /> {
<br /> if (Text2.Length == 0)
<br /> {
<br /> // Center the text inside the client area of the button.
<br /> // Set the vertical location of the text.
<br /> switch(TextLocation)
<br /> {
<br /> case TLocation.Bottom:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width + 2) / 2, (r.Height - size.Height) - 2);
<br /> break;
<br /> case TLocation.Left:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width + 2) / 2) - iImageWidth, (r.Height - size.Height) / 2);
<br /> break;
<br /> case TLocation.Middle:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width + 2) / 2, (r.Height - size.Height) / 2);
<br /> break;
<br /> case TLocation.Right:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width + 2) / 2) + iImageWidth, (r.Height - size.Height) / 2);
<br /> break;
<br /> case TLocation.Top:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width + 2) / 2, 5);
<br /> break;
<br /> }
<br /> }
<br /> else
<br /> {
<br /> // Center the text inside the client area of the button.
<br /> // Set the vertical location of the text.
<br /> switch(TextLocation)
<br /> {
<br /> case TLocation.Bottom:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width + 2) / 2, (r.Height - (2*size.Height)) - 2 + iGap);
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), (r.Width - size2.Width + 2) / 2, (r.Height - size.Height) - 2 - iGap);
<br /> break;
<br /> case TLocation.Left:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width + 2) / 2) - iImageWidth, ((r.Height / 2) - size.Height + iGap));
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), ((r.Width - size2.Width + 2) / 2) - iImageWidth, (r.Height / 2) - iGap);
<br /> break;
<br /> case TLocation.Middle:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width + 2) / 2, ((r.Height / 2) - size.Height + iGap));
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), (r.Width - size2.Width + 2) / 2, (r.Height / 2) - iGap);
<br /> break;
<br /> case TLocation.Right:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width + 2) / 2) + iImageWidth, ((r.Height / 2) - size.Height + iGap));
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), ((r.Width - size2.Width + 2) / 2) + iImageWidth, (r.Height / 2) - iGap);
<br /> break;
<br /> case TLocation.Top:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width + 2) / 2, 6 + iGap);
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), (r.Width - size2.Width + 2) / 2, (size2.Height + 6) - iGap);
<br /> break;
<br /> }
<br /> }
<br /> }
<br /> else
<br /> {
<br /> if (Text2.Length == 0)
<br /> {
<br /> // Center the text inside the client area of the button.
<br /> // Set the vertical location of the text.
<br /> switch(TextLocation)
<br /> {
<br /> case TLocation.Bottom:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width) / 2, (r.Height - size.Height - 1) - 2);
<br /> break;
<br /> case TLocation.Left:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width) / 2) - iImageWidth, (r.Height - size.Height - 2) / 2);
<br /> break;
<br /> case TLocation.Middle:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width) / 2, (r.Height - size.Height - 2) / 2);
<br /> break;
<br /> case TLocation.Right:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width) / 2) + iImageWidth, (r.Height - size.Height - 2) / 2);
<br /> break;
<br /> case TLocation.Top:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width) / 2, 4);
<br /> break;
<br /> }
<br /> }
<br /> else
<br /> {
<br /> switch(TextLocation)
<br /> {
<br /> case TLocation.Bottom:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width) / 2, (r.Height - (2*size.Height) - 1) - 2 + iGap);
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), (r.Width - size2.Width) / 2, (r.Height - size.Height - 1) - 2 - iGap);
<br /> break;
<br /> case TLocation.Left:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width) / 2) - iImageWidth, ((r.Height / 2) - size.Height) - 1 + iGap);
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), ((r.Width - size2.Width) / 2) - iImageWidth, (r.Height / 2) - 1 - iGap);
<br /> break;
<br /> case TLocation.Middle:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width) / 2, ((r.Height / 2) - size.Height - 1) + iGap);
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), (r.Width - size2.Width) / 2, (r.Height / 2) - 1 - iGap);
<br /> break;
<br /> case TLocation.Right:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), ((r.Width - size.Width) / 2) + iImageWidth, ((r.Height / 2) - size.Height - 1 + iGap));
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), ((r.Width - size2.Width) / 2) + iImageWidth, (r.Height / 2) - 1 - iGap);
<br /> break;
<br /> case TLocation.Top:
<br /> e.Graphics.DrawString(this.<wbr>Text, this.Font, new SolidBrush(TextColor), (r.Width - size.Width) / 2, 5 + iGap);
<br /> e.Graphics.DrawString(this.<wbr>Text2, this.Font, new SolidBrush(TextColor), (r.Width - size2.Width) / 2, (size2.Height + 5 - iGap));
<br /> break;
<br /> }
<br /> }
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Get the image attributes to set the transparent color.
<br /> /// </summary>
<br /> /// <param name="img">Image.</param>
<br /> /// <returns>ImageAttributes of the image.</returns>
<br /> private ImageAttributes GetImageAttributes(Image img)
<br /> {
<br /> Bitmap bit = new Bitmap(img);
<br />
<br /> // Set the Attributes for the Transparent color
<br /> ImageAttributes imageAttr = new ImageAttributes();
<br /> Color colorTrans = bit.GetPixel(0, 0);
<br /> imageAttr.SetColorKey(<wbr>colorTrans, colorTrans);
<br />
<br /> return imageAttr;
<br /> }
<br />
<br /> #endregion
<br />
<br /> #region Controls
<br />
<br /> /// <summary>
<br /> /// Repaints the button after the button is clicked.
<br /> /// </summary>
<br /> /// <param name="e">EventArgs.</param>
<br /> protected override void OnClick(EventArgs e)
<br /> {
<br /> if (this.Enabled)
<br /> {
<br /> // Check if toggle is set.
<br /> if (Style == ButtonStyle.ToggleButton)
<br /> {
<br /> // Toggle the pressed state.
<br /> if (Pressed)
<br /> {
<br /> Pressed = false;
<br /> }
<br /> else
<br /> {
<br /> Pressed = true;
<br /> }
<br /> }
<br /> else
<br /> {
<br /> this.Pressed = false;
<br /> }
<br />
<br /> this.Invalidate();
<br /> base.OnClick (e);
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Repaints the button in the enabled/disabled state.
<br /> /// </summary>
<br /> /// <param name="e">EventArgs.</param>
<br /> protected override void OnEnabledChanged(EventArgs e)
<br /> {
<br /> this.Invalidate();
<br /> base.OnEnabledChanged(e);
<br /> }
<br />
<br /> /// <summary>
<br /> /// Sets the focus to the control.
<br /> /// </summary>
<br /> /// <param name="e">EventArgs.</param>
<br /> protected override void OnGotFocus(EventArgs e)
<br /> {
<br /> if (this.Enabled)
<br /> {
<br /> this.Focus();
<br /> this.Invalidate();
<br /> base.OnGotFocus(e);
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Removes focus from the control.
<br /> /// </summary>
<br /> /// <param name="e">EventArgs.</param>
<br /> protected override void OnLostFocus(EventArgs e)
<br /> {
<br /> this.Invalidate();
<br /> base.OnLostFocus(e);
<br /> }
<br />
<br /> /// <summary>
<br /> /// Sets the button to be pressed.
<br /> /// </summary>
<br /> /// <param name="e">MouseEventArgs.</<wbr>param>
<br /> protected override void OnMouseDown (MouseEventArgs e)
<br /> {
<br /> if (this.Enabled)
<br /> {
<br /> // Check if the left mouse button was pressed.
<br /> if (e.Button == MouseButtons.Left)
<br /> {
<br /> // Check if toggle is set.
<br /> if (Style != ButtonStyle.ToggleButton)
<br /> {
<br /> this.Pressed = true;
<br /> }
<br />
<br /> this.Focus();
<br /> this.Invalidate();
<br /> }
<br />
<br /> base.OnMouseDown(e);
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Repaints the button when the mouse is moved.
<br /> /// </summary>
<br /> /// <param name="e">MouseEventArgs.</<wbr>param>
<br /> protected override void OnMouseMove(System.Windows.<wbr>Forms.MouseEventArgs e)
<br /> {
<br /> if (this.Enabled)
<br /> {
<br /> // Check if toggle is set.
<br /> if (Style != ButtonStyle.ToggleButton)
<br /> {
<br /> // Check if the left mouse button was pressed.
<br /> if (e.Button == MouseButtons.Left)
<br /> {
<br /> // Paint the button in the unpressed state when the mouse is not over the button.
<br /> if ((Pressed) && (!this.ClientRectangle.<wbr>Contains(e.X, e.Y)))
<br /> {
<br /> Pressed = false;
<br /> this.Invalidate();
<br /> }
<br /> else if ((!Pressed) && (this.ClientRectangle.<wbr>Contains(e.X, e.Y)))
<br /> {
<br /> Pressed = true;
<br /> this.Invalidate();
<br /> }
<br /> }
<br /> }
<br />
<br /> base.OnMouseMove(e);
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Resets the button.
<br /> /// </summary>
<br /> /// <param name="e">MouseEventArgs.</<wbr>param>
<br /> protected override void OnMouseUp (MouseEventArgs e)
<br /> {
<br /> if (this.Enabled)
<br /> {
<br /> // Check if toggle is set.
<br /> if (Style != ButtonStyle.ToggleButton)
<br /> {
<br /> this.Pressed = false;
<br /> }
<br />
<br /> this.Invalidate();
<br /> base.OnMouseUp(e);
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// This Paint function uses routines common to both platforms.
<br /> /// </summary>
<br /> private void OnPaint(object sender, System.Windows.Forms.<wbr>PaintEventArgs e)
<br /> {
<br /> Rectangle rcClient = this.ClientRectangle;
<br /> int intImageWidth = 0;
<br />
<br /> // Set the text color to be grayed or the forecolor.
<br /> if (this.Enabled == false)
<br /> {
<br /> TextColor = System.Drawing.SystemColors.<wbr>GrayText;
<br /> }
<br /> else
<br /> {
<br /> TextColor = this.ForeColor;
<br />
<br /> // Draw the dotted lines that shows the button has the focus.
<br /> if (this.Focused)
<br /> {
<br /> // Create the bitmap image.
<br /> if (BitBackground == null)
<br /> {
<br /> BitBackground = CreateBitmap(rcClient);
<br /> }
<br />
<br /> // Draw the bitmap that was created and stored.
<br /> e.Graphics.DrawImage((Image)<wbr>BitBackground, 0, 0);
<br /> }
<br /> }
<br />
<br /> // Draw the lines that makeup the button image.
<br /> e.Graphics.DrawLine(m_penGray, 0, 0, rcClient.Width - 1, 0);
<br /> e.Graphics.DrawLine(m_penGray, 0, 0, 0, rcClient.Height - 1);
<br /> e.Graphics.DrawLine(m_<wbr>penLightGray, 1, 1, rcClient.Width - 2, 1);
<br /> e.Graphics.DrawLine(m_<wbr>penLightGray, 1, 1, 1, rcClient.Height - 2);
<br /> e.Graphics.DrawLine(m_penGray, 1, rcClient.Height - 2, rcClient.Width - 2, rcClient.Height - 2);
<br /> e.Graphics.DrawLine(m_penGray, rcClient.Width - 2, 1, rcClient.Width - 2, rcClient.Height - 2);
<br /> e.Graphics.DrawLine(m_<wbr>penBlack, 0, rcClient.Height - 1, rcClient.Width - 1, rcClient.Height - 1);
<br /> e.Graphics.DrawLine(m_<wbr>penBlack, rcClient.Width - 1, 0, rcClient.Width - 1, rcClient.Height - 1);
<br />
<br /> // Check if the button is using an image.
<br /> if (ImageUnPressed != null)
<br /> {
<br /> intImageWidth = ImageUnPressed.Width / 2;
<br /> int intImageLeft = (rcClient.Width - ImageUnPressed.Width) / 2;
<br /> int intImageTop = (rcClient.Height - ImageUnPressed.Height) / 2;
<br /> Rectangle imgRect;
<br />
<br /> // If the text is being used, set the location of the image to be above, below, or in the middle of the text.
<br /> if (this.Text.Length > 0)
<br /> {
<br /> switch(TextLocation)
<br /> {
<br /> case TLocation.Bottom:
<br /> intImageTop = intImageTop - 5;
<br /> break;
<br /> case TLocation.Left:
<br /> intImageLeft = (rcClient.Width - ImageUnPressed.Width) - 5;
<br /> break;
<br /> case TLocation.Middle:
<br /> // Nothing to do here.
<br /> break;
<br /> case TLocation.Right:
<br /> intImageLeft = 5;
<br /> break;
<br /> case TLocation.Top:
<br /> intImageTop = intImageTop + 5;
<br /> break;
<br /> }
<br /> }
<br />
<br /> // Shift the image if the button is pressed.
<br /> if (Pressed)
<br /> {
<br /> imgRect = new Rectangle(intImageLeft + 1, intImageTop + 1, ImageUnPressed.Width, ImageUnPressed.Height);
<br />
<br /> // Draw the unpressed image if it was set.
<br /> if (ImagePressed != null)
<br /> {
<br /> // Get the Attributes for the Transparent color
<br /> ImageAttributes imageAttr = GetImageAttributes(<wbr>ImagePressed);
<br />
<br /> // Draw the pressed image if set.
<br /> e.Graphics.DrawImage(<wbr>ImagePressed, imgRect, 0, 0, ImagePressed.Width, ImagePressed.Height, GraphicsUnit.Pixel, imageAttr);
<br /> }
<br /> else
<br /> {
<br /> // Get the Attributes for the Transparent color
<br /> ImageAttributes imageAttr = GetImageAttributes(<wbr>ImageUnPressed);
<br />
<br /> // Draw the unpressed image.
<br /> e.Graphics.DrawImage(<wbr>ImageUnPressed, imgRect, 0, 0, ImageUnPressed.Width, ImageUnPressed.Height, GraphicsUnit.Pixel, imageAttr);
<br /> }
<br /> }
<br /> else
<br /> {
<br /> // Draw the unpressed image if set.
<br /> imgRect = new Rectangle(intImageLeft, intImageTop, ImageUnPressed.Width, ImageUnPressed.Height);
<br />
<br /> // Check which image to set.
<br /> if (this.Enabled == false)
<br /> {
<br /> // Set the ImageDisabled if the button is disabled.
<br /> if (ImageDisabled != null)
<br /> {
<br /> // Get the Attributes for the Transparent color
<br /> ImageAttributes imageAttr = GetImageAttributes(<wbr>ImageDisabled);
<br />
<br /> e.Graphics.DrawImage(<wbr>ImageDisabled, imgRect, 0, 0, ImageDisabled.Width, ImageDisabled.Height, GraphicsUnit.Pixel, imageAttr);
<br /> }
<br /> else
<br /> {
<br /> // Get the Attributes for the Transparent color
<br /> ImageAttributes imageAttr = GetImageAttributes(<wbr>ImageUnPressed);
<br />
<br /> e.Graphics.DrawImage(<wbr>ImageUnPressed, imgRect, 0, 0, ImageUnPressed.Width, ImageUnPressed.Height, GraphicsUnit.Pixel, imageAttr);
<br /> }
<br /> }
<br /> else
<br /> {
<br /> // Get the Attributes for the Transparent color
<br /> ImageAttributes imageAttr = GetImageAttributes(<wbr>ImageUnPressed);
<br />
<br /> e.Graphics.DrawImage(<wbr>ImageUnPressed, imgRect, 0, 0, ImageUnPressed.Width, ImageUnPressed.Height, GraphicsUnit.Pixel, imageAttr);
<br /> }
<br /> }
<br /> }
<br />
<br /> // Draw the text if needed.
<br /> if (this.Text.Length > 0)
<br /> {
<br /> DrawText(e, rcClient, intImageWidth);
<br /> }
<br />
<br /> // Set the button appearance when pressed.
<br /> if (Pressed)
<br /> {
<br /> // Draw the lines that makeup the button image in the pressed position.
<br /> e.Graphics.DrawLine(m_<wbr>penBlack, 0, 0, rcClient.Width - 1, 0);
<br /> e.Graphics.DrawLine(m_<wbr>penBlack, 0, 0, 0, rcClient.Height - 1);
<br /> e.Graphics.DrawLine(m_<wbr>penBlack, 1, 1, rcClient.Width - 2, 1);
<br /> e.Graphics.DrawLine(m_<wbr>penBlack, 1, 1, 1, rcClient.Height - 2);
<br /> e.Graphics.DrawLine(m_<wbr>penLightGray, 1, rcClient.Height - 2, rcClient.Width - 2, rcClient.Height - 2);
<br /> e.Graphics.DrawLine(m_<wbr>penLightGray, rcClient.Width - 2, 1, rcClient.Width - 2, rcClient.Height - 2);
<br /> e.Graphics.DrawLine(m_<wbr>penWhite, 0, rcClient.Height - 1, rcClient.Width - 1, rcClient.Height - 1);
<br /> e.Graphics.DrawLine(m_<wbr>penWhite, rcClient.Width - 1, 0, rcClient.Width - 1, rcClient.Height - 1);
<br /> }
<br /> }
<br />
<br /> /// <summary>
<br /> /// Resize the control in the design view.
<br /> /// </summary>
<br /> /// <param name="e">EventArgs.</param>
<br /> protected override void OnResize(EventArgs e)
<br /> {
<br /> this.Refresh();
<br /> }
<br />
<br /> #endregion
<br /> }
<br />}
<br />
<br />
<br />You can always directly include this file to your project then use button in the code to dynamically generate a button. But if you want to use it like the button from toolbar, you have to do special thing if you are using Visual studio 2003.
<br />
<br />If you are using Visual Studio 2005 or 2008, it is very easy.
<br />
<br />1)Add you button.cs to you project.
<br />2)Include its namespace.
<br />3)From toolbar, you will find out there is one more category with "Pointer" "button" in it, which is the customized button you just created!!!
<br /></div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-35128333065514280602009-06-24T08:12:00.000-07:002009-06-24T08:13:45.205-07:00Understanding Garbage Collection in .NET<div><a href="http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/?utm_source=simpletalk&utm_medium=email&utm_content=GarbageCollection-20090624&utm_campaign=.NET" target="_blank">Understanding Garbage Collection in .NET</a></div> <div>17 June 2009</div> <div>by <a href="http://www.simple-talk.com/author/andrew-hunter/" target="_blank">Andrew Hunter</a></div> <br /><div> <div> <p>Once you understand how .NET's garbage collector works, then the reasons for some of the more mysterious problems that can hit a .NET application become much clearer. NET may have promised the end to explicit memory management, but it is still necessary to profile the usage of memory when you're developing .NET applications if you wish to avoid memory-related errors and some performance issues.</p> <p><span>.NET’s garbage collector has been sold to us as the end of explicit memory management, and of memory leaks, in Windows applications: the idea is that, with a garbage collector running in the background, developers no longer need to worry about the need to manage the life-cycle of the objects they create - the garbage collector will take care of them once the application has finished with them.</span></p> <p><span>The reality is more complicated than this, however. The garbage collector certainly solves the most common leaks in unmanaged programs - those caused by developers forgetting to release memory when they have finished with it. It also solves the related problem of memory being released too soon, but the way in which this is solved can lead to memory leaks when the garbage collector has a different opinion to the developer about whether or not an object is still ‘live’ and able to be used. Before fixing these problems, you need some understanding of how the collector works.</span></p> <h1>How the Garbage Collector works</h1> <p><span>How, then, does the garbage collector achieve its magic? The basic idea is pretty simple: it examines how objects are laid out in memory and identifies all those objects that can be ‘reached’ by the running program by following some series of references.</span></p> <p><span>When a garbage collection starts, it looks at a set of references called the ‘GC roots’. These are memory locations that are designated to be always reachable for some reason, and which contain references to objects created by the program. It marks these objects as ‘live’ and then looks at any objects that they reference; it marks these as being ‘live’ too. It continues in this manner, iterating through all of the objects it knows are ‘live’. It marks anything that they reference as also being used until it can find no further objects.</span></p> <p><span>An object is identified, by the Garbage Collector, as referencing another object if it, or one of its superclasses, has a field that contains the other object.</span></p> <p><span>Once all of these live objects are known, any remaining objects can be discarded and the space re-used for new objects. .NET compacts memory so that there are no gaps (effectively squashing the discarded objects out of existence) - this means that free memory is always located at the end of a heap and makes allocating new objects very fast.</span></p> <p><span>GC roots are not objects in themselves but are instead references to objects. Any object referenced by a GC root will automatically survive the next garbage collection. There are four main kinds of root in .NET:</span></p> <p><span>A local variable in a method that is currently running is considered to be a GC root. The objects referenced by these variables can always be accessed immediately by the method they are declared in, and so they must be kept around. The lifetime of these roots can depend on the way the program was built. In debug builds, a local variable lasts for as long as the method is on the stack. In release builds, the JIT is able to look at the program structure to work out the last point within the execution that a variable can be used by the method and will discard it when it is no longer required. This strategy isn’t always used and can be turned off, for example, by running the program in a debugger.</span></p> <p><span>Static variables are also always considered GC roots. The objects they reference can be accessed at any time by the class that declared them (or the rest of the program if they are public), so .NET will always keep them around. Variables declared as ‘thread static’ will only last for as long as that thread is running.</span></p> <p><span>If a managed object is passed to an unmanaged COM+ library through interop, then it will also become a GC root with a reference count. This is because COM+ doesn’t do garbage collection: It uses, instead, a reference counting system; once the COM+ library finishes with the object by setting the reference count to 0 it ceases to be a GC root and can be collected again.</span></p> <p><span>If an object has a finalizer, it is not immediately removed when the garbage collector decides it is no longer ‘live’. Instead, it becomes a special kind of root until .NET has called the finalizer method. This means that these objects usually require more than one garbage collection to be removed from memory, as they will survive the first time they are found to be unused.</span></p> <h2>The Object Graph</h2> <p><span>Taken as a whole, memory in .NET forms a complicated, knotted graph of references and cross-references. This can make it difficult to determine the amount of memory used by a particular object. For instance, the memory used by a List<x> object is quite small, as the List<x> class only has a few fields. However, one of these is the array of objects in the list: this can be quite large if the list has many entries. This is almost always exclusively ‘owned’ by the list, so the relationship is fairly simple: The total size of the list is the size of the small initial object and the large array it references. The objects in the array could be another matter entirely, though: it’s possible that there could be some other path through memory through which they could be reached. In this case, it doesn’t make sense to count them as part of the ‘size’ of the list as they would remain even if the list ceased to exist, but neither does it make sense to count them via the alternative path - they’d remain if that was removed as well. </span></p> <p><span>Things become even more confusing when circular references come into play.</span></p> <p><img src="http://www.simple-talk.com/iwritefor/articlefiles/737-image001.jpg" border="0" width="531" height="453" /></p> <p>When developing code, it’s more usual to think of memory as being organized into a more easily understood structure: a tree starting at individual roots:</p> <p><img src="http://www.simple-talk.com/iwritefor/articlefiles/737-image002.jpg" border="0" width="539" height="347" /></p> <p><span>Thinking in this way does, indeed, make it easier (or indeed possible) to think about how objects are laid out in memory. This is also how data is represented when writing the program or using a debugger, but this makes it easy to forget that an object can be attached to more than one root. This is usually where memory leaks in .NET come from: the developer forgets, or doesn’t ever realize, that an object is anchored to more than one root. Consider the case shown here: setting GC root 2 to null will not actually allow the garbage collector to remove any objects, which can be seen from looking at the complete graph but not from the tree.</span></p> <p><span>A memory profiler makes it possible to view the graph from another perspective, as a tree rooted at an individual object and following the references backwards to put the GC roots at the leaves. For the ClassC object referenced by root 2, we can follow the references backwards to get the following graph:</span></p> <p><img src="http://www.simple-talk.com/iwritefor/articlefiles/737-image003.jpg" border="0" width="425" height="350" /></p> <p><span>Thinking in this way reveals that the ClassC object has two ultimate ‘owners’, both of which must relinquish it before the garbage collector can remove it. Any of the links between GC root 3 and the object can be broken in order to remove it once GC root 2 has been set to null.</span></p> <p><span>This situation can arise easily in practical .NET applications. The most common one is that a data object becomes referenced by an element in the user interface, but isn’t removed when the data has been finished with. This situation isn’t quite a leak: the memory will be reclaimed when the UI control is updated with new data, but can mean that the application uses much more memory than would be expected. Event handlers are another common cause: it’s easy to forget that an object will last at least as long as the objects which it receives events from, which is forever in the case of some global event handlers such as those in the Application class.</span></p> <p><span>Real applications, especially those with user interface components, have much more complicated graphs than this. Even something as simple as a label in a dialog box can be referenced from a huge number of different places…</span></p> <p style="margin-left: 0px;"><img src="http://www.simple-talk.com/iwritefor/articlefiles/737-image004.jpg" border="0" width="640" height="271" /></p> <p><span>It’s easy to see how the occasional object can become lost in this maze.</span></p> <h1>Limits of the Garbage Collector</h1> <h2>Unused objects that are still referenced</h2> <p><span>The biggest limitation of the garbage collector in .NET is a subtle one: while it is sold as being able to detect and remove unused objects, it actually finds <i>unreferenced</i> objects. This is an important distinction: an object might never be referred to by a program ever again; but, while there is some path from it leading to an object that might still be used, it will never be released from memory. This leads to memory leaks; in .NET these occur when an object that will not be used again remains referenced.</span></p> <p><span>The source of these leaks can be hard to detect, though the symptoms of rising memory usage are obvious. It’s necessary to determine which unused objects are remaining in memory, and then trace the references to find out why they are not being collected. A memory profiler is essential for this task: By comparing memory states while a leak is occurring, it is possible to find the troublesome unused objects, but no debugger can trace object references backwards.</span></p> <p><span>The garbage collector is designed to deal with resources that are plentiful - that is, where it doesn’t matter when the object is released. On modern systems, memory falls into that category (it doesn’t matter when it’s reclaimed, just so long as it’s done in time to prevent a new allocation failing). There are still resources that don’t fall into this category: file handles need to be closed quickly to avoid causing sharing conflicts between applications, for example. These resources cannot be completely managed by the garbage collector, and so .NET provides the </span><span>Dispose</span><span>() method along with the </span><span>using</span><span>() construct for objects that manage these resources. In these cases the scarce resources used by the object are released quickly by the implementation of the </span><span>Dispose</span><span> method, but the much less critical memory is released later by the garbage collector.</span></p> <p><span>Dispose</span><span> means nothing special to .NET, so disposed objects must still be de-referenced. This makes objects that have been disposed but have not been reclaimed good candidates for the source of a memory leak.</span></p> <h2>Fragmentation of the Heap</h2> <p><span>A less widely known limitation in .NET is that of the large object heap. Objects that become part of this heap are never moved by the runtime, and this can lead to a program running out of memory prematurely. When some objects live longer than others, this causes the heap to form holes where objects used to be - this is known as fragmentation. The problem occurs when the program asks for a large block of memory but the heap has become so fragmented that there is no single region of memory big enough to accommodate it. A memory profiler can estimate the largest object that can be allocated by a program: if this is declining then this is likely to be the cause. An <span>OutOfMemoryException</span> caused by fragmentation will typically happen when the program apparently has a lot of free memory - on a 32-bit system, processes should be able to use at least 1.5Gb, but failures due to fragmentation will often start to occur before it is using that much memory.</span></p> <p><span>Another symptom of fragmentation is that .NET will often have to keep the memory used by the empty holes allocated to the application. This causes it to apparently use much more memory than it needs when viewed in Task Manager. This effect is usually relatively harmless: Windows is quite good at realising that the memory occupied by the holes is not being used and will page it out, and if the fragmentation is not worsening then the program won’t run out of memory. It doesn’t look good to the user, though, who will probably think that the application is wasteful and ‘bloated’. This is often what is happening when a profiler shows that the objects allocated by a program are only using a small amount of memory but Task Manager shows that the process is occupying a large amount of space.</span></p> <h1>Performance of the Garbage Collector</h1> <p><span>In terms of performance, the most important characteristic of a garbage collected system is that the garbage collector can start executing at any time. This makes them unsuited for situations where timing is critical, as the timing of any operation can be thrown off by the operation of the collector.</span></p> <p><span>The .NET collector has two main modes of operation: concurrent and synchronous (sometimes known as workstation and server). Concurrent garbage collection is used in desktop applications and synchronous is used in server applications such as <a href="http://asp.net/" target="_blank">ASP.NET</a> by default.</span></p> <p><span>In concurrent mode, .NET will try to avoid stopping the running program while a collection is in progress. This means that the total amount that the application can get done in a given period of time is less but the application won’t pause. It’s good for interactive applications where it’s important to give the impression to the user that the application is responding immediately.</span></p> <p><span>In synchronous mode, .NET will suspend the running application while the garbage collector is running. This is actually more efficient overall than concurrent mode - garbage collection takes the same amount of time, but it doesn’t have to contend with the program continuing to run - but means that there can be noticeable pauses when a full collection has to be done.</span></p> <p><span>The type of garbage collector can be set in the configuration file for the application if the default isn’t suitable. Picking the synchronous collector can be useful when it’s more important that an application has a high throughput instead of appearing responsive.</span></p> <p><span>In large applications, the number of objects that the garbage collector needs to deal with can become very large, which means it can take a very long time to visit and rearrange all of them. To deal with this, .NET uses a ‘generational’ garbage collector, which tries to give priority to a smaller set of objects. The idea is that objects created recently are more likely to be released quickly, so a generational garbage collector prioritises them when trying to free up memory, so .NET first looks at the objects that have been allocated since the last garbage collection and only starts to consider older objects if it can’t free up enough space this way.</span></p> <p><span>This system works best if .NET can choose the time of collection itself, and will be disrupted if </span><span>GC.Collect</span><span>() is called, as this will often cause new objects to become old prematurely, which increases the likelihood of another expensive full collection in the near future.</span></p> <p><span>Classes with finalizers can also disrupt the smooth operation of the garbage collector. Objects of these classes can’t be removed immediately: they instead go to the finalizer queue and are removed from memory once the finalizer has been run. This means that any object they reference (and any object referenced by those, and so on) has to be kept in memory at least until this time as well and will require two garbage collections before the memory becomes available again. If the graph contains many objects with finalizers, this can mean that the garbage collector requires many passes to completely release all of the unreferenced objects.</span></p> <p><span>There is a simple way to avoid this problem: implement </span><span>IDisposable</span><span> on the finalizable classes, move the actions necessary to finalize the object into the </span><span>Dispose()</span><span> method and call </span><span>GC.SuppressFinalize()</span><span> at the end. The finalizer can then be modified to call the </span><span>Dispose()</span><span> method instead. </span><span>GC.SuppressFinalize()</span><span> tells the garbage collector that the object no longer needs to be finalized and can be garbage collected immediately, which can result in memory being reclaimed much more quickly.</span></p> <h1>Conclusion</h1> <p><span>It becomes easier to understand memory and performance problems in an application if you take time to understand how the garbage collector works. It reveals that, while .NET makes the burden of memory management lighter, it does not completely eliminate the need to track and manage resources. It is, however, easier to use a memory profiler to diagnose and fix problems in .NET. Taking account of the way .NET manages memory early in development can help reduce problems, but even then such problems can still arise because of the complexity of the framework or third-party libraries.</span></p></div> <br /><br />This article has been viewed 3431 times. </div> <div> <a title="Andrew Hunter" href="http://www.simple-talk.com/author/andrew-hunter/" target="_blank"><img src="http://www.simple-talk.com/iwritefor/publishers/149.gif" alt="Andrew Hunter" style="border-width: 0px;" align="left" /></a> <p><strong>Author profile:</strong> <a href="http://www.simple-talk.com/author/andrew-hunter/" target="_blank">Andrew Hunter</a></p> <p>Andrew Hunter is a Software Engineer at Red Gate who is responsible for much of the recent rewrite of ANTS. Before that, he wrote the SQL Layout utilities for SQL Refactor/SQL Prompt. He has been described as resident master of the dark .NET arts. Dereferenced in a freak accident, he is forced to spend his days hiding from the garbage collector.</p> <p><a href="http://www.simple-talk.com/author/andrew-hunter/" target="_blank">Search for other articles by Andrew Hunter</a></p> </div> <div> <strong>Rate this article:</strong> Avg rating: <img src="http://www.simple-talk.com/images/interface/icon_net_5star_70x13.gif" style="border-width: 0px; height: 13px; width: 70px;" /> from a total of 32 votes.<br /><br /> <div> <table border="0"> <tbody><tr> <td><input name="ctl00$MainContent$radRating" value="radRating1" type="radio"><br />Poor</td> <td><input name="ctl00$MainContent$radRating" value="radRating2" type="radio"><br />OK</td> <td><input name="ctl00$MainContent$radRating" value="radRating3" type="radio"><br />Good</td> <td><input name="ctl00$MainContent$radRating" value="radRating4" type="radio"><br />Great</td> <td><input name="ctl00$MainContent$radRating" value="radRating5" type="radio"><br />Must read</td> <td> <input name="ctl00$MainContent$btnRateArticle" title="Rate article" src="http://www.simple-talk.com/images/interface/btn_submit.gif" style="border-width: 0px; height: 19px; width: 56px;" type="image"> </td> </tr> </tbody></table> </div> </div> <a name="12212d2e1f58fd64_forum"> </a> <div> <div>Have Your Say</div> Do you have an opinion on this article? Then <a href="http://www.simple-talk.com/dotnet/.net-framework/understanding-garbage-collection-in-.net/?utm_source=simpletalk&utm_medium=email&utm_content=GarbageCollection-20090624&utm_campaign=.NET#commentform" target="_blank"><u>add your comment below</u></a>: </div> <br /><hr /> <table border="0" cellpadding="0" cellspacing="4" width="500"> <tbody><tr><td>Subject: </td><td><b><span>Large Object Heap</span></b></td></tr> <tr><td>Posted by: </td><td><i><span>Jon</span></i> (<a href="http://www.simple-talk.com/community/user/Profile.aspx?UserID=7905" target="_blank">view profile</a>)</td> </tr> <tr><td>Posted on: </td><td><i><span>Friday, June 19, 2009 at 4:20 PM</span></i></td></tr> <tr><td valign="top">Message: </td><td><span>If you do run into fragmentation problems with the Large Object Heap, it can sometimes be useful to break up your object into smaller objects that won't be put in the LOH. Here's an example of doing that with a MemoryStream:<br /><a href="http://blueonionsoftware.com/blog.aspx?p=61115cc1-7188-44d3-b8c0-8ef8a618fae6" target="_blank">http://blueonionsoftware.com/<wbr>blog.aspx?p=61115cc1-7188-<wbr>44d3-b8c0-8ef8a618fae6</a></span></td></tr> </tbody></table> <hr /> <table border="0" cellpadding="0" cellspacing="4" width="500"> <tbody><tr><td>Subject: </td><td><b><span>Generational Garbage collection demonstration</span></b></td></tr> <tr><td>Posted by: </td><td><i><span>NoMoreHacks</span></i> (<span>not signed in</span>)</td></tr> <tr><td>Posted on: </td><td><i><span>Wednesday, June 24, 2009 at 1:47 AM</span></i></td></tr> <tr><td valign="top">Message: </td><td><span>I created a demo to show the effects of generational garbage collection in systems that require high-throughput with low latency. The code and article are here<br /><br /><a href="http://nomorehacks.wordpress.com/2008/11/27/forcing-the-garbage-collector/" target="_blank">http://nomorehacks.wordpress.<wbr>com/2008/11/27/forcing-the-<wbr>garbage-collector/</a><br /></span></td></tr> </tbody></table> <hr /> <table border="0" cellpadding="0" cellspacing="4" width="500"><tbody><tr><td>Subject: </td><td><b><span>.NET Memory Management</span></b></td> </tr> <tr><td>Posted by: </td><td><i><span>grabnerandi</span></i> (<a href="http://www.simple-talk.com/community/user/Profile.aspx?UserID=16399" target="_blank">view profile</a>)</td> </tr> <tr><td>Posted on: </td><td><i><span>Wednesday, June 24, 2009 at 9:07 AM</span></i></td></tr> <tr><td valign="top">Message: </td><td><span>Hi Andrew<br />Thanks for the very detailed explaination of the .NET Gargabe Collector. Although we live in the managed world for a while now it is always good to refresh our memory about how GC works internally.<br />I've been doing some work regarding .NET Memory Management myself and I posted some of these findings at <a href="http://blog.dynatrace.com/tag/memory/" target="_blank">http://blog.dynatrace.com/tag/<wbr>memory/</a><br />I also compared the the different LatencyMode's that the GC has to offer: <a href="http://blog.dynatrace.com/2009/04/13/performance-analysis-comparing-interactive-and-low-latency-gc-strategies-in-net/" target="_blank">http://blog.dynatrace.com/<wbr>2009/04/13/performance-<wbr>analysis-comparing-<wbr>interactive-and-low-latency-<wbr>gc-strategies-in-net/</a><br /><br />Cheers<br />Andi</span></td></tr></tbody></table>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-73624077676194246732009-06-24T06:46:00.000-07:002009-06-24T06:51:09.780-07:00How to use C++ APIs in C# application?Presenting a C++ library (.lib) for use in C# project?<a href="http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/299da822-5539-4e5b-9ba7-b614e564c9f4">Presenting a C++ library (.lib) for use in C# project</a><br /><br />Q:<br />I have a collection of C++ programs and the C++ libraries they use. The libraries currently compile to a .lib format. Changing the project property to use a .dll results in multiple reference errors.<br /><br />Without having to go through the entire collection of source files, is there a way to create any kind of project in a .NET language that would provide a "wrapper" for the existing .lib files so that they could be used in that environment.<br /><br />Thanks.<br /><br />A:<br /><p>Yes (sort of) but it's non-trivial.</p> <p>Let's start with some background. Your project to compile to a .lib format is generating something known as a "static library". Static libraries are chunks of native code built to be combined with other pieces of code via the linker. You #include a header file that describes the functions/classes that you want to use and then link to the .lib file to provide the implementations of those functions/classes.</p> <p>You can't use that approach with a C# client because C# generates managed code and you just can't directly link native code to managed code.</p> <p>There are three ways (I can think of) to consume native code from a managed code client</p> <ol><li>You turn the native code into a native code COM object using the static library to provide the implementation of the COM object's methods and then use COM Interop to invoke the (native) COM object from the managed code client</li><li>You turn the native code into a native code DLL that exports some suitable entry points (again, using the static library to provide the actual implementation) and then call those DLL entry points from the managed code client using P/Invoke</li><li>You create a managed code Class Library using C++ and use the static library to provide the underlying implementation of that managed class library </li></ol> <p>Let's say your static library's header file looks like this</p> <table border="0" cellspacing="0" width="100%"><tbody><tr><td width="15"><br /></td><td bgcolor="lightgrey" width="15"><br /></td><td bg style="color:lightgrey;"><br /><span style="font-family:Lucida Console;font-size:85%;"><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">namespace</span></span><span style="font-size:85%;"> MathFuncs<br />{<br /></span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">class</span></span><span style="font-size:85%;"> MyMathFuncs<br />{<br /></span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">public</span></span><span style="font-size:85%;">:<br /></span><span style="font-size:85%;color:#008000;">// Returns a + b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Add(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b);<br /></span><span style="font-size:85%;color:#008000;">// Returns a - b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Subtract(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b);<br /></span><span style="font-size:85%;color:#008000;">// Returns a * b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Multiply(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b);<br /></span><span style="font-size:85%;color:#008000;">// Returns a / b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#008000;">// Throws DivideByZeroException if b is 0</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Divide(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b);<br />};<br />}</span><br /> </span></td></tr></tbody></table> <p>Using approach #1, you'd create a new project using the Visual C++ | ATL | ATL Server project template. You'd add a new simple ATL object to the project that exported Add, Subtract, Multiply and Divide methods. You'd #include your static library's header file to provide the underlying implementation of Add, Subtract etc and you'd have your COM object's Add method call the underlying MathFuncs::MyMathFuncs::Add method (and return the result). Finally, you'd make sure your COM object project linked to your static library .lib file as part of the build process.</p> <p>To consume the 'wrapper' from a C# program, you'd use Add | Reference to add a COM reference to your COM object and then just cal the COM object's methods as necessary.</p> <p>Using approach #2, you'd create a new project using the Visual C++ | Win32 | Win32 Project template and use Application Settings to change Application Type to DLL and set Additional Options to "Export symbols". Then you would create some exported entry points (like Add, Subtract etc) to be consumed by the client. Again, you would #include your static library's header file to get function descriptions and link to the .lib file to get actual implementations. You'd code your exported DLL entry points to call the static library's 'real' implementation methods and return the result.</p> <p>To consume this kind of wrapper, you would use the C# DllImportAttribute to declare the DLL entry point in C# terms and then just call the function as needed.</p> <p>Finally, using appoach #3, you'd create a managed C++ project using Visual C++ | CLR | Class Library. You'd create a managed class (a 'ref' class) which would be called by your C# client. Again, you'd #include the native code header file and link to the .lib file to get the actual implementation of the methods you want the client to be able to call. The managed code wrapper for the above header file might look something like this...</p> <table border="0" cellspacing="0" width="100%"><tbody><tr><td width="15"><br /></td><td bgcolor="lightgrey" width="15"><br /></td><td bg style="color:lightgrey;"><br /><span style="font-family:Lucida Console;font-size:85%;"><span style="font-size:85%;color:#0000ff;">#include</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#800000;">"MathFuncsLib.h"</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"> #pragma</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;">once<br /><span style="color:blue;">using</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">namespace</span></span><span style="font-size:85%;"> System;</span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">namespace</span></span><span style="font-size:85%;"> ManagedMathFuncsLib {<br /></span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">public</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">ref</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">class</span></span><span style="font-size:85%;"> Class1<br />{<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">public</span></span><span style="font-size:85%;">:<br /> Class1 ()<br /> {<br /> };<br /></span><span style="font-size:85%;color:#008000;"> // Returns a + b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Add(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b)<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">return</span></span><span style="font-size:85%;"> MathFuncs::MyMathFuncs::Add (a, b);<br /> }<br /></span><span style="font-size:85%;color:#008000;"> // Returns a - b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Subtract(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b)<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">return</span></span><span style="font-size:85%;"> MathFuncs::MyMathFuncs::<wbr>Subtract (a, b);<br /> };<br /></span><span style="font-size:85%;color:#008000;"> // Returns a * b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Multiply(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b)<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">return</span></span><span style="font-size:85%;"> MathFuncs::MyMathFuncs::<wbr>Multiply (a, b);<br /> };<br /></span><span style="font-size:85%;color:#008000;"> // Returns a / b</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#008000;"> // Throws DivideByZeroException if b is 0</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">static</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> Divide(</span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> a, </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">double</span></span><span style="font-size:85%;"> b)<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">return</span></span><span style="font-size:85%;"> MathFuncs::MyMathFuncs::Divide (a, b);<br /> };<br />};}</span><br /> </span></td></tr></tbody></table> <p>To consume this managed code wrapper, you'd use Add | Reference to add a .NET Reference (to your managed wrapper) to your client program and then would call the managed (ref) class's methods as necessary.</p> <p>In all three cases above, I simplified things by using static methods in the original native code implementation. If your static library implements classes with non-static functions then in all three approaches above you would have to conceal a private member variable that pointed to an instance of your native class and would have to new up that instance at some suitable point (in the constructor of the wrapper for example) and would have to use that private member variable to actually invoke the actual implementation of the method you were trying to call.</p><p><br /></p><p>Q: Could you go into a little more detail regarding the last paragraph of your post. I'm unclear as to dealing with functions that are not declared static. <br /><br />Where are you creating the private member?<br /><br />How do you invoke that private member, PInvoke?<br /><br />Would it be possible to see another example?<br /><br />Thanks<br /><br />Blue</p><p><br /></p><p>A:</p><p>There's no need to use P/Invoke because the wrapper is written in Managed C++ so it can invoke the private member's functions directly.</p> <p>Let's change the example slightly and create a statistical functions library that can be used to calculate a number of statistical properties of a group of numbers. Since I'm lazy I'll just calculate average but you could imagine calculating standard deviation and median and all sorts of things. To keep the example simple, I'll not store the actual data items, I'll just incorporate them into a sum variable as I go. Again though you could imagine a much more elaborate data structure underneath this native class.</p> <p>The header file for the native code static library implementation of this statistical functions library might look something like this</p> <table border="0" cellspacing="0" width="100%"><tbody><tr><td width="15"><br /></td><td bgcolor="lightgrey" width="15"><br /></td><td bg style="color:lightgrey;"><br /><span style="font-family:Lucida Console;font-size:85%;"><span style="font-size:85%;color:#008000;">// StatFuncsLib.h</span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">namespace</span></span><span style="font-size:85%;"> StatFuncs<br />{<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">class</span></span><span style="font-size:85%;"> MyStatFuncs<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">private</span></span><span style="font-size:85%;">:<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">double</span></span><span style="font-size:85%;"> m_Count;<br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">double</span></span><span style="font-size:85%;"> m_Sum;</span><br /><span style="font-size:85%;"><br /></span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">public</span></span><span style="font-size:85%;">:<br /></span><span style="font-size:85%;color:#008000;"> // Constructs an instance and initialises private members</span><br /><span style="font-size:85%;"> MyStatFuncs ();</span><br /><span style="font-size:85%;"><br /></span><span style="font-size:85%;color:#008000;"> // Adds item and returns updated count</span><br /><span style="font-size:85%;color:#0000ff;"> double</span><span style="font-size:85%;"> AddItem(</span><span style="font-size:85%;color:#0000ff;">double</span><span style="font-size:85%;"> item);</span><br /><span style="font-size:85%;"><br /></span><span style="font-size:85%;color:#008000;"> // Returns average</span><br /><span style="font-size:85%;color:#008000;"> // Throws DivideByZeroException if count is 0</span><br /><span style="font-size:85%;color:#0000ff;"> double</span><span style="font-size:85%;"> Average ();</span><br /><span style="font-size:85%;"><br /></span><span style="font-size:85%;color:#008000;"> // Returns count of items</span><br /><span style="font-size:85%;color:#0000ff;"> double</span><span style="font-size:85%;"> Count ();<br /> };<br />}</span><br /> </span></td></tr></tbody></table> <p>The <span style="font-family:Courier New, Courier, Monospace;">AddItem</span> function will increment m_<span style="font-family:Courier New, Courier, Monospace;">Count</span> by 1 and will add <span style="font-family:Courier New, Courier, Monospace;">item</span> to m_<span style="font-family:Courier New, Courier, Monospace;">Sum</span> while the <span style="font-family:Courier New, Courier, Monospace;">Average</span> function will return <span style="font-family:Courier New, Courier, Monospace;">m_</span><span style="font-family:Courier New, Courier, Monospace;">Sum</span> divided by <span style="font-family:Courier New, Courier, Monospace;">m_Count</span>.</p> <p>Because data is accumulated in the private member variables <span style="font-family:Courier New, Courier, Monospace;">m_Count</span> and <span style="font-family:Courier New, Courier, Monospace;">m_Sum</span> we can't just use static functions, we have to use individual instances of the <span style="font-family:Courier New, Courier, Monospace;">MyStatFuncs</span> class. That means when we create our managed C++ wrapper class it will have to create and use an instance of the <span style="font-family:Courier New;">MyStatFuncs</span> class. The wrapper class might look something like this</p> <table border="0" cellspacing="0" width="100%"><tbody><tr><td width="15"><br /></td><td bgcolor="lightgrey" width="15"><br /></td><td bg style="color:lightgrey;"><br /><span style="font-family:Lucida Console;font-size:85%;"><span style="font-size:85%;color:#008000;">// ManagedStatFuncsLib.h</span><span style="font-size:85%;color:#0000ff;"> #pragma</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;">once<br />#include</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#800000;">"StatFuncsLib.h"</span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">using</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">namespace</span></span><span style="font-size:85%;"> System;</span><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">namespace</span></span><span style="font-size:85%;"> ManagedStatFuncs {<br /></span><span style="font-size:85%;color:#0000ff;"> </span><br /><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">public</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">ref</span></span><span style="font-size:85%;"> </span><span style="font-size:85%;color:#0000ff;"><span style="color:blue;">class</span></span><span style="font-size:85%;"> MyManagedStatFuncs<br /><span style="color:#0000ff;"> </span>{<br /></span><br /><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">private</span></span><span style="font-size:85%;">:<br /><span style="color:#0000ff;"> </span>StatFuncs::MyStatFuncs * m_NativeStatFuncs;<br /></span><br /><span style="font-size:85%;color:#0000ff;"> <span style="color:blue;">public</span></span><span style="font-size:85%;">:</span><br /><span style="font-size:85%;"><br /></span><span style="font-size:85%;color:#008000;"><span style="color:#0000ff;"> </span>// Constructs an instance of the class and an instance </span><br /><span style="font-size:85%;color:#008000;"> // of the underlying native class MyStatFuncs</span><br /><span style="font-size:85%;"> MyManagedStatFuncs ()<br /> {<br /> m_NativeStatFuncs = </span><span style="font-size:85%;color:#0000ff;">new</span><span style="font-size:85%;"> StatFuncs::MyStatFuncs ();<br /> };<br /></span><br /><span style="font-size:85%;color:#008000;"> // Adds item and returns updated count</span><br /><span style="font-size:85%;color:#0000ff;"> double</span><span style="font-size:85%;"> AddItem(</span><span style="font-size:85%;color:#0000ff;">double</span><span style="font-size:85%;"> item)<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> return</span><span style="font-size:85%;"> m_NativeStatFuncs->AddItem (item);<br /> };<br /></span><br /><span style="font-size:85%;color:#008000;"> // Returns average</span><br /><span style="font-size:85%;color:#008000;"> // Throws DivideByZeroException if b is 0</span><br /><span style="font-size:85%;color:#0000ff;"> double</span><span style="font-size:85%;"> Average ()<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> return</span><span style="font-size:85%;"> m_NativeStatFuncs->Average ();<br /> };<br /></span><br /><span style="font-size:85%;color:#008000;"> // Returns count of items</span><br /><span style="font-size:85%;color:#0000ff;"> double</span><span style="font-size:85%;"> Count ()<br /> {<br /></span><span style="font-size:85%;color:#0000ff;"> return</span><span style="font-size:85%;"> m_NativeStatFuncs->Count ();<br /> };<br /> };<br />}</span><br /> </span></td></tr></tbody></table> <p>The managed C++ wrapper will compile up into an assembly that can be referenced from a C# program (using Add Reference). Then the C# program just creates instances of the managed wrapper class and invokes the various functions as needed. For example</p> <table border="0" cellspacing="0" width="100%"><tbody><tr><td width="15"><br /></td><td bgcolor="lightgrey" width="15"><br /></td><td bg style="color:lightgrey;"><br /><span style="font-family:Lucida Console;font-size:85%;"><span style="font-size:85%;">ManagedStatFuncs.</span><span style="font-size:85%;color:#008080;">MyManagedStat<wbr>Funcs</span><span style="font-size:85%;"> myStatOne = </span><br /><span style="font-size:85%;"> <span style="color:#0000ff;"><span style="color:blue;">new</span></span> ManagedStatFuncs.<span style="color:#008080;">MyManagedStat<wbr>Funcs</span>();</span><br /><span style="font-size:85%;">ManagedStatFuncs.<span style="color:#008080;">MyManagedStat<wbr>Funcs</span> myStatTwo = </span><br /><span style="font-size:85%;"> <span style="color:#0000ff;"><span style="color:blue;">new</span></span> ManagedStatFuncs.<span style="color:#008080;">MyManagedStat<wbr>Funcs</span>();</span><br /><br /><span style="font-size:85%;">myStatOne.AddItem(1.0);</span><br /><span style="font-size:85%;">myStatOne.AddItem(3.0);</span><br /><span style="font-size:85%;">myStatOne.AddItem(5.0);</span><br /><br /><span style="font-size:85%;">myStatTwo.AddItem(2.0);</span><br /><span style="font-size:85%;">myStatTwo.AddItem(4.0);</span><br /><span style="font-size:85%;">myStatTwo.AddItem(6.0);</span><br /><span style="font-size:85%;">myStatTwo.AddItem(8.0);</span><br /><br /><span style="font-size:85%;"><span style="color:#008080;">Console</span>.WriteLine(</span><br /><span style="font-size:85%;"> <span style="color:#800000;">"First group consists of {0} items with an average value of {1}"</span>,</span><br /><span style="font-size:85%;"> myStatOne.Count(), myStatOne.Average());</span><br /><span style="font-size:85%;"><span style="color:#008080;">Console</span>.WriteLine(</span><br /><span style="font-size:85%;"> <span style="color:#800000;">"Second group consists of {0} items with an average value of {1}"</span>,</span><br /><span style="font-size:85%;"> myStatTwo.Count(), myStatTwo.Average());</span><br /> </span></td></tr></tbody></table>Q:<br /><p style="margin: 0in 0in 0pt;"><span style="font-size: 9.5pt; color: black; font-family: Verdana;">This is a good example! Thanks! </span> </p> <p style="margin: 0in 0in 0pt;"><span style="font-size: 9.5pt; color: black; font-family: Verdana;">I am trying to get this code to work on a Pocket PC device. Is it possible to build a managed C++ assembly for the Pocket PC. <span> </span>So far I have only been able to build the managed C++ assembly for Win32. Visual studio will not let me do Add Reference for a Win32 assembly in C#.<span> </span>When I try to add reference I get an error saying that </span><span style="font-size: 10pt; color: black; font-family: 'Lucida Console';">ManagedStatFuncs can not be added because it is not a device project. Maybe this is because Win32 managed code is not compatible with compact frameworks.</span><span style="font-size: 9.5pt; color: black; font-family: Verdana;"> Maybe I need a different project template. Does anyone have any thoughts on this?</span></p> <p style="margin: 0in 0in 0pt;"><br /><span style="font-size: 9.5pt; color: black; font-family: Verdana;"></span></p><p style="margin: 0in 0in 0pt;"><span style="font-size: 9.5pt; color: black; font-family: Verdana;">A:</span></p> <table width="85%"><tbody><tr><td> <strong>Brian Wall wrote:</strong></td></tr><tr><td><table width="100%"><tbody><tr><td valign="top" width="100%"><span style="font-size:85%;">Is it possible to build a managed C++ assembly for the Pocket PC?</span></td> </tr></tbody></table></td></tr></tbody></table> <p><span style="font-family:Verdana;">In a word, no. I can't find an authoritative reference to cite but if you search the web (or these forums) for "Managed C++" and "Smart Device" you'll find several posts that say it can't be done. For example this chat transcript</span></p> <blockquote dir="ltr" style="margin-right: 0px;"> <p><span style="font-family:Verdana;"><strong>Q:</strong> Will there be support for Managed C++ with .NET CF 2.0?<br /><b>A:</b> Sorry, no. Only VB and C#. </span></p> <p><a title="http://msdn.microsoft.com/chats/transcripts/mobileembedded/netcf_020805.aspx" href="http://msdn.microsoft.com/chats/transcripts/mobileembedded/netcf_020805.aspx" target="_blank">http://msdn.microsoft.com/<wbr>chats/transcripts/<wbr>mobileembedded/netcf_020805.<wbr>aspx</a></p> </blockquote>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-15278964351558131212009-06-24T06:45:00.000-07:002009-06-24T06:46:19.714-07:00C++ template and C# templateC++ template and C# template<br /><br />In standard C++, template classes are resolved at compile time, basically "class generators" for the compiler. The compiler will generate a copy of the class definition for each type that is used for the template parameter. So, for "vector<int>" and "vector<float>", you'll end up with two seperate classes, one each for the types int and float.<br /><br />In .NET 2.0+ (not just C#), generic classes are resolved at runtime. They are special constructs that maintain their type information. There is only ever one copy of the class definition, and that class definition keeps track of the type of objects being used with it. So, "List<int>" and "List<float>" use the same class definition.<br /><br />Because of this, you can created a templated class of managed types because the runtime type information is unimportant to the template class, but you cannot create a generic class of unmanaged types, as the type information for unmanaged types isn't availabe at runtime.Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-72896439168001541532009-06-24T06:43:00.000-07:002009-06-24T06:44:56.946-07:00C# for MFC programmers Quick Equivalents Map<h1><span style="font-size:-1;"><a href="http://www.flounder.com/csharpfactoids.htm" target="_blank"><b><b>C# for MFC programmers Quick Equivalents Map</b></b></a></span></h1><span style="font-size:-1;">
<br /></span><p><span style="font-size:-1;">This list is by no means intended to be comprehensive. I am learning C#, and as I've had to look something up, I record it here. I figure if I had to look it up, you will, too. If you have entries to contribute based on your own experience, or if you discover an error caused by my own naiveté in C#, feel free to send them. I won't attribute each individual contributions, but I will add you to a "contributions by..." section at the end. If you want your email or your Web site included in the attributions list, please say so explicitly; otherwise I will just put your name there. Or, if you want to remain anonymous, tell me and I will hog all the credit myself.</span></p> <h2><span style="font-size:-1;">Useful Web Sites</span></h2> <p><span style="font-size:-1;">I've discovered a number of useful Web sites for beginning C# programmers. Included in no particular order,</span></p> <ul><span style="font-size:-1;"><li><a href="http://www.syncfusion.com/FAQ/winforms/default.asp" target="_blank"><b>http://www.syncfusion.com/FAQ/<wbr>winforms/default.asp</b></a></li><li><b><a href="http://www.syncfusion.com/faq/winforms/627.asp" target="_blank">http://www.syncfusion.com/faq/<wbr>winforms/627.asp</a> (owner-drawn ListBox)</b></li><li><a href="http://www.wintoolzone.com/dotnetcom.aspx" target="_blank"><b>http://www.wintoolzone.com/<wbr>dotnetcom.aspx</b></a></li></span></ul> <h2><span style="font-size:-1;">My FAQ</span></h2> <table border="1" width="100%"> <tbody><tr> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#A" name="1221278f4d7e7cbf_Index" target="_blank">A</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#B" target="_blank">B</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#C" target="_blank">C</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#D" target="_blank">D</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#E" target="_blank">E</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#F" target="_blank">F</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#G" target="_blank">G</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#H" target="_blank">H</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#I" target="_blank">I</a></h2> </td> <td align="center" width="4%"> <h2> J</h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#K" target="_blank">K</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#L" target="_blank">L</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#M" target="_blank">M</a></h2> </td> </tr> <tr> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#N" target="_blank"> N</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#O" target="_blank"> O</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#P" target="_blank">P</a></h2> </td> <td align="center" width="4%"> <h2> Q</h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#R" target="_blank">R</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#S" target="_blank">S</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#T" target="_blank"> T</a></h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#T" target="_blank">U</a></h2> </td> <td align="center" width="4%"> <h2> V</h2> </td> <td align="center" bgcolor="#00ff00" width="4%"> <h2><a href="http://www.flounder.com/csharpfactoids.htm#W" target="_blank">W</a></h2> </td> <td align="center" width="4%"> <h2> X</h2> </td> <td align="center" width="4%"> <h2> Y</h2> </td> <td align="center" width="4%"> <h2> Z</h2> </td> </tr> </tbody></table> <p><span style="font-size:-1;"> </span></p> <table border="1" width="1113" height="1741"> <tbody><tr> <td colspan="4" bgcolor="#ffff00" width="687" height="19"><b>C/MFC concept</b></td> <td colspan="2" bgcolor="#ffff00" width="410" height="19"><b>C#</b></td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_A">A</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>abs</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Math.Abs</pre> </td> </tr> <tr> <td rowspan="2" width="83" height="64">
<br /></td> <td colspan="3" width="598" height="32"> <pre>int n = ...;
<br />int a = abs(n);</pre> </td> <td rowspan="2" width="1" height="64">
<br /></td> <td width="468" height="32"> <pre>int n = ...;
<br />int a = Math.Abs(n);</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>int n = -2147483648; // largest negative #
<br />UINT u = abs(n); // n = 2147483648 </pre> </td> <td width="468" height="32"> <pre style="margin-bottom: 0pt;">int n = -2147483648;
<br />uint u = Math.Abs(n); // exception!</pre> <p style="margin-top: 0pt; margin-bottom: 0pt;"><i><span style="font-size:85%;">but the following works!</span></i></p> <pre style="margin-top: 0pt;">uint u = unchecked(n <> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>AddString</b>(...) (CListBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>.Items.Add(...) (CListBox)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>AfxMessageBox</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>MessageBox.Show</pre> </td> </tr> <tr> <td rowspan="2" width="83" height="64">
<br /></td> <td rowspan="2" colspan="3" valign="top" width="598" height="64"> <pre>UINT n =
<br />AfxMessageBox(body, flags);</pre> </td> <td rowspan="2" width="1" height="64">
<br /></td> <td width="468" height="32"> <pre>DialogResult n =
<br />MessageBox.Show(body, caption,
<br />flags, icon);</pre> </td> </tr> <tr> <td width="468" height="32"><i>See <b>MessageBox</b></i></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>atoi</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Parse</pre> </td> </tr> <tr> <td width="83" height="32">
<br /></td> <td colspan="3" width="598" height="32"> <pre>CString s;
<br />int n = atoi(s);</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>String s
<br />int n = int.Parse(s)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>atol</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Parse</pre> </td> </tr> <tr> <td width="83" height="32">
<br /></td> <td colspan="3" width="598" height="32"> <pre>CString s;
<br />long n = atol(s);</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>String s
<br />long n = long.Parse(s)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_B">B</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="32"> <pre><b>BOOL</b></pre> </td> <td colspan="2" width="410" height="32"> <pre>Boolean
<br />bool</pre> </td> </tr> <tr> <td colspan="4" width="687" height="32"> <pre><b>bool</b></pre> </td> <td colspan="2" width="410" height="32"> <pre>Boolean
<br />bool</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>BS_PUSHLIKE</b></pre> </td> <td colspan="2" width="410" height="16"> <p><i><span style="font-size:85%;">Drag a check box onto the form. Select its <b>Appearance</b> property as <b>Button</b></span></i></p> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>BYTE</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>byte</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_C">C</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CBitmap</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Bitmap (actually, a GDI+ bitmap)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CBrush</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Brush</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CDC</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Graphics</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CClientDC</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Graphics</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&c_Ctl)</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Graphics g =
<br />c_Ctl.CreateGraphics();</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>ceil</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Math.Ceiling</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CenterWindow</b> (CWnd)</pre> </td> <td colspan="2" width="410" height="16"> <pre style="margin-bottom: 0pt;">.StartPosition = FormStartPosition.CenterParent </pre> <p style="margin-top: 0pt;"><span style="font-size:85%;"><i>(can be set at design time)</i></span></p></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CFileDialog</b></pre> </td> <td colspan="2" width="410" height="16">Create an object (usually in the forms design template) of type <b><span style="font-family:Courier New;font-size:85%;">SaveFileDialog</span> </b>or <b><span style="font-family:Courier New;font-size:85%;">OpenFileDialog</span></b>. Use the <b><span style="font-family:Courier New;font-size:85%;">ShowDialog</span></b> method to invoke it.</td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CFont</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Font</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>char</b> <i>(as a character type)</i></pre> </td> <td colspan="2" width="410" height="16"> <pre>char</pre> </td> </tr> <tr> <td width="83" height="45">
<br /></td> <td colspan="3" width="598" height="45">
<br /></td> <td width="1" height="45">
<br /></td> <td width="468" height="45"><span style="font-size:85%;">Note however that <b>char</b> in C# means <i>Unicode character</i> and is not the same as <b>byte</b> or the concept in C/C++ known as <b>char</b>. Signedness is not a characteristic of the C# <b>char</b> type. It is conceptually closer to the C/C++ <b>WCHAR</b> type.</span></td> </tr> <tr> <td colspan="4" width="687" height="17"> <pre><b>char</b> <i>(as a signed 8-bit integer)</i></pre> </td> <td colspan="2" width="410" height="17"> <pre>sbyte</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CListBox::AddString</b>(...) (CListBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>CListBox.Items.Add(...) (CListBox)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CListBox.GetLBText</b>(n) (CListBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>CListBox.GetItemText(n)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>COLOR_ </b>constants</pre> </td> <td colspan="2" width="410" height="16"> <pre><i>See</i> GetSysColor</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>COLORREF</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Color</pre> </td> </tr> <tr> <td rowspan="3" width="83" height="48"> </td> <td colspan="3" width="598" height="16"> <pre>COLORREF r =
<br />RGB(255,128,0);</pre> </td> <td rowspan="3" width="1" height="48">
<br /></td> <td width="468" height="16"> <pre>Color c =
<br />Color.FromArgb(255,128,0);</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"><span style="font-size:85%;">This actually oversimplifies, or over complicates, the problem. C# contains a number of "predefined color names", many with really obscure names and no good graphical representation in the Help system of what they look like. However, RGB(255,0,0) is the name .Red. The names appear to conform to the HTML naming conventions. You can also name system colors. See <b>GetSysColor</b>.</span></td> <td width="468" height="16"><span style="font-size:85%;"><b>Argb</b> stands for the 4-tuple, Alpha, Red, Green, Blue, and the overload with three arguments assumes Alpha (transparency) is 255 (completely opaque).</span></td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLORREF r = RGB(255,0,0)</pre> </td> <td width="468" height="16"> <pre>Color c = Color.Red;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CPaintDC</b></pre> </td> <td colspan="2" width="410" height="16"> The <span style="font-family:Courier New;font-size:85%;">.Graphics</span> member of the <span style="font-family:Courier New;font-size:85%;">System.Windows.Forms.<wbr>PaintEventArgs</span> argument to the <span style="font-family:Courier New;font-size:85%;">OnPaint</span> event </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CPen</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Pen</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CSize</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Size (integer values)
<br />SizeF (floating point values)</pre> </td> </tr> <tr> <td rowspan="2" width="83" height="64">
<br /></td> <td rowspan="2" colspan="3" width="598" height="64"> <pre>CSize sz = ...;
<br />int w = <a href="http://sz.cx/" target="_blank">sz.cx</a>;
<br />int h = <a href="http://sz.cy/" target="_blank">sz.cy</a>;</pre> </td> <td rowspan="2" width="1" height="64">
<br /></td> <td width="468" height="32"> <pre>SizeF sz = ...;
<br />int w = sz.Width;
<br />int h = sz.Height;</pre> </td> </tr> <tr> <td width="468" height="32"><span style="font-size:85%;">This is an oversimplification because the fields of a <b>SizeF</b> are floats and not integers!</span></td> </tr> <tr> <td colspan="4" width="687" height="16"> <span style="font-family:Courier New;font-size:85%;"><b>CSpinCtrl</b></span> (with <span style="font-family:Courier New;font-size:85%;">CEdit</span> buddy control) </td> <td colspan="2" width="410" height="16"> <pre>NumericUpDown</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CString</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>String</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CString::Find</b>(CString s)</pre> </td> <td colspan="2" width="410" height="16"> <pre>String.IndexOf(String s)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b><a name="1221278f4d7e7cbf_CString::Format">CString::Format</a></b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Format</pre> </td> </tr> <tr> <td width="83" height="32">
<br /></td> <td colspan="3" width="598" height="32"> <pre>CString s;
<br />s.Format(fmt, val...)</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>String s;
<br />s = Format(fmt, val...)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="123">
<br /></td> <td colspan="2" valign="top" width="410" height="123"><span style="font-size:85%;">Formatting specifications in C# are much more flexible than in traditional C. For example, you can associate several format requests with the same argument, and the formatting options are richer, including localized date, time, and currency representations.</span> <p><span style="font-size:85%;">Instead of %, the format specifiers in C# are enclosed in {}, and are of the form {n:Fp} where n specifies the argument in the formatting string (the n: can be omitted in the <b>ToString</b> method call), F is a format specifier, and p is the precision.</span></p></td> </tr> <tr> <td rowspan="7" width="83" height="161"> </td> <td colspan="3" width="598" height="17"> <pre><b>%d</b></pre> </td> <td colspan="2" width="410" height="17"> <pre>{n:d}<i> or </i>{n:D}</pre> </td> </tr> <tr> <td colspan="3" width="598" height="17"> <pre><b>%02d</b></pre> </td> <td colspan="2" width="410" height="17"> <pre>{n:d2} <i>or</i> {n:D2}</pre> </td> </tr> <tr> <td colspan="3" width="598" height="19"> <pre><b>%o</b></pre> </td> <td colspan="2" width="410" height="19"><i>octal is not supported</i></td> </tr> <tr> <td colspan="3" width="598" height="38"> <pre><b>%ld</b></pre> </td> <td colspan="2" width="410" height="38"><span style="font-family:Courier New;font-size:85%;">{n:d}</span> <i>No special handling is required for int values</i></td> </tr> <tr> <td colspan="3" width="598" height="38"> <pre><b>%I64d</b></pre> </td> <td colspan="2" width="410" height="38"><span style="font-family:Courier New;font-size:85%;">{n:d}</span> <i>No special handling is required for 64-bit int values</i></td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre><b>%x</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>{n:x}</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre><b>%X</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>{n:X}</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CWnd::GetClientRect()</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>ClientRectangle <i>(property)</i></pre> </td> </tr> <tr> <td colspan="4" width="687" height="19"> <pre><b>CWnd::Invalidate</b>()</pre> </td> <td colspan="2" width="410" height="19"> <pre><span style="font-family:Courier New;">.Invalidate()</span></pre> </td> </tr> <tr> <td colspan="4" width="687" height="19"> <pre><b>CWnd::InvalidateRect</b>(&r)</pre> </td> <td colspan="2" width="410" height="19"> <pre><span style="font-family:Courier New;">.Invalidate(...);</span></pre> </td> </tr> <tr> <td colspan="4" width="687" height="19"> <pre><b>CWnd::ShowWindow</b>(SW_SHOW)</pre> </td> <td colspan="2" width="410" height="19"> <pre>.Visible = true;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="17"> <pre><b>CWnd::ShowWindow</b>(SW_HIDE);</pre> </td> <td colspan="2" width="410" height="17"> <pre>.Visible = false;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>CString.GetLength</b>();</pre> </td> <td colspan="2" width="410" height="16"> <pre>String.Length;</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_D">D</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>DeleteDC</b></pre> </td> <td colspan="2" valign="top" width="410" height="16"><span style="font-size:85%;">No need to; implicitly handled by the <b>Graphics</b> destructor during garbage collection.</span></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>DestroyWindow</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Close</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>DoModal</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.ShowDialog</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>double</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>double</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>DrawItem</b> (CListBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>DrawItem event</pre> <p>See <b><a href="http://www.syncfusion.com/faq/winforms/627.asp" target="_blank">http://www.syncfusion.com/faq/<wbr>winforms/627.asp</a></b> </p></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>DWORD</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>uint</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_E">E</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.Ellipse</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.DrawEllipse</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />CRect r;
<br />CPen pen(PS_SOLID, n, RGB(0,0,0));
<br />dc.SelectObject(&pen);
<br />dc.Ellipse(&r);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />Rectangle r;
<br />Pen pen = new Pen(Color.Black, n);
<br />g.DrawEllipse(pen, r);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>EndDialog(IDCancel)</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Close</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>EndDialog(IDOK)</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Close</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>exp</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Math.Exp</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_F">F</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>Find</b> (CString)</pre> </td> <td colspan="2" width="410" height="16"> <pre>.IndexOf (String)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>float</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>float</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.Format</b></pre> </td> <td colspan="2" width="410" height="16"> see <b><span style="font-family:Courier New;font-size:85%;"><a href="http://www.flounder.com/csharpfactoids.htm#CString::Format" target="_blank">CString::Format</a> </span></b> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_G">G</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetBValue</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.B</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>COLORREF c = ...;
<br />int b = GetBValue(c);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Color c = ...;
<br />int b = c.B;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.GetClientRect()</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.ClientRectangle <i>(property)</i></pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CRect r;
<br />wnd.<b>GetClientRect</b>(&r);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Rectangle r =
<br />wnd.ClientRectangle;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetCurSel</b> (CComboBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>... = ComboBox.SelectedIndex;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetDC</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Graphics</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>CDC * dc = wnd.GetDC();</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Graphics g =
<br />wnd.CreateGraphics();</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetFont</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.Font</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CFont * f = wnd.<b>GetFont</b>();</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Font f = wnd.Font;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetGValue</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.G</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>COLORREF c = ...;
<br />int g = GetGValue(c);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Color c = ...;
<br />int g = c.G;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>GetLBText</b>(n) (CListBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>.GetItemText(n)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.</b><b>GetLBText</b>(n) (CComboBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>.GetSelectedItem.ToString();</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>GetLength</b>() (CString)</pre> </td> <td colspan="2" width="410" height="16"> <pre>s.Length</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>GetMiterLimit</b> (CDC)</pre> </td> <td colspan="2" width="410" height="16"> <pre><span style="font-size:85%;">... = Pen.MiterLimit;</span></pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetModuleFileName</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>System.Windows.Forms.<wbr>Application.ExecutablePath</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>TCHAR name[MAX_PATH];
<br />GetModuleFileName(NULL, name, MAX_PATH);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>String name = System.Windows.Forms.
<br />Application.ExecutablePath;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetPos</b> (CSpinCtrl)</pre> </td> <td colspan="2" width="410" height="16"> <pre>NumericUpDown.Value</pre> <p><span style="font-size:85%;"><i>Note that the values of <b>.Minimum</b>, <b>.Maximum</b>, and <b>.Value</b></i> <i>are of type <b>decimal</b>. This means that to assign a value which is a fractional value, you have to use a decimal constant. To use the values, you may have to cast them from <b>decimal</b> to <b>int</b> or <b>float</b>.</i></span> </p></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetRange</b> (CSpinCtrl)</pre> </td> <td colspan="2" width="410" height="16"> <pre>NumericUpDown.Maximum and
<br />NumericUpDown.Minimum</pre> <p><span style="font-size:85%;"><i>Note that the values of <b>.Minimum</b>, <b>.Maximum</b>, and <b>.Value</b></i> <i>are of type <b>decimal</b>. This means that to assign a value which is a fractional value, you have to use a decimal constant. To use the values, you may have to cast them from <b>decimal</b> to <b>int</b> or <b>float</b>.</i></span> </p></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetRValue</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.R</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>COLORREF c = ...;
<br />int r = GetRValue(c);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Color c = ...;
<br />int r = c.R;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>GetSize</b>() (CArray)</pre> </td> <td colspan="2" width="410" height="16"> <pre>s.Length</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetSysColor</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Color.FromKnownColor(<wbr>KnownColor.<i>colorname</i>)</pre> </td> </tr> <tr> <td rowspan="34" width="83" height="544"> </td> <td colspan="3" width="598" height="16"> <pre>COLORREF c = ::GetSysColor(COLOR_WINDOW)</pre> </td> <td rowspan="34" width="1" height="544">
<br /></td> <td width="468" height="16"> <pre>Color.KnownColor.Window</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_3DDKSHADOW</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.<wbr>ControlDarkDark (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_3DFACE</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.Control (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_3DHIGHLIGHT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ControlLight (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_3DHILIGHT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ControlLight (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_3DLIGHT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.?</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_ACTIVEBORDER</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ActiveBorder</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_ACTIVECAPTION</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ActiveCaption</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_APPWORKSPACE</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.AppWorkspace</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_BACKGROUND</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.Desktop</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_BTNFACE</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.Control (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_BTNHIGHLIGHT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ControlLight (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_BTNHILIGHT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ControlLight (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_BTNSHADOW</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ControlDark (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_BTNTEXT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ControlText</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_CAPTIONTEXT</pre> </td> <td width="468" height="16">
<br /></td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_DESKTOP</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.Desktop</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_GRADIENTACTIVECAPTION</pre> </td> <td width="468" height="16">
<br /></td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_GRADIENTINACTIVECAPTION</pre> </td> <td width="468" height="16">
<br /></td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_GRAYTEXT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.GrayText</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_HIGHLIGHT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.Highlight</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_HIGHLIGHTTEXT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.HighlightText</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_HOTLIGHT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.HotTrack (?)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_INACTIVEBORDER</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.<wbr>InactiveBorder</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_INACTIVECAPTION</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.<wbr>InactiveCaption</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_INACTIVECAPTIONTEXT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.<wbr>InactiveCaptionText</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_INFOBK</pre> </td> <td width="468" height="16">
<br /></td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_INFOTEXT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.InfoText</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_MENU</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.Menu</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_MENUTEXT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.MenuText</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_SCROLLBAR</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.ScrollBar</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_WINDOW</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.Window</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_WINDOWFRAME</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.WindowFrame</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLOR_WINDOWTEXT</pre> </td> <td width="468" height="16"> <pre>Color.KnownColor.WindowText</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetSystemMetrics</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>System.Windows.Forms.<wbr>SystemInformation</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetTextExtent</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>MeasureString</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />CSize sz;
<br />CString s = ...;
<br />sz = dc.<b>GetTextExtent</b>(s);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />SizeF sz;
<br />String s = ...;
<br />sz = g.MeasureString(wnd.Font, s);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <span style="font-family:Courier New;font-size:85%;"><b>GetTickCount</b></span></td> <td colspan="2" width="410" height="16"> <b><span style="font-family:Courier New;font-size:85%;">DateTime.Now.Ticks</span></b></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GetUserName</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>System.Environment.UserName</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>GWL_DLGRESULT</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Closing event, DialogResult property</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>void CMyDialog::OK()
<br />{
<br />DWORD result = ...;
<br />SetWindowLong((HWND)this,
<br />GWL_DLGRESULT,
<br />result);
<br />
<br />CDialog::OnOK();
<br />}</pre> </td> <td valign="top" width="1" height="16">
<br /></td> <td valign="top" width="468" height="16"> <p><i><span style="font-size:85%;">select the Closing event for the form and type a name of the function you want, such as <b>OnClosing</b></span></i></p> <pre>private void OnClosing(
<br />Object sender,
<br />System.ComponentModel.<wbr>CancelEventArgs e)
<br />{
<br />Object result = ...;
<br />e.DialogResult = result;
<br />}</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_H">H</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>HBITMAP</b></pre> </td> <td colspan="2" valign="top" width="410" height="16"> <pre>Bitmap (actually, a GDI+ bitmap)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>HBRUSH</b></pre> </td> <td colspan="2" valign="top" width="410" height="16"> <pre>Brush</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>HDC</b></pre> </td> <td colspan="2" valign="top" width="410" height="16"><span style="font-family:Courier New;font-size:85%;">Graphics</span> <i>(see CDC</i>)</td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>HPEN</b></pre> </td> <td colspan="2" valign="top" width="410" height="16"> <pre>Pen</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_I">I</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <b><span style="font-family:Courier New;font-size:85%;">_I64_MAX</span></b></td> <td colspan="2" width="410" height="16"> <b><span style="font-family:Courier New;font-size:85%;">Int64.MaxValue</span></b></td> </tr> <tr> <td colspan="4" width="687" height="16"> <b><span style="font-family:Courier New;font-size:85%;">_I64_MIN</span></b></td> <td colspan="2" width="410" height="16"> <b><span style="font-family:Courier New;font-size:85%;">Int64.MinValue</span></b></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>int</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>int</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>__int64</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>long</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <b><span style="font-family:Courier New;font-size:85%;">INT_MAX</span></b></td> <td colspan="2" width="410" height="16"> <b><span style="font-family:Courier New;font-size:85%;">Int32.MaxValue</span></b></td> </tr> <tr> <td colspan="4" width="687" height="16"> <b><span style="font-family:Courier New;font-size:85%;">INT_MIN</span></b></td> <td colspan="2" width="410" height="16"> <b><span style="font-family:Courier New;font-size:85%;">Int32.MinValue</span></b></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>Invalidate</b>()</pre> </td> <td colspan="2" width="410" height="16"> <pre>.Invalidate();</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>InvalidateRect</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.Invalidate();</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CRect r;
<br />wnd.<b>InvalidateRect</b>(&r)</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Rectangle r;
<br />wnd.Invalidate(r);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>itoa</b></pre> </td> <td colspan="2" width="410" height="16"> <pre><b>ToString</b></pre> </td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <pre>3</pre> </td> <td rowspan="4" width="1" height="64">
<br /></td> <td valign="top" width="468" height="16"> <pre>int v;
<br />String s;
<br />s = i.ToString();</pre> </td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%3d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <span style="font-family:Courier New;font-size:85%;">··3 </span>(leading spaces) </td> <td valign="top" width="468" height="16"> <span style="font-family:Courier New;font-size:85%;">int v;
<br />String s;
<br />s = String.Format("{0,3:d}", v);</span></td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%03d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <pre>003</pre> </td> <td valign="top" width="468" height="16"> <pre>int v = 3;
<br />String s;
<br />s = i.ToString("D3");</pre> </td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%03d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <pre>003</pre> </td> <td valign="top" width="468" height="16"> <pre>int v = 3;
<br />String s;
<br />s = i.ToString("000");</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_K">K</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>KillTimer</b></pre> </td> <td colspan="2" width="410" height="16"><i>place a timer object on the form and give it a name</i>
<br /><span style="font-family:Courier New;font-size:85%;"><i>timer</i>.Stop();</span></td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_L">L</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>LineTo</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>DrawLine</pre> </td> </tr> <tr> <td rowspan="2" width="83" height="32"> </td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />dc.SelectObject(&pen);
<br />dc.MoveTo( x0, y0);
<br />dc.LineTo( x1, y1);</pre> </td> <td rowspan="2" width="1" height="32">
<br /></td> <td valign="top" width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />g.DrawLine(pen, x0, y0, x1, y1);</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />dc.SelectObject(&pen);
<br />CPoint p0(x0, y0);
<br />CPoint p1(x1, y1);
<br />dc.MoveTo( p0 );
<br />dc.LineTo( p1 );</pre> </td> <td valign="top" width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />Point p0 = new Point(x0, y0);
<br />Point p1 = new Point(x1, y1);
<br />g.DrawLine(pen, p0, p1);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>::<b>LoadCursor</b>(NULL, cursorid)
<br /><b>LoadStandardCursor</b>(cursorid) (CWinApp)</pre> </td> <td colspan="2" valign="top" width="410" height="16"> <i><span style="font-size:85%;">No equivalent. See <b>OnSetCursor</b></span></i> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>long</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>int</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>LONG</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>int</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>LONGLONG</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>long</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_M">M</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>MessageBox</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>MessageBox.Show</pre> </td> </tr> <tr> <td width="83" height="32">
<br /></td> <td colspan="3" valign="top" width="598" height="32"> <pre>UINT n =
<br />MessageBox(body, caption, flags);</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>DialogResult n =
<br />MessageBox.Show(body);
<br />DialogResult n =
<br />MessageBox.Show(body, caption);
<br />DialogResult n =
<br />MessageBox.Show(body, caption,
<br />buttons);
<br />DialogResult n =
<br />
<br />MessageBox.Show(body, caption,
<br />buttons, icon);
<br />DialogResult n =
<br />MessageBox.Show(body, caption,
<br />buttons, icon,
<br />defaultbutton);</pre> </td> </tr> <tr> <td rowspan="8" width="83" height="256">
<br /></td> <td colspan="5" width="1014" height="32"> <i>buttons</i> can be any of the following:</td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_ABORTRETRYIGNORE</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>MessageBoxButtons.<wbr>AbortRetryIgnore</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_HELP</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <p><i>no equivalent</i></p> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_OK</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>MessageBoxButtons.OK</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_OKCANCEL</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>MessageBoxButtons.OKCancel</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_OKRETRY</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>MessageBoxButtons.OKRetry</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_YESNO</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>MessageBoxButtons.YesNo</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_YESNOCANCEL</pre> </td> <td width="1" height="32">
<br /></td> <td width="468" height="32"> <pre>MessageBoxButtons.YesNoCancel</pre> </td> </tr> <tr> <td rowspan="11" width="83" height="352">
<br /></td> <td colspan="5" width="1014" height="32"> <i>icon</i> is optional and can be any of</td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_ASTERISK</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre style="margin-bottom: 0pt;">MessageBoxIcon.Asterisk</pre> <p style="margin-top: 0pt;"><i><span style="font-size:85%;">Note: this code should be considered obsolete; <b>.Information </b>should be used instead</span></i></p> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_ERROR</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre>MessageBoxIcon.Error</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_EXCLAMATION</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre style="margin-top: 0pt; margin-bottom: 0pt;">MessageBoxIcon.Exclamation</pre> <p style="margin-top: 0pt; margin-bottom: 0pt;"><i><span style="font-size:85%;">Note: this code should be considered obsolete; <b>.Warning </b>should be used instead</span></i></p> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_HAND</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre style="margin-bottom: 0pt;">MessageBoxIcon.Hand</pre> <p style="margin-top: 0pt;"><i><span style="font-size:85%;">Note: this code should be considered obsolete; <b>.Error </b>should be used instead</span></i></p> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_INFORMATION</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre>MessageBoxIcon.Information</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32">
<br /></td> <td align="center" width="1" height="32">
<br /></td> <td valign="top" width="468" height="32"> <pre>MessageBoxIcon.None</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_ICONQUESTION</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre>MessageBoxIcon.Question</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_ICONSTOP</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre style="margin-bottom: 0pt;">MessageBoxIcon.Stop</pre> <p style="margin-top: 0pt;"><i><span style="font-size:85%;">Note: this code should be considered obsolete; <b>.Error </b>should be used instead</span></i></p> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="32"> <pre>MB_ICONWARNING</pre> </td> <td align="center" width="1" height="32"> <pre><img border="0" width="32" height="32" /></pre> </td> <td valign="top" width="468" height="32"> <pre>MessageBoxIcon.Warning</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_USERICON</pre> </td> <td align="center" width="1" height="32">
<br /></td> <td width="468" height="32"> <p><i>no equivalent</i></p> </td> </tr> <tr> <td colspan="3" width="598" height="32">
<br /></td> <td colspan="3" width="1448" height="32"> The default button can be one of the following</td> </tr> <tr> <td rowspan="4" width="83" height="128">
<br /></td> <td colspan="3" width="598" height="32"> <pre>MB_DEFBUTTON1</pre> </td> <td rowspan="4" width="1" height="128">
<br /></td> <td width="468" height="32"> <pre>MessageBoxDefaultButton.<wbr>Button1</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_DEFBUTTON2</pre> </td> <td width="468" height="32"> <pre>MessageBoxDefaultButton.<wbr>Button2</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_DEFBUTTON3</pre> </td> <td width="468" height="32"> <pre>MessageBoxDefaultButton.<wbr>Button3</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>MB_DEFBUTTON4</pre> </td> <td width="468" height="32"> <p><i>no equivalent</i></p> </td> </tr> <tr> <td colspan="2" width="90" height="32"> </td> <td colspan="4" width="1007" height="32"> The return value can be one of the following</td> </tr> <tr> <td rowspan="8" width="83" height="256">
<br /></td> <td colspan="3" width="598" height="32"> <pre>IDABORT</pre> </td> <td rowspan="8" width="1" height="256">
<br /></td> <td width="468" height="32"> <pre>DialogResult.Abort</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>IDCANCEL</pre> </td> <td width="468" height="32"> <pre>DialogResult.Cancel</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>IDIGNORE</pre> </td> <td width="468" height="32"> <pre>DialogResult.Ignore</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>IDNO</pre> </td> <td width="468" height="32"> <pre>DialogResult.No</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"><i>There is no equivalent to this value in the standard API</i></td> <td width="468" height="32"> <pre>DialogResult.None</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>IDOK</pre> </td> <td width="468" height="32"> <pre>DialogResult.OK</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>IDRETRY</pre> </td> <td width="468" height="32"> <pre>DialogResult.Retry</pre> </td> </tr> <tr> <td colspan="3" width="598" height="32"> <pre>IDYES</pre> </td> <td width="468" height="32"> <pre>DialogResult.Yes</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>MoveTo</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>DrawLine</pre> </td> </tr> <tr> <td rowspan="2" width="83" height="32"> </td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />dc.SelectObject(&pen);
<br />dc.MoveTo( x0, y0);
<br />dc.LineTo( x1, y1);</pre> </td> <td rowspan="2" width="1" height="32">
<br /></td> <td valign="top" width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />g.DrawLine(pen, x0, y0, x1, y1);</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />CPoint p0(x0, y0);
<br />CPoint p1(x1, y1);
<br />dc.SelectObject(&pen);
<br />dc.MoveTo( p0 );
<br />dc.LineTo( p1 );</pre> </td> <td valign="top" width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />Point p0 = new Point(x0, y0);
<br />Point p1 = new Point(x1, y1);
<br />g.DrawLine(pen, p0, p1);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>MoveWindow</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.Location (changes only the top-left origin)</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>// Move window to X, Y retaining size
<br />CRect r;
<br />ctl.GetWindowRect(&r);
<br />CSize sz(r.Width(), r.Height());
<br />ctl.MoveWindow(X, Y, <a href="http://sz.cx/" target="_blank">sz.cx</a>, <a href="http://sz.cy/" target="_blank">sz.cy</a>);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>ctl.Location = new Point(X, Y);</pre> <p><i><span style="font-size:85%;">Note that accessing the <b>.Location </b>member returns a <u>copy</u> of the <b>Point</b> value, so changing the values in this will not change the size in the control itself, e.g., </span></i></p> <pre>ctl.Location.x = X; // does not work</pre> <p><i><span style="font-size:85%;">changes only the value in the copy. You must assign a complete <b>Point</b> object to the <b>.Location</b> member.</span></i></p> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>MoveWindow</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.Size (changes only the size)
<br />.Width (changes only the width)
<br />.Height (changes only the height)</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>// Change window to size W,H in same place
<br />CRect r;
<br />ctl.GetWindowRect(&r);
<br />ScreenToClient(&r);
<br />ctl.MoveWindow(r.left, r.top, W, H);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>ctl.Size = new Size(X, Y);</pre> <p><i><span style="font-size:85%;">or you can change each dimension independently</span></i></p> <pre>ctl.Width = W;
<br />ctl.Height = H;</pre> <p><i><span style="font-size:85%;">Note that accessing the <b>.Size</b> member returns a <u>copy</u> of the <b>Size</b> value, so changing the values in this will not change the size in the control itself, e.g., </span></i></p> <pre>ctl.Size.Width = W; // does not work</pre> <p><i><span style="font-size:85%;">changes only the value in the copy. You must assign a complete <b>Size</b> object to the <b>.Size</b> member, or assign independently to the <b>.Width</b> or <b>.Height</b> members</span></i></p> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_N">N</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>NULL</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>null</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_O">O</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>OnClose</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Closing event</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>void CMyWnd::OnClose()
<br />{
<br />if(MyQueryClose())
<br />return;
<br />CWnd::OnClose();
<br />}</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <p><i><span style="font-size:85%;">select the Closing event for the form and type a name of the function you want, such as <b>OnClosing</b></span></i></p> <pre>private void OnClosing(
<br />Object sender,
<br />System.ComponentModel.<wbr>CancelEventArgs e)
<br />{
<br />e.Cancel = MyQueryClose();
<br />}</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>OnDestroy</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Closed event</pre> </td> </tr> <tr> <td width="83" height="1">
<br /></td> <td colspan="3" valign="top" width="598" height="1"> <pre>void CMyWnd::OnDestroy() { ... }</pre> </td> <td width="1" height="1">
<br /></td> <td width="468" height="1"> <p><i><span style="font-size:85%;">select the Closing event for the form and type a name of the function you want, such as <b>OnClosed</b></span></i></p> <pre>private void OnClosing(Object sender,
<br />System.ComponentModel.<wbr>EventArgs e)
<br />{
<br />...
<br />}</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>OnVScroll(...)</pre> </td> <td colspan="2" width="410" height="16"> <pre>Create a <b>ScrollEvent</b> handler</pre> </td> </tr> <tr> <td rowspan="10" width="83" height="10">
<br /></td> <td colspan="3" width="598" height="1"> <pre>switch(nSBCode)</pre> </td> <td rowspan="10" width="1" height="10">
<br /></td> <td width="468" height="1"> <pre>switch(e.Type)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_PAGEUP</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.LargeDecrement</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_PAGEDOWN</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.LargeIncrement</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_LINEUP</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.SmallDecrement</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_LINEDOWN</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.SmallIncrement</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_TOP</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.First</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_BOTTOM</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.Last</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_THUMBPOSITION</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.ThumbPosition</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_THUMBTRACK</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.ThumbTrack</pre> </td> </tr> <tr> <td colspan="3" width="598" height="1"> <pre>SB_ENDSCROLL</pre> </td> <td width="468" height="1"> <pre>ScrollEventType.EndPos</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>OnInitDialog</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Load event</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><span style="font-size:85%;"><b>OnLButtonDown</b></span></pre> </td> <td colspan="2" width="410" height="16"> <pre><span style="font-size:85%;">MouseDown event</span></pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>OnLButtonUp</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>MouseUp event</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>OnMouseMove</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>MouseMove event</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b><span style="font-size:85%;">OnMove</span></b></pre> </td> <td colspan="2" width="410" height="16"> <pre><span style="font-size:85%;">LocationChanged event</span></pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><span style="font-size:85%;"><b>OnPaint</b></span></pre> </td> <td colspan="2" width="410" height="16"> <pre><span style="font-size:85%;">OnPaint event</span></pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>OnSetCursor</b></pre> </td> <td colspan="2" width="410" height="16"> <i><span style="font-size:85%;">No equivalent; cursor is set using the <b>Cursor</b> property of the window whose cursor is to be set. See <b>SetCursor</b></span></i> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b><span style="font-size:85%;">OnSize</span></b></pre> </td> <td colspan="2" width="410" height="16"> <pre><span style="font-size:85%;">SizeChanged event</span></pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_P">P</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>PostMessage</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>BeginInvoke</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>ON_MESSAGE(UWM_MYMESSAGE, OnMyMessage)</pre> <pre>LRESULT CMyClass::OnMyMessage(
<br />WPARAM, LPARAM)
<br />{
<br />... do something
<br />return 0;
<br />}</pre> <pre>void CMyClass::DoSomething()
<br />{
<br />CString * s =
<br />new CString(_T("Message"));
<br />PostMessage(UWM_MYMESSAGE,
<br />(WPARAM)s);</pre> </td> <td width="1" height="16">
<br /></td> <td valign="top" width="468" height="16"> <pre>public delegate
<br />void MessageHandler(String s);</pre> <pre>class CMyClass {
<br />public void MyHandler(String s) { ... }
<br />}</pre> <pre> public void DoSomething()
<br />{
<br />String s = "Message";
<br />MessageHandler handler =
<br />new MessageHandler(MyHandler);
<br />handler.BeginInvoke(handler);</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16">
<br /></td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <span style="font-size:85%;">As with many C# equivalences, this is an oversimplification of a far more sophisticated concept. For example, in C# you can actually receive a callback when the message is handled, or wait for the receiving thread to process it.</span> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>PostQuitMessage</b>(0)</pre> </td> <td colspan="2" width="410" height="16"> <pre>Close()</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>pow</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Math.Pow</pre> </td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <pre><b>printf</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>System.Console.Write
<br />System.Console.WriteLine</pre> </td> </tr> <tr> <td valign="top" width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>printf("%s", string);</pre> </td> <td valign="top" width="1" height="16">
<br /></td> <td valign="top" width="468" height="16"> <pre>CString string;
<br />System.Console.Write(string);</pre> </td> </tr> <tr> <td rowspan="2" valign="top" width="83" height="32"> </td> <td rowspan="2" colspan="3" valign="top" width="598" height="32"> <pre>printf("%s\n", string);</pre> </td> <td rowspan="2" valign="top" width="1" height="32">
<br /></td> <td valign="top" width="468" height="16"> <pre>CString string;
<br />System.Console.Write(string +"\n");</pre> </td> </tr> <tr> <td valign="top" width="468" height="16"> <pre>CString string;
<br />System.Console.WriteLine(<wbr>string);</pre> </td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <pre><b>puts</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>System.Console.Write
<br />System.Console.WriteLine</pre> </td> </tr> <tr> <td valign="top" width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>CString string;
<br />puts(string);</pre> </td> <td valign="top" width="1" height="16">
<br /></td> <td valign="top" width="468" height="16"> <pre>CString string;
<br />System.Console.Write(string);</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_R">R</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.Rectangle</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.DrawRectangle</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />CRect r;
<br />...assign to r
<br />dc.SelectObject(&pen);
<br />dc.SelectStockObject(HOLLOW_<wbr>BRUSH);
<br />dc.Rectangle(&r);</pre> </td> <td width="1" height="16">
<br /></td> <td valign="top" width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />Rectangle r;
<br />...assign to r
<br />g.DrawRectangle(pen, r);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>ReleaseDC</b></pre> </td> <td colspan="2" width="410" height="16"><i>No need to; implicitly handled by the <b>Graphics</b> destructor during garbage collection.</i></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.ResetContent</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>listbox.Items.Clear()</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.RestoreDC</b> (CDC)</pre> </td> <td colspan="2" width="410" height="16"> <span style="font-family:Courier New;font-size:85%;">.Restore (graphics)</span> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />int n = dc.SaveDC();
<br />...
<br />dc.RestoreDC(n);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />GraphicsState gs = g.Save();
<br />...
<br />g.Restore(gs);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.ReverseFind</b> (CString)</pre> </td> <td colspan="2" width="410" height="16"> <pre>.LastIndexOf</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>RGB</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.FromArgb</pre> </td> </tr> <tr> <td rowspan="3" width="83" height="48"> </td> <td colspan="3" width="598" height="16"> <pre>COLORREF r =
<br />RGB(255,128,0);</pre> </td> <td rowspan="3" width="1" height="48">
<br /></td> <td width="468" height="16"> <pre>Color c =
<br />Color.FromArgb(255,128,0);</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"><span style="font-size:85%;">This actually oversimplifies, or over complicates, the problem. C# contains a number of "<a href="http://www.flounder.com/csharp_color_table.htm" target="_blank">predefined color names</a>" with really obscure names and no good graphical representation in the Help system of what they look like. The names correspond to the standard names used in HTML. However, as an example, RGB(255,0,0) is the name <b> .Red</b></span></td> <td width="468" height="16"><span style="font-size:85%;"><b>Argb</b> stands for the 4-tuple, Alpha, Red, Green, Blue, and the overload with three arguments assumes Alpha (transparency) is 255 (completely opaque).</span></td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre>COLORREF r = RGB(255,0,0)</pre> </td> <td width="468" height="16"> <pre>Color c = Color.Red;
<br /><i>or</i>
<br />Color c = Color.FromArgb(255,0,0);</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_S">S</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>SaveDC</b> (CDC)</pre> </td> <td colspan="2" width="410" height="16"> <span style="font-family:Courier New;font-size:85%;">.Save (graphics)</span> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>CClientDC dc(&wnd);
<br />int n = dc.SaveDC();
<br />...
<br />dc.RestoreDC(n);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Graphics g = wnd.CreateGraphics();
<br />GraphicsState gs = g.Save();
<br />...
<br />g.Restore(gs);</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>SetCurSel</b> (CComboBox)</pre> </td> <td colspan="2" width="410" height="16"> <pre>ComboBox.SelectedIndex = ...;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>::SetCursor</b>(AfxGetApp()-><wbr>LoadStandardCursor(<i>id</i>));</pre> </td> <td colspan="2" width="410" height="16"> <pre>.Cursor = Cursors.<i>id</i> </pre> </td> </tr> <tr> <td rowspan="28" width="83" height="433"> </td> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_APPSTARTING</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.AppStarting</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_ARROW</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.Arrow</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_CROSS</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.Cross</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <p><b><i>no equivalent</i></b></p> </td> <td width="1" height="16">
<br /></td> <td valign="top" width="468" height="16"> <pre>Cursors.Default</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_HAND</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="29" height="31" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.Hand</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_HELP</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="32" height="35" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.Help</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="28" height="31" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.HSplit</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_IBEAM</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.IBeam</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_NO</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.No</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="1"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="1"> <pre><img border="0" width="30" height="30" /></pre> </td> <td valign="top" width="468" height="1"> <pre>Cursors.NoMove2D</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="32" height="30" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.NoMoveHoriz</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="33" height="30" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.NoMoveVert</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="29" height="30" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanEast</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="29" height="30" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanNE</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="31" height="31" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanNorth</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="30" height="30" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanNW</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="30" height="30" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanSE</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="29" height="30" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanSouth</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="29" height="31" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanSW</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="29" height="29" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.PanWest</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_SIZEALL</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.SizeAll</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_SIZENESW</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.SizeNESW</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_SIZENS</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.SizeNS</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_SIZESWNE</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.SizeSWNE</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_SIZEWE</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.SizeWE</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_UPARROW</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.UpArrow</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b><i>no equivalent</i></b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="25" height="32" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.VSplit</pre> </td> </tr> <tr> <td colspan="3" valign="top" width="598" height="16"> <pre><b>IDC_WAIT</b></pre> </td> <td width="1" height="16"> <pre><img border="0" width="27" height="33" /></pre> </td> <td valign="top" width="468" height="16"> <pre>Cursors.WaitCursor</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.SetMapMode</b> (CDC)</pre> </td> <td colspan="2" width="410" height="16"> <pre>.PageScale (Graphics)</pre> </td> </tr> <tr> <td rowspan="7" width="83" height="112"> </td> <td colspan="3" width="598" height="16"> <pre><b>MM_TEXT</b></pre> </td> <td rowspan="7" width="1" height="112">
<br /></td> <td width="468" height="16"> <pre>GraphicsUnit.Pixel</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre><b>MM_LOENGLISH
<br />MM_HIENGLISH</b></pre> </td> <td width="468" height="16"> <pre>GraphicsUnit.Inch</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre><b>MM_LOMETRIC
<br />MM_HIMETRIC</b></pre> </td> <td width="468" height="16"> <pre>GraphicsUnit.Millimeter</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre><b>MM_TWIPS</b> (<sup>1</sup>/<sub>1440</sub> inch)</pre> </td> <td width="468" height="16"> <pre>GraphicsUnit.Document (<sup>1</sup>/<sub>300</sub> inch)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <i>no equivalent</i> </td> <td width="468" height="16"> <pre>GraphicsUnit.Display (<sup>1</sup>/<sub>72</sub> inch)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <pre><b>MM_ISOTROPIC
<br />MM_ANISOTROPIC</b></pre> </td> <td width="468" height="16"> <pre>GraphicsUnit.World (closest approximation)</pre> </td> </tr> <tr> <td colspan="3" width="598" height="16"> <p><i>no equivalent</i></p> </td> <td width="468" height="16"> <pre>GraphicsUnit.Display (<sup>1</sup>/<sub>75</sub> inch)</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>SetMiterLimit</b> (CDC)</pre> </td> <td colspan="2" width="410" height="16"> <pre><span style="font-size:85%;">Pen.MiterLimit = ...;</span></pre> </td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <pre><b>.SetPos</b> (CSpinCtrl)</pre> </td> <td colspan="2" width="410" height="16"> <pre>NumericUpDown.Value = ...</pre> <p><span style="font-size:85%;"><i>Note that the values of <b>.Minimum</b>, <b>.Maximum</b>, and <b>.Value</b></i> <i>are of type <b>decimal</b>. This means that to assign a value which is a fractional value, you have to use a decimal constant. To use the values, you may have to cast them from <b>decimal</b> to <b>int</b> or <b>float</b>.</i></span> </p></td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <pre><b>.SetRange</b> (CSpinCtrl)</pre> </td> <td colspan="2" width="410" height="16"> <pre>NumericUpDown.Maximum = ...
<br />NumericUpDown.Minimum = ...;</pre> <p><span style="font-size:85%;"><i>Note that the values of <b>.Minimum</b>, <b>.Maximum</b>, and <b>.Value</b></i> <i>are of type <b>decimal</b>. This means that to assign a value which is a fractional value, you have to use a decimal constant. To use the values, you may have to cast them from <b>decimal</b> to <b>int</b> or <b>float</b>.</i></span> </p></td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <pre><b>SetTimer</b></pre> </td> <td colspan="2" width="410" height="16"> <p style="margin-bottom: 0pt;"><i>place a timer object on the form and give it a name</i></p> <pre style="margin-top: 0pt;"><span style="font-family:Courier New;font-size:85%;"><i>timer</i>.Interval = ...; // can be set
<br /></span> // at design time<span style="font-family:Courier New;font-size:85%;">
<br /><i>timer</i>.Start();</span></pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>.SetViewPortExt</b>/
<br />.<b>SetWindowExt </b>(CDC)</pre> </td> <td colspan="2" valign="top" width="410" height="16"> <pre>.PageScale (Graphics)</pre> </td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <pre><b>SetWindowPos</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>.Location (changes only the top-left origin)
<br />.Size (changes width and height but not origin)
<br />.Width (changes only width)
<br />.Height (changes only height)</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" valign="top" width="598" height="16"> <pre>// Move window to X, Y retaining size
<br />ctl.SetWindowPos(NULL, X, Y, 0, 0,
<br />SWP_NOSIZE | SWP_NOZORDER);</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>ctl.Location = new Point(X, Y);</pre> <p><i><span style="font-size:85%;">Note that accessing the <b>.Location </b>member returns a <u>copy</u> of the <b>Point</b> value, so changing the values in this will not change the size in the control itself, e.g., </span></i></p> <pre>ctl.Location.x = X; // does not work</pre> <p><i><span style="font-size:85%;">changes only the value in the copy. You must assign a complete <b>Point</b> object to the <b>.Location</b> member.</span></i></p> </td> </tr> <tr> <td width="83" height="13">
<br /></td> <td colspan="3" valign="top" width="598" height="13"> <pre>// Change size to W, H and don't move
<br />ctl.SetWindowPos(NULL, 0, 0, W, H,
<br />SWP_NOMOVE | SWP_NOZORDER);</pre> </td> <td width="1" height="13">
<br /></td> <td width="468" height="13"> <pre>ctl.Size = new Size(W, H);</pre> <p><i><span style="font-size:85%;">or the values can be set independently</span></i></p> <pre>ctl.Width = W;
<br />ctl.Height = H;</pre> <p><i><span style="font-size:85%;">Note that accessing the <b>.Size</b> member returns a <u>copy</u> of the <b>Size</b> value, so changing the values in this will not change the size in the control itself, e.g., </span></i></p> <pre>ctl.Size.Width = W; // does not work</pre> <p><i><span style="font-size:85%;">changes only the value in the copy. You must assign a complete <b>Size</b> object to the <b>.Size</b> member, or assign independently to the <b>.Width</b> or <b>.Height</b> members</span></i></p> </td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <pre><b>ShBrowseForFolder</b></pre> </td> <td colspan="2" width="410" height="16"> <i><span style="font-size:85%;">No good equivalent. KB article 306285 shows how to call the underlying <b>ShBrowseForFolder</b> call in .NET 1.0; in .NET 1.1 there is a <b>FolderBrowserDialog</b> class, but it is not supported in the Common Framework, meaning you can't use it if you expect to run on a Pocket PC. Probably your best bet is to look at the Web site</span></i> <p style="margin-top: 0pt; margin-bottom: 0pt;"><a href="http://www.wintoolzone.com/dotnetcom.aspx" target="_blank"><b>http://www.wintoolzone.com/<wbr>dotnetcom.aspx</b></a></p> <p style="margin-top: 0pt;"><i><span style="font-size:85%;">where there is an implementation that does not involve the shell API and does not require Common Framework (CF) support.</span></i> </p></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>ShellExecute</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>System.Diagnostics.Process.<wbr>Start</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <span style="font-family:Courier New;font-size:85%;"><b>SHRT_MAX</b></span></td> <td colspan="2" width="410" height="16"> <b><span style="font-family:Courier New;font-size:85%;">Int16.MaxValue</span></b></td> </tr> <tr> <td colspan="4" width="687" height="16"> <span style="font-family:Courier New;font-size:85%;"><b>SHRT_MIN</b></span></td> <td colspan="2" width="410" height="16"> <b><span style="font-family:Courier New;font-size:85%;">Int16.MinValue</span></b></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>short</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>short</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>ShowWindow</b>(SW_SHOW);</pre> </td> <td colspan="2" width="410" height="16"> <pre>.Visible = true;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>.<b>ShowWindow</b>(SW_HIDE);</pre> </td> <td colspan="2" width="410" height="16"> <pre>.Visible = false;</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>sprintf</b></pre> </td> <td colspan="2" width="410" height="16"> <pre><b>ToString</b></pre> </td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <pre>3</pre> </td> <td rowspan="4" width="1" height="64">
<br /></td> <td width="468" height="16"> <pre>int v;
<br />String s;
<br />s = i.ToString();</pre> </td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%3d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <span style="font-family:Courier New;font-size:85%;">··3 </span>(leading spaces) </td> <td valign="top" width="468" height="16"> No equivalent in C# </td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%03d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <pre>003</pre> </td> <td width="468" height="16"> <pre>int v = 3;
<br />String s;
<br />s = i.ToString("D3");</pre> </td> </tr> <tr> <td valign="top" width="83" height="16"> <pre>%03d</pre> </td> <td colspan="3" valign="top" width="598" height="16"> <pre>003</pre> </td> <td width="468" height="16"> <pre>int v = 3;
<br />String s;
<br />s = i.ToString("000");</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>strcat</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>+ (applied to String objects)</pre> </td> </tr> <tr> <td colspan="4" rowspan="2" valign="top" width="687" height="32"> <span style="font-family:Courier New;font-size:85%;"><b>strcmp</b></span></td> <td rowspan="2" valign="top" width="155" height="32"> <b><span style="font-family:Courier New;font-size:85%;">.Equals</span></b></td> <td width="255" height="16"> <b><span style="font-family:Courier New;font-size:85%;">String s1;
<br />String s2;
<br />if(s1.Equals(s))</span></b></td> </tr> <tr> <td width="255" height="16"> <i><span style="font-size:85%;">note that the comparison operators work also; so you can write
<br /></span></i><span style="font-size:85%;"><b><span style="font-family:Courier New;">if(s1 <></b> <i>or</i> <b><span style="font-family:Courier New;">if(s1 == s2)</span></b> <i>or </i> <b><span style="font-family:Courier New;">if(s1 > s2)</span></b> as well as <b> <span style="font-family:Courier New;">!=</span></b>, <b><span style="font-family:Courier New;"><=</span></b> and <b><span style="font-family:Courier New;">>=</span></b>.</span></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>strrchr</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>LastIndexOf</pre> </td> </tr> <tr> <td colspan="4" valign="top" width="687" height="16"> <b><span style="font-family:Courier New;font-size:85%;">strstr</span></b></td> <td valign="top" width="90" height="16"> <b><span style="font-family:Courier New;font-size:85%;">.Contains</span></b></td> <td width="320" height="16"> <span style="font-family:Courier New;font-size:85%;">String s;
<br />s = "Permissions";
<br />if(s.Contains("miss"))
<br /> ... contains the substring</span></td> </tr> <tr> <td colspan="4" width="687" height="16"> <div align="left"> <pre><b>strtol</b>(LPCTSTR, NULL, 16)</pre> </div> </td> <td colspan="2" width="410" height="16"> <pre>int.Parse(String, "x") // throws exception</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>strtol</b>(LPCTSTR, NULL, 10)</pre> </td> <td colspan="2" width="410" height="16"> <pre>int.Parse(String, "d") // throws exception</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>strtol</b>(LPCTSTR, NULL, 2)</pre> </td> <td colspan="2" width="410" height="16"> <p><i>No equivalent</i></p> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>strtol</b>(LPCTSTR, NULL, 8)</pre> </td> <td colspan="2" width="410" height="16"> <p><i>No equivalent</i></p> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_T">T</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre>_T(...)</pre> </td> <td colspan="2" width="410" height="16"><i><span style="font-size:85%;">Not needed as all strings and characters are implicitly Unicode strings and characters.</span></i></td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_U">U</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16">
<br /></td> <td colspan="2" width="410" height="16">
<br /></td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>UINT</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>uint</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>ULONG</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>uint</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>ULONGLONG</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>ulong</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>unsigned</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>uint</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>unsigned int</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>uint</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>unsigned __int64</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>ulong</pre> </td> </tr> <tr> <td colspan="6" bgcolor="#00ffff" width="1103" height="16"> <h1><a name="1221278f4d7e7cbf_W">W</a> <a href="http://www.flounder.com/csharpfactoids.htm#Index" target="_blank"><img border="0" width="19" height="11" /></a></h1> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>WM_CLOSE</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Close</pre> </td> </tr> <tr> <td width="83" height="16">
<br /></td> <td colspan="3" width="598" height="16"> <pre>PostMessage(WM_CLOSE)</pre> </td> <td width="1" height="16">
<br /></td> <td width="468" height="16"> <pre>Close()</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>WM_DESTROY</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Closed event</pre> </td> </tr> <tr> <td width="83" height="1">
<br /></td> <td colspan="3" width="598" height="1"> <pre>void CMyWnd::OnDestroy() { ... }</pre> </td> <td width="1" height="1">
<br /></td> <td width="468" height="1"> <p><i><span style="font-size:85%;">select the Closing event for the form and type a name of the function you want, such as <b>OnClosed</b></span></i></p> <pre>private void OnClosed(Object sender,
<br />System.ComponentModel.<wbr>EventArgs e)
<br />{
<br />...
<br />}</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>WM_INITDIALOG</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>Load event</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>WM_MOVE</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>LocationChanged event</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>WM_SIZE</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>SizeChanged event</pre> </td> </tr> <tr> <td colspan="4" width="687" height="16"> <pre><b>WORD</b></pre> </td> <td colspan="2" width="410" height="16"> <pre>ushort</pre> </td> </tr> </tbody></table> <h2><span style="font-size:-1;">Acknowledgements</span></h2> <p><span style="font-size:-1;">I didn't discover all of this myself. I asked a lot of questions. Thanks to many contributors, especially those in the <b>microsoft.public.dotnet.<wbr>languages.csharp</b> and the <b>microsoft.public.dotnet.<wbr>framework.windowsforms</b> newsgroups. Particular contributors whose information I have used in this table, in alphabetical order, include</span></p> <ul><span style="font-size:-1;"><li>Mike Burton</li><li>Yan-Hong Huang</li><li>Daniel Jebaraj</li><li>Gaurav Khanna</li><li>Mattias Sjögren</li><li>Geert Verkade</li></span></ul><span style="font-size:-1;">
<br /></span>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-42976058741555755252009-03-10T08:45:00.000-07:002009-03-10T08:47:43.592-07:00Bluetooth Handsfree Profile Support for Windows Mobile 5 - The Serieshttp://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profil_116786630484523617.html<br /><br /><h2> Bluetooth Handsfree Profile Support for Windows Mobile 5 - The Series (Part 1)</h2> <div class="blogPost"> Bluetooth Handsfree Profile Support for Windows Mobile 5 - Part 1<br /><br />Have you ever run into the question of what mechanisms are there for supporting Bluetooth on your WM5 device? What has Microsoft provided to extend the Handsfree profile functionality? How can I use the Audio Gateway?<br /><br />Very good questions. In this series of articles about Bluetooth support, I'm going to try to fill in the holes. This series is geared towards developers who have experimented with the Audio Gateway and are scratching their heads as to how to get into this "black box".<br /><br />Microsoft supports Bluetooth with an architecture known as the "Audio Gateway." It consists of the core itself, the Services interface, AT Command Extension Module, Phone Extension Module, and Network Component. All of these components interact with the Core that signals the Bluetooth stack of commands and state changes. To read up on the Audio Gateway architecture, trickle into the MSDN website and search for "Bluetooth Audio Gateway."<br /><br />Now, as a developer, you're wondering, "How do I get into this darn thing and make it do what I want it to do?"<br /><br />There are a few ways to interact with the Audio Gateway (which I'll refer to as the "AG").<br /><br />Firstly, from a services standpoint, Services.exe and the underlying layer of IOCTL calls the core support call enumerations to control the AG. I've listed the constants below. They are also in the .h file. The constants are pretty self-explanatory, so I won't go into much detail about them. Basically, there is the AG service, which we can start, stop and refresh. If the service has started and a Bluetooth device has been paired with the WM5 device, a service level connection must be established with the device as to signal different commands via AT Commands (to be discussed later), which we can start and stop as well. On top of that, the AG can route audio to the Bluetooth headset.<br /><br /><pre>// You can find these within service.h<br />// IOCTL_SERVICE_START<br />// IOCTL_SERVICE_REFRESH<br />// IOCTL_SERVICE_STOP<br />// IOCTL_SERVICE_STATUS<br /><br />#define IOCTL_AG_OPEN_AUDIO 0x01<br />#define IOCTL_AG_CLOSE_AUDIO 0x02<br />#define IOCTL_AG_CLOSE_CONTROL 0x03<br />#define IOCTL_AG_SET_SPEAKER_VOL 0x04<br />#define IOCTL_AG_SET_MIC_VOL 0x05<br />#define IOCTL_AG_GET_SPEAKER_VOL 0x06<br />#define IOCTL_AG_GET_MIC_VOL 0x07<br />#define IOCTL_AG_GET_POWER_MODE 0x08<br />#define IOCTL_AG_SET_POWER_MODE 0x09<br />#define IOCTL_AG_OPEN_CONTROL 0x0A</pre><br /><br />So, by simply calling these defines within a IOCTL call, you'll be able to achieve basic services support. Note that some defines require you to pass in values. I don't want to go into too much detail about this, since we're just scratching the surface, and I'm hoping as the reader you're asking yourself, "When does the fun <strong>really</strong> start?"<br /><br /><pre>HANDLE msAGHandle = ::CreateFile( L"BAG0:", 0, 0, 0, OPEN_EXISTING, 0, 0 );<br />if ( INVALID_HANDLE_VALUE == msAGHandle )<br />{<br /> // log something with GetLastError();<br /> return;<br />}<br /><br />BOOL result = ::DeviceIoControl( msAGHandle, IOCTL_SERVICE_STOP, 0, 0, 0, 0, 0, 0 );<br />if ( FALSE == result )<br />{<br /> // log something<br />}<br /><br />::CloseHandle( msAGHandle );</pre><br /><br />Aside from the services layer, it has been hypothesized (however not actually confirmed by me) that we can replace the AT Command Extension Module to override the AG core of AT command reception and AT command processing. What happens in the AG core, once paired and a service level connection has been established, is if an AT command is received, the core will first "ask" the AT Command Extension Module if it would like to handle this command. If the AT Command Extension Module wishes to handle the command, it returns, from the interface call, "true", otherwise "false" to signal that the core does its own processing.<br /><br />So how do you replace the AT Command Extension Module?<br /><br />Easy. There are two ways to replace this module. In the Windows directory of your WM5 device, a file called "btagext.dll" exposes an interface (interface description to come) which the core dynamically links to. You can replace this file with your own file to override the AT command processing. Replacing the file can get a little messy if one doesn't have the proper access rights to overwrite Windows dlls.<br /><br />Another way is to edit the registry so that the AT Command Extension Module path points to your dll. First, copy your AT Command Extension DLL onto the device, edit the registry path "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Bluetooth\\AudioGateway\\BTAGExtModule" with your DLL path, restart the device or restart the AG service and... Voila!<br /><br />So what does your custom AT Command Extension Module have to override?<br /><br />The "btagext.dll" exposes these commands:<br /><pre>typedef DWORD (*PFN_SendATCommand) (LPSTR szCommand, DWORD cbCommand);<br />BOOL BthAGATHandler(LPSTR szCommand, DWORD cbCommand);<br />void BthAGATSetCallback(PFN_SendATCommand pfn);<br />DWORD BthAGOnVoiceTag(BOOL fOn);<br /></pre><br /><br />I leave it up to you to explore how you can replace the AT Command Extension Module. Take a look at the MSDN Website for further details about these methods. Since we are supporting the Handsfree profile, search the Bluetooth website for the .pdf file for a list of AT commands to support... Or stay tuned for a description of these AT commands.<br /><br />OK, now for the really fun stuff.<br /><br />I know some of you are in the same boat as I was, saying to yourself, "I've paired and authenticated with the device, so how do I use the AG to route audio? I can route audio via the IOCTL calls but I can't do any other in-call processing. Some libraries offered in WinCE are not exposed to me, e.g. the Network component (for network signalling), so I can't signal different in-call states."<br /><br />Personally, I've never gotten around to using the AG service, since specific libraries in the WM5 PPC and Smartphone SDK weren't included in my version and, simply put, I had no mechanism to control the AG service besides the service component via IOCTL calls.<br /><br />What to do, what to do?! Hey lets build our own Audio Gateway! Yeah! That'll be fun!<br /><h2> Bluetooth Handsfree Profile Support for Windows Mobile 5 - The Series (Part 2)</h2> <div class="blogPost"> Bluetooth HandsFree Profile Support for Windows Mobile 5 - part 2<br /><br />In our last article, we explored some of the interfaces offered by the Audio Gateway (AG) for developers.<br />The problem was that some of the mechanisms offered in WinCE to signal the AG core of specific network events are not present in the PPC and Smartphone SDK. In this article, I'll show you how to create a lightweight replacement for the AG without spending two weeks (or more) figuring out what's inside that little "black box" they call the Audio Gateway. Please be aware I've never worked for Microsoft and everything within this article should be considered "as is".<br /><br />To start, I'll give you some background information on how the AG core is constructed and then I'll share specific details on creating a connection with the Bluetooth device, processing AT commands, and routing audio to the Bluetooth chip.<br /><br />The AG core consists of 3 modules:<br /><br />Parser: Once the AG core has established a socket connection with the Bluetooth Headset device, the interactions between the WM5 device and the Bluetooth Headset are signed via the socket connection with AT Commands. The parser' responsibility is to retrieve these messages from the socket, parse them and return them to the Handler module for processing.<br /><br />Interface: Exposes methods to signal the network states and initiate commands from the services layer. It also listens for incoming Bluetooth device requests that are trying to create a baseband connection, whether synchronously or asynchronously.<br /><br />Handler: The core module that receives input from both the Interface module and the Parser module and, based on those stimuli and the internal state of the AG core, will respond accordingly, i.e. send AT command responses, create a service level socket connection, an IOCTL call to the audio driver to route voice...etc.<br /><br />The Meat and Bones of the Parser<br />The parser is quite simple. After the Handler creates a socket connection with the Bluetooth Headset (I'll talk more about that in the third installment) it passes the connected socket to the Parser module to listen for and receive incoming AT commands. Listed below are the AT commands that are supported by the Bluetooth HandsFree profile and their corresponding general definitions.<br /><br /><span style="font-size: 85%;">"AT+CKPD=200" - Indicates a Bluetooth button press</span><br /><span style="font-size: 85%;">"AT+VGM=" - Indicates a microphone volume change</span><br /><span style="font-size: 85%;">"AT+VGS=" - Indicates a speakerphone volume change</span><br /><span style="font-size: 85%;">"AT+BRSF=" - The Headset is asking what features are supported</span><br /><span style="font-size: 85%;">"AT+CIND?" - The Headset is asking about the indicators that are signaled</span><br /><span style="font-size: 85%;">"AT+CIND=?" - The Headset is asking about the test indicators</span><br /><span style="font-size: 85%;">"AT+CMER=" - The Headset is asking which indicates are registered for updates</span><br /><span style="font-size: 85%;">"ATA" - When an incoming call has been answered, usually a Bluetooth button press</span><br /><span style="font-size: 85%;">"AT+CHUP" - When a call has been hung up, usually a Bluetooth button press</span><br /><span style="font-size: 85%;">"ATD>" - The Headset is requesting the local device to perform a memory dial</span><br /><span style="font-size: 85%;">"ATD" - The Headset is requesting to dial the number</span><br /><span style="font-size: 85%;">"AT+BLDN" - The Headset is requesting to perform last number dialed</span><br /><span style="font-size: 85%;">"AT+CCWA=" - The Headset has enabled call waiting</span><br /><span style="font-size: 85%;">"AT+CLIP=" - The Headset has enabled CLI (Calling Line Identification)</span><br /><span style="font-size: 85%;">"AT+VTS=" - The Headset is asking to send DTMF digits</span><br /><span style="font-size: 85%;">"AT+CHLD=" - The Headset is asking to put the call on Hold</span><br /><span style="font-size: 85%;">"AT+BVRA=" - The Headset is requesting voice recognition</span><br /><span style="font-size: 85%;">"ATH" - Call hang-up</span><br /><br />Once the parser receives one of these commands, it parses the received buffer for these character sequences and passes the parsed command back to the Handler (discussed later) as an enumeration that the Handler will be able to identify and process.<br /><br />The Meat and Bones of the Interface Module<br />The Interface module exposes methods for signaling the Handler of network connections, listens for incoming connections and calls Handler methods of services requests.<br /><br />Firstly, the Interface layer must ensure that the Bluetooth stack has been started, otherwise there's no point in processing any other commands for the network layer or the services layer. The mechanism in which the underlying layer signals that the Bluetooth stack is fully functional is via waiting on an Event Handle. Here's some code to support this:<br /><pre>#define BTH_NAMEDEVENT_STACK_INITED L"system/events/bluetooth/StackInitialized"<br />HANDLE btStack = ::OpenEvent( EVENT_ALL_ACCESS, FALSE,BTH_NAMEDEVENT_STACK_INITED );<br /><br />// m_closeEvent is a previously Created Event to signal other<br />// waiting threads to stop waiting (created by the developer)<br /><br />if( btStack && m_closeEvent )<br />{<br /> HANDLE waitObjects[] = {btStack, m_closeEvent};<br /> DWORD result = ::WaitForMultipleObjects( 2, &waitObjects[0], FALSE, INFINITE );<br /> ::CloseHandle( btStack );<br /> if( result - WAIT_OBJECT_0 == 0 )<br /> {<br /> //The Bluetooth stack is up, signal core module to finish initialization<br /> }<br /> else if( 1 == result - WAIT_OBJECT_0 WAIT_FAILED == result )<br /> {<br /> // We've been signaled to close, Bluetooth stack is down!<br /> // Or our application has signaled us to stop waiting<br /> }<br />}</pre><br />Here we wait on the Open Bluetooth Stack Initialized Event or our own pre-created event to indicate either the Bluetooth stack is operational or to exit, since our application is closing too.<br /><br />This same scheme also works for waiting for a synchronous or asynchronous baseband connection (Which I'll discuss further in the third installment), but instead of waiting on the BTH_NAMEDEVENT_STACK_INITED wstring, we wait on the Opened Event BTH_NAMEDEVENT_CONNECTIONS_CHANGED, as defined below:<br /><pre>#define BTH_NAMEDEVENT_CONNECTIONS_CHANGED L"system/events/bluetooth/ConnectionsChange"</pre><br />If the Interface module receives a signal of this event, it notifies the Handler module to check its baseband connections for changes.<br /><br />Aside from the listening for baseband connections, or if the Bluetooth Stack is up, the Interface module also want to process service commands and network layer notifications. So, following the services interface, as mentioned in the previous article, the module needs to support:<br /><br />Opening audio<br />Closing audio<br />Opening a control channel<br />Closing a control channel<br />Getting/setting the microphone volume<br />Getting/setting the speaker volume<br />Getting/setting the power mode<br /><br />And these methods simply call the Handler methods for processing (Which I'll talk about more in the third installment).<br />For reliability, however, a developer can't create a control channel if no Bluetooth device has been paired with the WM5 device (obviously). Also, a developer can't open up a control channel without a fully initialized Interface Module (Bluetooth Stack is operational).<br />Secondly, you can't open an audio channel if there is no control channel open.<br /><br />On the Network signaling side, the Interface Module exposes a method call to the network layer, which passes a number to identify the type of network call being signaled. The supported signaling calls are:<br /><pre>#define NETWORK_EVENT_CALL_IN 0x00<br />#define NETWORK_EVENT_CALL_OUT 0x01<br />#define NETWORK_EVENT_CALL_CONNECT 0x02<br />#define NETWORK_EVENT_CALL_DISCONNECT 0x03<br />#define NETWORK_EVENT_CALL_REJECT 0x04<br />#define NETWORK_EVENT_CALL_INFO 0x05<br />#define NETWORK_EVENT_CALL_BUSY 0x06<br />#define NETWORK_EVENT_RING 0x07<br /><br />void BthAGOnNetworkEvent( DWORD dwEvent, LPSTR pszParam );</pre><br />If you're designing the Interface module and the appliction accesses the network layer, you'll have to support these defines and signal your Handler class to handle these events. For more detail on these libraries, visit the MSDN website.<br /><br /><b>Important Note</b>:<br />If you're developing the Interface Module alongside Microsoft's Audio Gateway, be sure that you turn off the MS AG in your Interface Module initialization code <strong>before doing anything else</strong>. If you don't, the Microsoft's AG will interfere with *your* Gateway application. The first article in this series lists code that turn offs the service. Please refer to it for the IOCTL call that corresponds to the service shutdown.<br /><br />Ok, now we're getting to the really juicy part, The Handler Module. What's ticking underneath that hood, you might ask. In this article, we've explored a system level overview of the AG core and gone into details about the different responsibilities associated with the Parser Module and the Interface Module. But what ties them all together? The Handler module!<br /><br />Stay tuned for a detailed description of the Handler Module...<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html" title="permanent link">#</a> posted by Quan Nguyen @ 11:41 PM <span class="item-action"><a href="email-post.g?blogID=35928092&postID=116786702940637421" title="Email Post"><img class="icon-action" alt="" src="img/icon18_email.gif" /></a></span><span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="post-edit.g?blogID=35928092&postID=116786702940637421" title="Edit Post"><img class="icon-action" alt="" src="img/icon18_edit_allbkg.gif" /></a></span> </div> </div> <a name="comments"></a> Comments: <div class="blogComment"> <a name="1154890784467266841"></a> <a href="http://thefiles.macadamian.com/2007/01/www.internet-explorer-errors.com/index.php?k=internet+explorer+6,7" rel="nofollow">Internet Explorer may not respond</a> when you click Print or Print Preview in the File menu.When you try to connect to Web folders, you may receive the following error message:The current operation could not be completed because an unexpected error has occurred.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1185537300000#c1154890784467266841" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <a href="http://thefiles.macadamian.com/2007/01/www.internet-explorer-errors.com/index.php?k=internet+explorer+6,7" rel="nofollow">David</a> : 7:55 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=1154890784467266841" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="3343327731876113749"></a> What version were you using?<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1185541320000#c3343327731876113749" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/12753716679505402680" rel="nofollow">Jason Mawdsley</a> : 9:02 AM </div> <span class="item-control blog-admin pid-680504776"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=3343327731876113749" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="8802477095857629169"></a> This is very useful artical, I have developed tiny AG for bluetooth Hands Free (HF) device but I am facing issue to connect with HF when HF is made ON/OFF means connection from HF side.<br /><br />I am able to make socket connection with BT_ADDRESS from registry to HF but how can I make it possible that HF make connection with me when it made start.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1187781720000#c8802477095857629169" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Anonymous</span> : 7:22 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=8802477095857629169" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="3686780727747065999"></a> There are a few options you can use to detect that the Headset has either turned on or is trying to communicate with your device.<br />You can listen to the event "system/events/bluetooth/ConnectionsChange" just call OpenEvent with this string. Otherwise you can build a notification framework around RequestBluetoothNotifications(...). Look on msdn for more information about this. If your bluetooth device is paired and has turned on it will notify with an event<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1187797560000#c3686780727747065999" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 11:46 AM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=3686780727747065999" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="5506064403405626122"></a> Another problem that you might run into is that MS AG might be interferring with your tiny AG. If that is the case simple do a IOControl call to the "BAG" to stop the control channel<br />#define IOCTL_AG_CLOSE_CONTROL 0x03<br />#define IOCTL_AG_OPEN_CONTROL 0x0A<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1187797920000#c5506064403405626122" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 11:52 AM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=5506064403405626122" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="5726560481909111624"></a> Thanks for your prompt response.I tried both the methods to get event on connection change but I am facing issue like I get disconnect event immediately as I get connect event. I figure out the event type by second method Request......<br />I have already stoped MS AG (BAG ) service.<br />How can my AG accept the initiated connection request and get socket handle or should my AG try to connect with the BT_Address what my AG currently doing??<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1187869440000#c5726560481909111624" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 7:44 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=5726560481909111624" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="6329209766253444796"></a> Try this out, don't stop the MS AG service entirely, keep it running. If you receive the disconnection from the headset (e.g. the headset has powered off or gone out of range) close the connection and start the MS AG control channel. When you receive a notification that there is a baseband connection again, stop MS AG control channel and then try to connect to the headset with your tiny AG. And yes connect with the BT_Address from the registry. Does this answer your question? - I'm a little unclear as to your second post.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1187875920000#c6329209766253444796" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 9:32 AM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=6329209766253444796" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="3625900985854491225"></a> Hello Quan Nguyen,<br /><br />I tried your suggested way to connect with HF by stopping MS AG control channel on baseband connection event but the issue is my AG fails to connect with HF if my AG try to connect with HF on base band connection event, means MS AG start to make connection with HF earlier than my AG start on the event.<br /><br />My AG is able to make connection with HF after few second (around 1)of the event by closing already opened MS AG connection by IOCTL_AG_CLOSE_CONTROL.<br /><br />How can I stop MS AG to make connection on this connection event? or any other event that I can use for knowing about MS AG made connection with HF after base band connection event.<br /><br />One thing I also want to know is if I stop entire MS AG service is there any functinality that may be affected like pairing or file transfer or other???<br /><br />Any help will be very helpful to me.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1187959140000#c3625900985854491225" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 8:39 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=3625900985854491225" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="5722009295016375693"></a> Yes the MS AG when it receives the baseband notification will connect faster than your AG. And from my experience this is unavoidable unless you turn the MS AG off entirely. If MS AG service is running I do not know of any "clean" way of stopping the MS AG service from trying to connect.<br />You will be able to see that the headset makes a connection with the system through the RequestBluetoothNotifications notifications and you can equate that if you're not connect to it, it must be the MS AG.<br /><br />If you turn off MS AG entirely, pairing and file transfer will not be affected (to my knowledge). However functionality related to BT audio while *your* AG has control of the control channel will be affected if you don't support it properly.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1187973720000#c5722009295016375693" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 12:42 PM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=5722009295016375693" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="6187800926599789754"></a> Hello Quan Nguyen,<br /><br />Thanks for your response.<br />I did it by stopping MS AG entirely.<br />Again I have one issue related to connect() API with blocking mode. When HF is already OFF and I am trying to make connection by connect() it blocks for ever and it hangs my application. and also normally when HF is ON connect() takes 7-10 seconds to return. Can you please give me some guide line or how to tackle with such situation.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1188390540000#c6187800926599789754" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 8:29 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=6187800926599789754" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="5996816584342861189"></a> Well there a few things you can do to get around this. You can always run a multi-threaded application. One thread would call the connect() and on another thread you can set a timer which will closesocket() and stop the connect() from blocking. You can also use the select() method with a timeout. Drop by MSDN and take a look at the methods for socket programming. When the Headset is ON and it takes 7-10 seconds to connect, I think this is unavoidable. This is the latency it takes for the bluetooth connection to negotiate properly. From my experience it shouldn't take that long. If you analyse your code and it's not because of something you're doing in your application then from your perspective there is really nothing you can do (I believe - from an application level implementation).<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1188409800000#c5996816584342861189" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 1:50 PM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=5996816584342861189" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="2319074283607825506"></a> Hello Quan Nguyen,<br /><br />One time more I need your help.<br />I already created complete service for bluetooth AG and it works fine.<br /><br />Issue I am facing in DOPOD 810 and HTC TyTN is Createfile("PFX0",0,0,NULL,OPEN_EXISTING,0,NULL);<br /><br />But it fails every time I try to call createfile() and return invalid handle (0xFFFFFFFFF).<br /><br />It is called in multithreaded application.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1191499260000#c2319074283607825506" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 8:01 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=2319074283607825506" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="904026302460133107"></a> Hi,<br />A few things here,<br />1# For your CreateFile(...) make sure that it is L"PFX0" and not "PFX0". I would imagine this is important. The compiler should catch this<br />2# Make sure that the index is correct, possibly it could be PFX1..etc<br />3# Make sure that you can find this within the active drivers list [HKEY_LOCAL_MACHINE\Drivers\Active] within the registry of the device<br />4# If createFile(...) returns an error what does GetLastError() return, this could reveal some possible hints.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1191590640000#c904026302460133107" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 9:24 AM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=904026302460133107" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="5354252978454463583"></a> Hello Quan Nguyen,<br /><br />One hint I want, is service I made for tiny bluetooth gateway is working correctly with HTC Touch. I am facing issue with TyTN device is event socket gets connected with Hands Free it doesn't start to send AT commands to my service. Also some time I start to connect and it doesn't gets connected forever. Is there any thing missing to say bluetooth stack after socket gets closed??<br /><br />Socket connection is not smooth as HTC Touch device I am getting.<br /><br />I try to connect with hands free when STACK_UP, connect event from stack.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1192085880000#c5354252978454463583" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 2:58 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=5354252978454463583" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="6384300681656191971"></a> Hello Quan Nguyen,<br /><br />I want to close connection on removing pairing from settings on PDA.<br /><br />Can you please suggest me the way how can I get notification of removing perticular pairing??<br /><br />One thing I found with my AG is once my AG gets connected with HF and I remove pairing from PDA, still registry entry for the same HF is there and not removed while in case of not connected with HF via my AG it removes the registry on removing pairing.<br /><br />Any thing left to inform stack to take that action after closing socket??<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1192694040000#c6384300681656191971" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">paresh</span> : 3:54 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=6384300681656191971" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="2246234068367017028"></a> Hello Quan Nguyen,<br /><br />I really want help from you,<br /><br />My service for BTAG works fine but I am facing issue for making pairing.<br />Pairing logic I am using from default , When device gets paired my service will try to make connection.<br /><br />I handled BTE_KEY_REVOKED event to remove connection on removing pairing. Problem I am facing with Jabra BT135 is after removing pairing if I try to make pairing again then Jabra device continuously asking for passkey and give incorrect passkey msg.<br /><br />On removing pairing my service just close the socket and tear down the connection. I think any thing is missed out during closing connection hence again pairing create issue.<br /><br />Can you please tell me for closing connection with BTHF just close socket in any condition like active voice or active call? or anything need to take care with BTHF or stack.<br /><br />After removing pairing if I try it again, device found successfully and asking for passkey again and again.<br /><br />How can I tell BTHF or stack to remove previous connection completely sp I can make fresh pairing and new connection again??<br /><br /><br />Please respond atleast.<br /><br />Thanks in advance.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1194231540000#c2246234068367017028" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 9:59 PM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=2246234068367017028" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="8958006165572900846"></a> Hello Quan Nguyen,<br /><br />I didn't receive any reply for earlier post.<br /><br />Can you please reply for this one atlest?<br /><br />Proble I am facing is receiving AT commands.<br /><br />After making BT radio ON when my AG try to connect with BTHF and gets connected and negotiated with proper At commends and responses successfully but after that my AG didn't receive any AT commands for call operating like ATA,CHUP or BLDN and none. When my AG sends AT commands like RING it operates correctly and play ring but my AG didn't receive any At commands from HF.<br /><br /><br />This problem happens only when I break active connection by making BT radio OFF. It doesn't create any problem if I break active connection by making BTHF OFF. Why my AG didn't get any AT commands from BTHF?????<br /><br />Is there anything to say to BT stack or BTHF???<br /><br />Any registry to cahnge?<br />When I make BTHF off and try to make connection after makinf ON, it works fine but not working when BT radio is made OFF and then ON, it gets negotiated correctly but after that not responding well and At commands are not received.<br /><br />Please respond at lest, even have no answer.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1195457940000#c8958006165572900846" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 2:39 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=8958006165572900846" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="24688334092667889"></a> Hi Paresh,<br />My apologies for not responding, I'm not a part of the Macadamian Files any longer and hence have not checked this blog site for quite some time.<br /><br />My apologies again<br /><br />Regards,<br /><br />Quan Nguyen<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1196112420000#c24688334092667889" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 4:27 PM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=24688334092667889" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <a name="7368647186619483583"></a> How can I control the AG to connect HF by my application?<br />I tried to use the bluetooth api, suck as: BthCreateACLConnection, BthCreateScoConnection, or via socket directly. But all did work.<br />Because the AG didn't know the connection status. Maybe i have to use the AG to connect HF in the application.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support_03.html?showComment=1198636620000#c7368647186619483583" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/08422535923513620930" rel="nofollow">Liang xing yuan</a> : 9:37 PM </div><br /><h2> Bluetooth HandsFree Profile Support for Windows Mobile 5 - The Series (part 3)</h2> <div class="blogPost"> In the last two articles, we talked about the different ways to interact with Microsoft's Audio Gateway (AG). We then focused on how to start writing your own light-weight Audio Gateway, since some versions of the PPC and Smartphone SDK do not include mechanisms to support control of the AG. In the second article, we took a system level view of the AG core and gave enough detail to create a Parser and Interface Module.<br /><br />Today, we'll get to the real guts, and this is what heroes are made of: the Handler Module. However, be warned that this is not for the timid, nor the faint of heart. We'll dive into the deep end right away!<br /><br />This third and last installment will discuss how to create the Handler Module, which includes processing the services and network commands from the Interface module; processing the AT Commands from the Parser Module, starting the service/control level socket connection with the Bluetooth Device; and routing audio to the Bluetooth chip.<br /><br />Yeah, that's right--what you've been waiting for! With this information, you can do loads of cool things like streaming mp3 music from your mobile device to your bluetooth headset. Wow! Imagine what else you can do with a little imagination!<br /><br /><h3>The Guts of the Handler Module</h3><br />The guts of the Handler Module contains four small sub-modules, the connection processing, the AT command processing, network notification processing and the services processing. We'll break down these four sub-modules in this article.<br /><br /><h4>Creating a Socket Connection with the Bluetooth HandsFree device:</h4><br />First, we assume that the Bluetooth device has already been paired with WM5 device, if not then do so right now! Start->Settings->Connections->Bluetooth... you know the rest, if not consult your WM5 Device User's Manual on how to pair with a Bluetooth device.<br /><br />Once the pair has been completed and Microsoft's AG has been turned off (See the previous article), we're ready to create a service level connection with the Bluetooth device.<br /><br />The pairing of the Bluetooth device will create an entry in the registry, under [HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Bluetooth\\AudioGateway\\Devices]. In this registry folder will be numbered folders for the different Bluetooth devices that have been paired with the WM5 device. These folders consist of a socket address and the associated service value which the connection offers, in our case, the Handsfree profile service. To create a service/control-level socket connection, first iterate through the numbered folders to get the right address and service that corresponds to the device that you want to create a connection with. Then, simply connect with the Bluetooth device by using the standard winsock socket connection scheme as shown in the code below:<br /><br /><pre>// make sure to include these<br />#include <winsock2.h><br />#include <ws2bth.h><br /><br />// in a function to create the connection, do this<br />// create a Socket<br />m_socket = socket(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);<br />if (INVALID_SOCKET == m_socket)<br />{<br /> // Failed to create socket: Log something here with GetLastError();<br /> return;<br />}<br /><br />// Fill the socket addr structure with the bluetooth device information<br />SOCKADDR_BTH socketAddr = {0};<br />socketAddr.serviceClassId = /*Service value from the registry goes here*/;<br />socketAddr.addressFamily = AF_BTH;<br />socketAddr.btAddr = /*Address from the registry goes here*/;<br /><br />// connect to the device<br />if( SOCKET_ERROR == connect(m_socket, (SOCKADDR *)&m_addr, sizeof(m_addr)) )<br />{<br /> // Failed to connect: Log something here with GetLastError();<br /> return;<br />}</pre>Simply put, get the registry value, create the socket, fill the SOCKADDR_BTH structure with the registry value and try to connect to the Bluetooth device.<br /><br /><h4>Parse AT Command Processing and Initialization Hand-shaking</h4><br />So, we've created a service/control level connection with the Bluetooth device, now what? Well, once the Bluetooth device has detected a connection, it will send initialization codes as AT Commands. It's the Parser's job to parse these initialization codes and send them to us to send to the Handler Module for processing.<br /><br />To receive these commands, we'll need to receive, from the socket, i.e.<br /><pre>// create an array of char with a size of RECEIVE_BUFFER_SIZE (that's your define)<br />// with s(the socket that was just connected)<br />int result = recv(s, buffer, RECEIVE_BUFFER_SIZE, 0);</pre><br />And subsequently send out responses through the same socket the AT Command responses, i.e.<pre>// "command" is a std::string and "s" is the socket<br />// that has the connection to the Bluetooth device<br />::send(s, command.c_str(), command.size(), 0);</pre><br /><br />The initialization hand-shaking is outlined below. However, for a detailed overview of this call flow <a href="http://www.bluetooth.com/NR/rdonlyres/C0F90A55-BDE4-4FB3-A4FF-DAB0F137DBDF/1762/HFP15_SPEC_V10r00.pdf">go to the Bluetooth website </a>.<pre> Headset AG<br /> | |<br /> | AT+BRSF=<supported> |<br /> |--------------------->| 1.<br /> | |<br /> | +BRSF:<ag> |<br /> |<---------------------|<br /> | OK |<br /> |<---------------------|<br /> | |<br /> | AT+CIND=? |<br /> |--------------------->| 2.<br /> | |<br /> | +CIND:... |<br /> |<---------------------|<br /> | OK |<br /> |<---------------------|<br /> | |<br /> | AT+CIND |<br /> |--------------------->| 3.<br /> | |<br /> | +CIND:... |<br /> |<---------------------|<br /> | OK |<br /> |<---------------------|<br /> | |<br /> | AT+CMER= |<br /> |--------------------->| 4.<br /> | OK |<br /> |<---------------------|<br /> | |<br /> | |</pre><br />Note that the OK command send string as follows: "\r\nOK\r\n"<br /><br />1. The Headset first sends the AG the features that it supports and in turn the AG sends back features that are supported.<br /><br />Listed below are constants to define the end of the AT command (after the "=" sign)<br /><br /><pre>#define HF_FEATURE_EC_ANDOR_NR 0x01<br />#define HF_FEATURE_CALL_WAITING_THREEWAY_CALLING 0x02<br />#define HF_FEATURE_CLI_PRESENTATION 0x04<br />#define HF_FEATURE_VOICE_RECOGNITION_ACTIVATION 0x08<br />#define HF_FEATURE_REMOTE_VOLUME_CONTROL 0x10<br /><br />#define AG_FEATURE_THREE_WAY_CALLING 0x01<br />#define AG_FEATURE_EC_ANDOR_NR 0x02<br />#define AG_FEATURE_VOICE_RECOGNITION 0x04<br />#define AG_FEATURE_INBAND_RINGTONE 0x08<br />#define AG_FEATURE_ATTACH_NUMBER_TO_VOICETAG 0x10<br />#define AG_FEATURE_REJECT_A_CALL 0x20</pre><br />These values can be OR'ed together to create the support value, e.g. if we only want to support three-way calling and reject a call features the value would be 0x21. Subsequently, if the headset only supports voice recognition activation and remote volume control, it would send to the AG 0x18. Hence, the string which would be sent out from the AG to the headset would be "\r\n+BRSF:%d\r\n", where %d is equal to the features supported.<br /><br />Note the new line and carriage return before and after the command. These are classic AT Command delimiters. See the Bluetooth Spec for details.<br /><br />2. The next message sent from the Headset to the AG is a request by the Headset to the AG to indicate which indicators are supported by the AG. An example of the response string is as follows: "\r\n+CIND:<br /><br />(\"service\",(0,1)),(\"call\",(0,1)),(\"callsetup\",(0-3))\r\n"<br /><br />3. The headset then requests the status of those indicators. In our example we respond with the string "\r\n+CIND: %d,%d,%d\r\n", where the %d are defined:<br /><br />first %d indicates that we have cellular service (from the listed values this could be 0-1)<br />second %d indicates that we're in a call: 0 for false (from the listed values this could be 0-1)<br />third %d indicates the current call set-up: 0 for idle (from the listed values this could be 0-3)<br /><br />4. Finally, the headset sends a request to enable the indicator status update in the AG.<br /><br />NOTE: From time to time, in my experience, what follows with some devices that the microphone volume information is sent after step 4.<br /><br />ALSO NOTE: In the last article, we discussed the different AT commands which can be expected to be received by the AG, the additional commands not mentioned in this article are out of scope, i.e. "AT+BLDN" - last number dialed, which requires the developer to have some grasp of the RIL layer. However, from a purely simple view, sending back an "\r\nOK\r\n" to the headset for these commands will be sufficient. But, I've given enough information that if the developer does understand the RIL and has implemented telephony functionality, they will be able to piece together how processing of these AT commands can be done. Keep a look out for additional articles about RIL if interested.<br /><br />OK, we're done with the initialization! WOW! that was a lot of information. Let's move on to network signaling.<br /><br /><h4>Network Signaling of In-call States:</h4><br />As mentioned in the second article from the Interface layer, there are a few messages which will be signaled by the Interface Module to the Handler module that need to be supported: Incoming Call, Outgoing Call, Call Connected, Call Disconnected, Call Rejected, Call Busy, Call Waiting and Call Ringing. Listed below are the AT Commands sent to the headset for the corresponding Network event to signal the Headset into a different state<br /><br />Incoming Call<br /><pre>"\r\n+BSIR:0\r\n"<br />"\r\n+CIEV:3,1\r\n"</pre><br />Outgoing Call<br /><pre>"\r\n+CIEV:3,3\r\n"</pre><br />Call Connected<br /><pre>"\r\n+CIEV:2,1\r\n"<br />"\r\n+CIEV:3,0\r\n"</pre><br />Call Disconnected and Call Rejected<br /><pre>"\r\n+CIEV:2,0\r\n"</pre><br />Call Waiting<br /><pre>"\r\n+CCWA:\"0\",0,1\r\n"</pre><br />Call Ringing<br /><pre>"\r\nRING\r\n"</pre><br />Almost done! Let’s move to the final section--voice routing.<br /><br /><h4>Services Processing:</h4><br />In the last article, we talked about the Interface Module and how the Handler Module needs to support method calls from the Interface Layer. In this section, we'll go deeper into these calls to see how we can accurately process them. The commands are listed as:<br /><br />Opening Audio<br />Closing audio<br />Opening a control channel<br />Closing a control channel<br />Getting/setting the mic volume<br />Getting/setting the speaker volume<br />Getting/setting the power mode<br /><br />I leave it up to the reader to be able to handle the start and stop of your own AG service and also the mic/speaker and power getting and setting methods, since they are trivial.<br /><br />Open/Close Control Channel: from the previous section, we learned how to connect to the Bluetooth socket to create a service level connection with the remote Bluetooth device. Hence, to handle the Open Control Channel command, we'll need to create some reliability and error checking around this socket connection. To close the control channel, all that is needed is to close the connected socket with a Winsock call. I leave it up to the reader to choose an appropriate method to shut down the socket connection.<br /><br />Finally, the last piece is to open and close the audio, and this is not a trivial task.<br /><br />First, we need to create a synchronous connection with the Bluetooth device. If you're lucky enough, you'll already have the libraries for creating this connection. Unfortunately, this is an article that describes a work-around if you don't have this library.<br /><br />In the Windows directory, you'll find the DLL "btdrt.dll." You'll need to dynamically link to a few methods to get the audio connection. Listed below is example code to call the create synchronous connection and shut down the synchronous connection (which we'll need to route audio):<br /><br /><pre>//******Note that the developer needs to call<br />//before these calls call ::LoadLibrary(...)<br />//once finished with these calls call ::FreeLibrary(...)<br /><br />// Code for creating a SCO connection<br />typedef int (*BthCreateSCOConnectionWrapper)( BT_ADDR*, unsigned short* );<br />BthCreateSCOConnectionWrapper proc;<br />HMODULE hMod;<br />if(NULL == (hMod = ::GetModuleHandle(L"\\Windows\\btdrt.dll")))<br />{<br /> // Log something since we can't find the module<br /> return;<br />}<br /><br />if(NULL == (proc = (BthCreateSCOConnectionWrapper)::GetProcAddress(hMod,<br />L"BthCreateSCOConnection")))<br />{<br /> // Log something since we can't find the method<br /> return;<br />}<br />//ptrBTAddr is a pointer to the Bluetooth Address--the same address we created the service level connection with<br />//ptrHandle is a pointer to an unsigned short which will be filled with the handle to the SCO connection<br />proc(ptrBTAddr, ptrHandle);<br /><br /><br />// Code for closing the SCO connection<br />typedef int (*BthCloseConnectionWrapper)( unsigned short );<br />BthCloseConnectionWrapper proc;<br />HMODULE hMod;<br />if(NULL == (hMod = ::GetModuleHandle(L"\\Windows\\btdrt.dll")))<br />{<br /> // Log something since we can't find the module<br /> return;<br />}<br /><br />if(NULL == (proc = (BthCloseConnectionWrapper)::GetProcAddress(hMod,<br />L"BthCloseConnection")))<br />{<br /> // Log something since we can't find the method<br /> return;<br />}<br />// handle is the pointer to the unsigned short value that was passed in to create the SCO connection<br />return proc( handle );</pre><br /><br />Once we have a service level connection, a SCO connection with the Bluetooth device,<br />we can call the audio driver to route to the Bluetooth chip.<br /><br /><pre>#define WODM_BT_SCO_AUDIO_CONTROL 500<br />waveOutMessage(0, WODM_BT_SCO_AUDIO_CONTROL, 0, TRUE);</pre><br />To close the audio channel, first signal the audio driver to stop routing to the Bluetooth chip and close the SCO connection.<br /><pre>waveOutMessage(0, WODM_BT_SCO_AUDIO_CONTROL, 0, FALSE);</pre><br />And that's it!<br /><br />I hope that this has been an adventure. Play around with what has been shown; contact me if there is anything missing. I've omitted the getting and setting of the registry values with regards to different call states, volume settings and feature supports. However, if you're interested, take a look on the MSDN websites for registry settings related to the Audio Gateway and apply them into your architecture (and AT Command processing).<br /><br />Best of luck in your Bluetooth Handsfree Adventures!<br /><br />If you've read this series in its entirety drop me a line, I would love to hear what you've thought about the article.<br /><br />Look for more articles related to Bluetooth and Telephony in the near feature by me!<p class="blogger-labels">Labels: <a rel="tag" href="http://thefiles.macadamian.com/labels/audio%20gateway.html">audio gateway</a>, <a rel="tag" href="http://thefiles.macadamian.com/labels/Bluetooth.html">Bluetooth</a>, <a rel="tag" href="http://thefiles.macadamian.com/labels/c++.html">c++</a></p><br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html" title="permanent link">#</a> posted by Quan Nguyen @ 2:02 PM <span class="item-action"><a href="email-post.g?blogID=35928092&postID=116787119621009699" title="Email Post"><img class="icon-action" alt="" src="img/icon18_email.gif" /></a></span><span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="post-edit.g?blogID=35928092&postID=116787119621009699" title="Edit Post"><img class="icon-action" alt="" src="img/icon18_edit_allbkg.gif" /></a></span> </div> </div> <a name="comments"></a> Comments: <div class="blogComment"> <a name="8036509865267979715"></a> Hello Quan,<br /><br />great article :dumpup:<br />I've enjoyed reading a lot :)<br /><br />Could you give a hint how to redirect a2dp to wiress stereo headset?<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1180557420000#c8036509865267979715" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Anonymous</span> : 4:37 PM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=8036509865267979715" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="3242985085023399056"></a> Hi,<br />Thanks for the comments. A2DP is quite involved and possibly would require an additional article(s) ;-) to describe. I would like to note that A2DP streaming audio is not done through the narrow band voice on the SCO channel. In any case it's not a trivial task to undertake. What exactly are you having trouble with? Have you referred to the bluetooth spec for A2DP profile? <a href="http://www.bluetooth.com/NR/rdonlyres/800D10CD-DE3D-4D51-ABC0-726C8DF26151/921/A2DPspecv10.pdf" rel="nofollow">A2DP Profile Link</a><br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1180618680000#c3242985085023399056" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 9:38 AM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=3242985085023399056" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="8912115704515651302"></a> Hi Quan,<br /><br />thanks for the link. Great info.<br />I tried to set up a a2dp connection and wasn't successful so far.<br /><br />I would love to read an a2dp article by you :)<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1180636500000#c8912115704515651302" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Anonymous</span> : 2:35 PM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=8912115704515651302" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="6293613688670612297"></a> Hi Quan,<br /><br />It is very useful to understand , how to switch audio between device and bluetooth hands free. I am facing issue here in DOPOD 810 is I am able to route audio from device to bluetooth hands free as your suggested way, but routing from hands free to device is something funny. I just close SCO connection and send 500 (FALSE) to driver and I loose audio from either side, what it require is stop/start audio after starting it again I am able to route. Same thing is done in default phone hands free usage, it can route audio anywhere without stop/start. Only difference I am getting here is I am able to route audio from hands free to device for cell call only but If I try same for music or audio played with WaveOut API then above problem occurs. Any idea will help me lot I stuck with it.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1192437060000#c6293613688670612297" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 4:31 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=6293613688670612297" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="1587302210178999562"></a> <span class="deleted-comment">This post has been removed by the author.</span><br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1192477620000#c1587302210178999562" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 3:47 PM </div> <span class="item-control blog-admin"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=1587302210178999562" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="2469313782213032572"></a> Hi Paresh,<br />So after closing the SCO conneciton calling<br />waveOutMessage(0, 500, 0, FALSE); gives you no audio?<br />Does the call fail or is it successful, waveOutMessage(...) usually comes with a return code. If it is successful quite possibly you need to call the RIL audio set audio method, i.e. call RIL_SetAudioDevices(HRIL, RILAUDIODEVICEINFO* ); which is from the ril.dll within the Windows system folder.<br />If you're having a hard time finding the definition of this method try finding the ril.h file on google.<br /><br />Basically this translates to a IOControl call to the WAV driver to route audio<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1192477680000#c2469313782213032572" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/13136230095345799666" rel="nofollow">Quan Nguyen</a> : 3:48 PM </div> <span class="item-control blog-admin pid-2007684100"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=2469313782213032572" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="1550961493065070358"></a> Hello Quan,<br /><br />I am trying to switch audio from HF to device with DeviceIOControl() with IOCTL IOCTL_WAV_MESSAGE and<br />suggested msg value 500 with dwParam2 -> TRUE/FALSE in MMDRV_MESSAGE_PARAMS structure. I am able to route cell call audio only without STOP/START but not other audio.<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1192524720000#c1550961493065070358" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon anon-comment-icon"><img src="img/anon16-rounded.gif" alt="Anonymous" style="display: inline;" /></span> <span class="anon-comment-author">Paresh</span> : 4:52 AM </div> <span class="item-control blog-admin pid-1764264767"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=1550961493065070358" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="1199817923336653552"></a> hi this is good article but it would have been better for me if i could have it for linux. such as handfree profile implememntation on linuc system..<br /><br />thanks but..<br />good one<br />thanks a lot<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1200985080000#c1199817923336653552" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/10605034583746944633" rel="nofollow">pamya</a> : 1:58 AM </div> <span class="item-control blog-admin pid-1256639372"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=1199817923336653552" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <div class="blogComment"> <a name="7799330304143358153"></a> please give me some guidance for the same for linux<br /> <div class="byline"><a href="http://thefiles.macadamian.com/2007/01/bluetooth-handsfree-profile-support.html?showComment=1200985200000#c7799330304143358153" title="permanent link">#</a> posted by <span style="line-height: 16px;" class="comment-icon blogger-comment-icon"><img src="img/b16-rounded.gif" alt="Blogger" style="display: inline;" /></span> <a href="profile/10605034583746944633" rel="nofollow">pamya</a> : 2:00 AM </div> <span class="item-control blog-admin pid-1256639372"><a style="border: medium none ;" href="delete-comment.g?blogID=35928092&postID=7799330304143358153" title="Delete Comment"><span class="delete-comment-icon"> </span></a></span> </div> <a name="1157969322038082142"></a> Hello QUAN,<br /><br />It is really very good article.<br />I am quite n ew to this Bluetooth technology. However I am in need of Bluetooth API's for Application level on Linux so that with those API's I should be able to call driver level functions.Can you suggest me something.<br /><br />Regards<br />Nisha<br /></div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com3tag:blogger.com,1999:blog-6052374310229468906.post-25988036257863798512009-03-10T05:24:00.001-07:002009-03-10T05:24:42.702-07:00How to be a program managerHow to be a program manager <div class="author">by Joel Spolsky</div> <div class="date">Monday, March 09, 2009</div> <p>Having a good program manager is one of the secret formulas to making really great software. And you probably don’t have one on your team, because most teams don’t.</p> <p>Charles Simonyi, the brilliant programmer who co-invented WYSIWYG word processing, dated Martha Stewart, made a billion dollars off of Microsoft stock and went into space, first tried to solve the <a href="http://www.amazon.com/gp/product/0201835959?ie=UTF8&tag=joelonsoftware&linkCode=as2&camp=1789&creative=390957&creativeASIN=0201835959">Mythical Man Month</a> problem of organizing really big software teams by creating one super duper überprogrammer writing the top-level functions, while handing off the implementation of the lower-level functions to a team of grunt junior-programmers as needed. They called this position <em>program manager. </em>Simonyi is brilliant, but this idea, not so much. Nobody wanted to be a grunt junior programmer, I guess. </p> <blockquote class="textmessage">For more on the history, read William Poundstone’s <a href="http://www.amazon.com/gp/product/0316778494?ie=UTF8&tag=joelonsoftware&linkCode=as2&camp=1789&creative=9325&creativeASIN=0316778494">How Would You Move Mount Fuji?</a></blockquote> <p>Jabe Blumenthal, a programmer on the Mac Excel team in the late 80s, recycled the title for a different job. He had noticed that software development was getting so complicated that none of the programmers had the time to figure out how to make software that was either usable or useful. The marketing team was ranting and raving about customer needs and nobody had time to talk to them or translate their MBA-speak into actual features. There was a lot of product design stuff that took a lot of work: talking to users, running usability tests, reviewing competitive products, and thinking hard about how to make things easier, and most programmers just didn’t have the time (nor were they particularly good at it). Blumenthal took the title “Program Manager,” but reinvented the job completely.</p> <h3>What does a program manager do?</h3> <p>Henceforth, a program manager would:</p> <ol><li>Design UIs </li><li>Write functional specs</li><li>Coordinate teams</li><li>Serve as the customer advocate, and</li><li>Wear Banana Republic chinos</li></ol> <p>On small products, you might just have one program manager, but on larger products, you would probably have more than one. Each can be responsible for some subset of the features. A good rule of thumb is that it takes about one program manager for every four programmers. If you’re having trouble dividing up the work, one approach I learned from Mike Conte is to <a href="http://www.joelonsoftware.com/uibook/chapters/fog0000000065.html">divide up the product according to user activities</a>. For example, Twitter could be divided into four user activities:</p> <ol><li>Registering and getting started</li><li>Posting messages and reading replies</li><li>Configuring your account</li><li>Searching for news</li></ol> <p><span class="side"><a href="http://www.joelonsoftware.com/items/2009/03/09Meeting.jpg"><img class="sideimg" alt="" src="http://www.joelonsoftware.com/items/2009/03/09Meeting-thumbnail.jpg" /></a><br /><span class="caption">Tyler Griffin Hicks-Wright</span></span>My first program management assignment at Microsoft was on Excel, working on the user activity called “customization,” i.e., scripting and macros. The first thing I had to do was figure out what customers needed, which I did by talking to as many customers as I could until I started to get kind of bored because I kept hearing the same thing. I spent a lot of time talking to the development team to figure out what would be possible and reasonable to implement in a single 18 month release, and I spent a lot of time talking to the Visual Basic team to see if they could supply a compiler, code editor, and dialog box editor that could be used in Excel for our macro language. I also had to talk to Apple, which was developing their own universal macro language called AppleScript, and the other application teams at Microsoft, mainly Word, Access, Project, and Mail, who generally did whatever Excel did. Most of this process consisted of talking. Meetings, email, phone calls. I am scarred for life from this, and now cower in my office in fear that the phone will ring.</p> <p>The second step was writing a vision statement: sort of a broad document that said, this is how Visual Basic would work in Excel, this is what some sample macros would look like, these are the major pieces we would need to build, and this is how it would solve customers’ problems. When that didn’t generate too many objections, I started working on a much more detailed spec, which explained, down to the smallest detail, how everything looked to the user.</p> <p>This was a functional spec, not a technical spec, which means, all it talked about was what the user saw, not how it was implemented. (<a href="http://www.joelonsoftware.com/articles/fog0000000036.html">Read all about functional specs here</a>.) A program manager doesn’t care how the development team implements things internally. As I sent chapters of the spec to Ben Waldman, the development lead, he and his team sat down and figured out what they had to do internally to make it work. They came up with a rather brilliant and very compact table that mapped the object-oriented interface I was defining onto internal Excel functions, but that really wasn’t my business. I didn’t know too much about Excel internals and didn’t really know how things should be implemented.</p> <p>Truth be told, I didn’t know anything about anything. Fresh out of college, I didn’t have enough experience to develop the code, test the code, write the documentation, market the product, or do the usability tests. Luckily, Microsoft had seriously experienced gurus in each of those positions, who taught me everything I know today, and who did the real work of producing an awesome product. For example, I knew that users would want to copy the value of a spreadsheet cell into a variable:</p> <pre>x = [A1]<br /></pre> <p>had to work. The trouble was that a cell could hold a number or a string, but Basic was early bound… you had to DIM x as an Integer, Float or String before you could use it.</p> <p>Basic had to get some kind of dynamic types, but I wasn’t smart enough to figure out how to do that. Didn’t matter. Tom Corbett, a programmer on the Visual Basic team, <a href="http://www.patentstorm.us/patents/5689709/description.html">figured out how</a>. And thus Variants and IDispatch were born, and Basic became a dynamic language with what you kids now call “duck typing”. The point being, my job wasn’t necessarily to solve problems, it was to figure out what customers needed and make sure that programmers figured out how to solve them.</p> <p>Once the spec was finished and the development team got down to work, I had two responsibilities: resolving any questions that came up about the design, and talking to all the other teams so that the developers didn’t have to. I met with the testers explaining how things were supposed to work and helping them plan how to test everything. I met with the documentation team, making sure they understood how to write a good tutorial and reference for Excel Basic. I met with localization experts to figure out a localization strategy. I sat down with marketing to explain the marketing benefits of VBA. I worked with usability experts to set up usability tests.</p> <p>A program manager does go to a lot of meetings, but doesn’t produce much other than that written spec, which is why as a twerp fresh out of school I was still able to do the job. You don’t have to be a 14-year veteran programmer to work as a program manager (in fact, with 14 years of programming experience, you might know too much to be a good user advocate.)</p> <h3>Conflict</h3> <p><span class="side"><a href="http://www.ok-cancel.com/comic/4.html"><img class="sideimg" alt="" src="http://www.joelonsoftware.com/items/2009/03/09DevUI-thumbnail.png" /></a><br /><span class="caption"><a href="http://www.ok-cancel.com/comic/4.html">Tom Chi and Kevin Cheng</a></span></span>Lacking a program manager, your garden-variety super-smart programmer is going to come up with a completely baffling user interface that makes perfect sense IF YOU’RE A VULCAN (cf. git). The best programmers are notoriously brilliant, and have some trouble imagining what it must be like not to be able to memorize 16 one-letter command line arguments. These programmers then have a tendency to get attached to their first ideas, especially when they’ve already written the code.</p> <p>One of the best things a program manager can add to the software design process is a second opinion as to how things should be designed, hopefully one that is more empathetic to those RETARDED USERS with their pesky mental feebleness requiring that an application be usable without reading the man page, writing a custom emacs-lisp function, or translating numbers into octal in your head.</p> <p>A good program manager will come with her own ideas for how the UI should work, which might be better, or worse, than the developer’s idea. And then there’s a long debate. Typically, the program manager wants something simple and easy to understand for the users, featuring a telepathic user interface and a 30" screen that nonetheless fits in your pocket, while the developer wants something that is trivial to implement in code, with a command-line interface (“what’s so unusable about that?”) and Python bindings.</p> <p>One of the most monumental debates I remember from the Excel 5 project was between a developer who wanted pivot tables to float on the drawing layer above the spreadsheet, and the program manager, who insisted that pivot tables live right in the cells on the spreadsheet. This debate went on for a really, really long time, and eventually, the program manager prevailed, but the final design came out much much better than any one individual’s design would have been.</p> <p>To make sure that the debate happens respectfully and on a rational basis of facts, it’s absolutely critical that the program managers and developers be <em>peers</em>. If developers report to the program manager, at some point during the debate the program manager is going to get sick of the whole thing and just say, “OK, enough talking, now we do it my way.” When they’re peers, this can never happen. It’s a little bit like courts of law: we don’t allow a lawyer for one side to be the judge, and we work on the theory that the truth is most likely to be uncovered through a process of debate between equals. The debate can only be a fair one if neither side has an unfair advantage. </p> <p>This is an important point, so if you were daydreaming about Sally in 11th grade, wondering where she is now, snap out of it. She’s a biotherapist in Scottsdale, and a Republican. Now pay attention. Programmers <em>can’t report to program managers</em> which means, among other things, that the development lead, or the CTO, or the CEO, can’t be the person who writes the specs.</p> <p>The <em>number one mistake</em> most companies make is having the manager of the programmers writing the specs and designing the product. This is a mistake because the design does not get a fair trial, and is not born out of conflict and debate, so it’s not as good as it could be.</p> <p>I learned this the hard way. At Fog Creek Software, I did a lot of the program management myself, and it was a constant battle to remind people that they were supposed to argue with me when I said wrong things. We’re not a big company but we are finally big enough to have real program managers now, Dan and Jason, and the programmers <em>love</em> arguing with them.</p> <p>Of course, when programmers are peers of the program managers, the programmers tend to have the upper hand. Here’s something that has happened several times: a programmer asks me to intervene in some debate he is having with a program manager. </p> <p><span class="side"><a href="http://www.joelonsoftware.com/items/2009/03/09Tiara.JPG"><img class="sideimg" alt="" src="http://www.joelonsoftware.com/items/2009/03/09Tiara-thumbnail.JPG" /></a></span>“Who is going to write the code?” I asked.</p> <p>“I am…”</p> <p>“OK, who checks things into source control?”</p> <p>“Me, I guess, …”</p> <p>“So what’s the problem, exactly?” I asked. “You have absolute control over the state of each and every bit in the final product. What else do you need? A tiara?”</p> <p>You see, it turns out that this system puts the burden on the program manager to persuade the programmer, because at some point, the program manager runs the risk that the programmer will give up and just do whatever the heck the programmer feels like. Thus, being effective as a program manager means you have to (a) be right, and (b) earn the respect of the programmers so that they concede that you’re right.</p> <p>How do you earn this respect?</p> <p>It helps, as a program manager, to be pretty good at coding yourself. This is unfair. Program managers aren’t supposed to write code. But programmers tend to respect programmers a lot more than non-programmers, no matter how smart they are. It is possible to be an effective program manager without being a coder, but the burden of earning the respect of the programming team will be higher.</p> <blockquote class="textmessage"><span style="font-weight: bold;">flip the bozo bit </span><span style="font-style: italic;">v. </span>Decide that someone is a clown, and stop listening to them.</blockquote> <p>The other way to earn the programming team’s respect is to demonstrate intelligence, open-mindedness, and fairness in any debates that come up. If a program manager says dumb things, the programmer might flip the bozo bit on them. If a program manager becomes personally or emotionally attached to a certain way of doing things, to the point at which they’re being unreasonable, they’re going to lose a lot of credibility… both sides, but especially the program manager, need to be emotionally detached from the debate and willing to consider new evidence and change their opinions when the facts merit it. Finally, if a program manager is seen as playing politics, having private meetings with the boss or trying to divide-and-conquer to win a debate instead of debating on the merits, they’re going to lose a lot of trust of the programmers.</p> <p>And when a program manager loses the programming team’s trust, it’s over. They’re not going to be effective. The programmers are going to tune them out and do whatever they want anyway. This leads to worse code and wasted time, since not only are you paying an ineffective program manager a salary, but that ineffective program manager is calling meetings and soaking up everybody else’s time even though they’re not really making the code any better.</p> <h3>Specs? Really? That’s so <em>unagile</em></h3> <p><span class="side"><a href="http://www.joelonsoftware.com/items/2009/03/09InternDesk.png"><img class="sideimg" style="border: medium none ;" alt="" src="http://www.joelonsoftware.com/items/2009/03/09InternDesk-thumbnail.png" /></a></span>There are so many development organizations where specs are a monument to mindless bureaucratic paperwork that entire movements sprung up organized around the idea of not writing specs. These people are misguided. Writing a functional specification is at the very heart of agile development, because it lets you iterate rapidly over many possible designs before you write code. Compared to code, a written spec is trivial to change. The very act of writing a specification forces you to think through the design you thought you had in your head, and helps you see the flaws in it quickly so that you can iterate and try more designs. Teams that use functional specifications have better designed products, because they had the opportunity to explore more possible solutions quickly. They also write code faster, because they have a clearer picture when they start of what’s going to be needed. Functional specifications are so important one of the few hard and fast rules at Fog Creek is “No Code Without Spec.”</p> <p>The exact form the functional specification takes may vary. All a functional specification has to do is explain how the program will behave. It doesn’t say anything about how the code will work internally. You start at the highest level: a vision statement, no more than one page explaining the gist of the new feature. Once that’s nailed down, you can develop storyboards… mockups of the screens showing the user’s progression through the application, with detailed notes showing how they work. For many types of functionality, especially UI-heavy functionality, once you have these storyboards, you’re done. That’s your spec. <a href="http://www.37signals.com/svn/archives/001050.php">Jason Fried, you can go now</a>.</p> <blockquote class="textmessage">To learn how to write good functional specifications, read my <a href="http://www.joelonsoftware.com/articles/fog0000000036.html">four part series</a>. If you want to see a typical spec I wrote, you can download the full <a href="http://www.joelonsoftware.com/articles/AardvarkSpec.html">Fog Creek Copilot spec</a>.</blockquote> <p>For more complex functionality with hidden behavior that’s not expressed in the UI storyboards, you’re going to want more details written down. In any case, the very act of writing down a spec helps you discover problems, conflicts, and design issues long before the first line of code is written, so when you do write the code, you have far fewer unexpected issues popping up which might force a rewrite or, worse, a suboptimal design.</p> <h3>How do you learn to be a Program Manager?</h3> <p>Mostly, becoming a program manager is about learning: learning about technology, learning about people, and learning how to be effective in a political organization. A good program manager combines an engineer’s approach to designing technology with a politician’s ability to build consensus and bring people together. While you’re working on that, though, there are a few books you should read:</p> <p>As far as I can tell, Scott Berkun’s book <a href="http://www.amazon.com/gp/product/0596517718?ie=UTF8&tag=joelonsoftware&linkCode=as2&camp=1789&creative=390957&creativeASIN=0596517718">Making Things Happen</a> is the only book that’s been written that pretty much covers exactly what a program manager has to do, so start with that. Scott was a program manager on the Internet Explorer team for many years. </p> <p>Another big part of the program manager’s job is user interface design. Read Steve Krug’s <a href="http://www.amazon.com/gp/product/0321344758?ie=UTF8&tag=joelonsoftware&linkCode=as2&camp=1789&creative=390957&creativeASIN=0321344758">Don’t Make Me Think</a>, then my own book <a href="http://www.amazon.com/gp/product/1893115941?ie=UTF8&tag=joelonsoftware&linkCode=as2&camp=1789&creative=390957&creativeASIN=1893115941">User Interface Design for Programmers</a>.</p> <p>Finally, and I know it sounds cheesy, but Dale Carnegie’s 1937 book <a href="http://www.amazon.com/gp/product/0671027034?ie=UTF8&tag=joelonsoftware&linkCode=as2&camp=1789&creative=390957&creativeASIN=0671027034">How to Win Friends & Influence People</a> is actually a fantastic introduction to interpersonal skills. It’s the first book I make all the management trainees at Fog Creek read, before anything else, and they always snicker when I tell them to read it, and love it when they’re done.</p> <br /> <blockquote class="textmessage"> Work with me, here! Fog Creek Software has great <a href="http://www.fogcreek.com/Jobs/SummerIntern.html">paid internships</a> in software development for qualified college students. They’re in New York City. Free housing, lunch, and more. And you get to work on real, shipping software with the smartest developers in the business. </blockquote> <br /> <br /> <h4 class="microhead">Want to know more? </h4> <p>You’re reading <a href="http://www.joelonsoftware.com/">Joel on Software</a>, stuffed with years and years of completely raving mad articles about software development, managing software teams, designing user interfaces, running successful software companies, and rubber duckies. </p> <br /> <br /> <h4 class="microhead">About the author. </h4> <p>I’m <a href="http://www.joelonsoftware.com/AboutMe.html">Joel Spolsky</a>, founder of <a href="http://www.fogcreek.com/">Fog Creek Software</a>, a <span style="white-space: nowrap;">New York</span> company that proves that you can treat programmers well and still be highly profitable. Programmers get private offices, free lunch, and work 40 hours a week. Customers only pay for software if they’re delighted. We make <a href="http://www.fogcreek.com/FogBugz/">FogBugz</a>, an enlightened project management system designed to help great teams develop brilliant software, and <a href="https://www.copilot.com/">Fog Creek Copilot</a>, which makes remote desktop access easy. </p>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-79497872864670319242009-03-10T05:16:00.002-07:002009-03-10T05:17:12.342-07:00Install project has error "An error occurred while validating. HRESULT = '80040155'"http://social.msdn.microsoft.com/Forums/en-US/winformssetup/thread/a0fb1a0d-ecb8-47ba-8a69-e2af82f08516/<br /><br /><br />Hi, Eric<br /><br />Have you installed the software "InstallShield" on your PC and uninstalled it?<br /><br />You can check the link http://support.installshield.com/kb/view.asp?articleid=q106194 provided above and do as the instruction shows.<br /><br />For me, I just download the .REG file from http://support.installshield.com/kb/files/Q106194/Hotfix.zip and runs it to modify the registry file. Then the above problem is fixed.<br /><br />If you did not install the software, there may be some other causes. You can first make a backup of your registry and runs the modification. If the error still exists, it means your problem is different from mine, first restore your registry and see whether there is more information about your problem.<br /><br />Hope it useful!Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-17325463510329890592009-03-10T05:16:00.001-07:002009-03-10T05:16:50.716-07:00polymorphism in C#<h3><a href="http://maxotek.net/blog/csharp-tutorial-lesson-5-encapsulation-abstraction-t31.html" target="_blank"><em>Maxotek Blog</em> » <em>C# Tutorial</em></a></h3><p>
<br /></p><p>The term polymorphism means multiple forms. In the world of programming, it refers to the ability of an object to exist in multiple forms. Polymorphism is one one of the key concepts of Object Oriented Programming.</p> <h5>Why do we need polymorphism?</h5> <p>Polymorphism is there to increase the complexity of the already complex world of programming. Just kidding! By using functions, we break down the program into smaller logical parts that are easier to understand, implement and thereby maintain. In this sense, the function is the smallest self sufficient (ideally) logical block of a program. As you get to know more about the real world programming, you’ll find that even these small logical blocks are often very big and rather complex. Consider the following function which is used to calculate the area of a circle from the radius entered as integer.</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">double</span> CalcArea<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> Radius<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(255, 0, 0);">double</span> Area <span style="color: rgb(0, 128, 0);">=</span> Math.<span style="color: rgb(0, 0, 255);">PI</span> <span style="color: rgb(0, 128, 0);">*</span> Radius <span style="color: rgb(0, 128, 0);">*</span> Radius<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> Area<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>This function can only handle integers as input. What if the Radius was in double? The function would fail in such a case. We can create another function named <strong>CalcAreaDouble</strong> to handle the input in double.</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">double</span> CalcAreaDouble<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">double</span> Radius<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(255, 0, 0);">double</span> Area <span style="color: rgb(0, 128, 0);">=</span> Math.<span style="color: rgb(0, 0, 255);">PI</span> <span style="color: rgb(0, 128, 0);">*</span> Radius <span style="color: rgb(0, 128, 0);">*</span> Radius<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> Area<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>While, this works, there’s something wrong about this method. The name of a function should describe(in brief) what it does and not the type of values it returns or takes as input. Both these functions do the same job, Calculate Area. Hence, they should have the same name. Thanks to Polymorphism, we can declare two functions with the same name, inside the same class.</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">double</span> CalcArea<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> Radius<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(255, 0, 0);">double</span> Area <span style="color: rgb(0, 128, 0);">=</span> Math.<span style="color: rgb(0, 0, 255);">PI</span> <span style="color: rgb(0, 128, 0);">*</span> Radius <span style="color: rgb(0, 128, 0);">*</span> Radius<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> Area<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">double</span> CalcArea<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">double</span> Radius<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(255, 0, 0);">double</span> Area <span style="color: rgb(0, 128, 0);">=</span> Math.<span style="color: rgb(0, 0, 255);">PI</span> <span style="color: rgb(0, 128, 0);">*</span> Radius <span style="color: rgb(0, 128, 0);">*</span> Radius<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> Area<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>This is called <span>function overloading</span>. For two functions with the same name to co-exist, they must follow certain rules:-</p> <ul><li>The functions must differ in either the type, the sequence or the number of input parameters i.e they must have different function signatures. The CalcArea functions have different types of parameters. <p>These two functions differ in the number of parameters:-</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">int</span> SumOfNum<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> Num1, <span style="color: rgb(255, 0, 0);">int</span> Num2<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">return</span> Num1 <span style="color: rgb(0, 128, 0);">+</span> Num2<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br />
<br /><span style="color: rgb(255, 0, 0);">int</span> SumOfNum<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> Num1, <span style="color: rgb(255, 0, 0);">int</span> Num2, <span style="color: rgb(255, 0, 0);">int</span> Num3<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">return</span> Num1 <span style="color: rgb(0, 128, 0);">+</span> Num2 <span style="color: rgb(0, 128, 0);">+</span> Num3<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>While, these have different sequence:-</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">float</span> SumOfNum<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> Num1, <span style="color: rgb(255, 0, 0);">float</span> Num2<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">return</span> Num1 <span style="color: rgb(0, 128, 0);">+</span> Num2<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br />
<br /><span style="color: rgb(255, 0, 0);">float</span> SumOfNum<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">float</span> Num1, <span style="color: rgb(255, 0, 0);">int</span> Num2<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">return</span> Num1 <span style="color: rgb(0, 128, 0);">+</span> Num2<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre> </td></tr></tbody></table></div> </li><li>Return type has no influence on function overloading. Hence, these two functions cannot co-exist:- <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">double</span> CalcArea<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> Radius<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(255, 0, 0);">double</span> Area <span style="color: rgb(0, 128, 0);">=</span> Math.<span style="color: rgb(0, 0, 255);">PI</span> <span style="color: rgb(0, 128, 0);">*</span> Radius <span style="color: rgb(0, 128, 0);">*</span> Radius<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> Area<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">int</span> CalcArea<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> Radius<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(255, 0, 0);">double</span> Area <span style="color: rgb(0, 128, 0);">=</span> Math.<span style="color: rgb(0, 0, 255);">PI</span> <span style="color: rgb(0, 128, 0);">*</span> Radius <span style="color: rgb(0, 128, 0);">*</span> Radius<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> Area<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> </li></ul> <h5>Static Polymorphism</h5> <p>Function overloading along with operator overloading which we shall look at in the next tutorial are ways of implementing static polymorphism. Static polymorphism inturn, is one of the two types of Polymorphism, the other being Dynamic polymorphism. Also called as early binding, this concept refers to an entity existing in different forms. Just like a teacher who carries on the role of a father, a husband, a comrade besides being a teacher, the functions exist in different forms, each specializing in handling one type of role. In static polymorphism, the response to a function is decided at compile time and hence it is also called early binding.</p> <h5>Overloading Constructors</h5> <p>Since constructors are also functions and can be parameterized(takes parameters as input), they can be overloaded. This allows flexibility while creating an object. Consider the Rectangle class declared in the <strong>System.Drawing</strong> namespace. It can be instantiated by either of the two methods.</p> <p><b>Method 1: Using default constructor</b></p> <p>In this method, the bounds of the rectangle object <strong>Rect</strong> are individually set.</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br /></pre></td><td><pre>Rectangle Rect <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Rectangle<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />Rect.<span style="color: rgb(0, 0, 255);">X</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">10</span><span style="color: rgb(0, 128, 0);">;</span>
<br />Rect.<span style="color: rgb(0, 0, 255);">Y</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">20</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />Rect.<span style="color: rgb(0, 0, 255);">Width</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">30</span><span style="color: rgb(0, 128, 0);">;</span>
<br />Rect.<span style="color: rgb(0, 0, 255);">Height</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">40</span><span style="color: rgb(0, 128, 0);">;</span></pre> </td></tr></tbody></table></div> <p><b>Method 2: Using the Parametrized Constructor</b></p> <div><div><pre>Rectangle Rect <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Rectangle<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">10</span>, <span style="color: rgb(255, 0, 0);">20</span>, <span style="color: rgb(255, 0, 0);">30</span>, <span style="color: rgb(255, 0, 0);">40</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span></pre> </div></div> <p>Notice, how much easier this method is. The initialization in this case is handled by the constructor of the Rectangle class.</p> <p>The rectangle class would have an implementation similar to this one:-</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br />12
<br />13
<br />14
<br />15
<br />16
<br />17
<br />18
<br />19
<br />20
<br />21
<br />22
<br />23
<br /></pre></td><td> <pre><span style="color: rgb(255, 0, 0);">class</span> Rectangle
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> X<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> Y<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> Width<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> Height<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Rectangle<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">X</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">0</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">Y</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">0</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">Width</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">0</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">Height</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">0</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /> Rectangle<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> x, <span style="color: rgb(255, 0, 0);">int</span> y, <span style="color: rgb(255, 0, 0);">int</span> width, <span style="color: rgb(255, 0, 0);">int</span> height<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">X</span> <span style="color: rgb(0, 128, 0);">=</span> x<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">Y</span> <span style="color: rgb(0, 128, 0);">=</span> y<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">Width</span> <span style="color: rgb(0, 128, 0);">=</span> width<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">this</span>.<span style="color: rgb(0, 0, 255);">Height</span> <span style="color: rgb(0, 128, 0);">=</span> height<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>As you can see, the class has two overloaded constructors, one being the default constructor which takes no parameter and initializes the values of <strong>X</strong>, <strong>Y</strong>, <strong>Width</strong> and <strong>Height</strong> to 0. The other one initializes these values based on the inputs to it.</p> <p><i>Note: This code is just to give you an idea of how the constructors are implemented. In actual fact, the rectangle class would be a lot more complex than this and would require further codes inside the constructors.</i></p><p>
<br /></p><h5>Operator Overloading</h5> <p>By default, out of the various C# operators, only the dot operator can be applied to user-defined types. Consider the following code snippet:-</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br />12
<br />13
<br />14
<br />15
<br />16
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">class</span> Program
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car Car1 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car Car2 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />
<br /> Car Car3 <span style="color: rgb(0, 128, 0);">=</span> Car1 <span style="color: rgb(0, 128, 0);">+</span> Car2<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Car
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> Speed<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table> </div> <p>The compiler generates an error at line 8 saying that the operator + cannot be applied to objects of the <b>Car</b> class. How is the compiler supposed to know whether we want to add the speeds of two cars or concatenate their names. This is where the concept of Operator Overloading jumps in. Before we see how the + operator is prepared to work with the objects of the <b>Car</b> class, we need to understand how the concept works. Given below is a code snippet which accomplishes the addition in objects using a specialized method - <b>Add()</b>.</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br />12
<br />13
<br />14
<br />15
<br />16
<br />17
<br />18
<br />19
<br />20
<br />21
<br />22
<br />23
<br />24
<br />25
<br />26
<br />27
<br />
<br />28
<br />29
<br /></pre></td><td><pre><span style="color: rgb(6, 0, 255);">using</span> <span style="color: rgb(0, 128, 128);">System</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Program
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car Car1 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car Car2 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car1.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">30</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> Car2.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">70</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />
<br /> Car Car3 <span style="color: rgb(0, 128, 0);">=</span> Car.<span style="color: rgb(0, 0, 255);">Add</span><span style="color: rgb(0, 0, 0);">(</span>Car1, Car2<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Car3's Speed = {0}"</span>, Car3.<span style="color: rgb(0, 0, 255);">Speed</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Console.<span style="color: rgb(0, 0, 255);">Read</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Car
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> Speed<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> Car Add<span style="color: rgb(0, 0, 0);">(</span>Car Car1, Car Car2<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car NewCar <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> NewCar.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">=</span> Car1.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">+</span> Car2.<span style="color: rgb(0, 0, 255);">Speed</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> NewCar<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr> </tbody></table></div> <p>The <b>Add</b> method is declared as static so it can be invoked at the class level as <b>Car.Add()</b>. It takes two parameters of the type <b>Car</b> as inputs. It then creates a new object of the Car class, with a speed equal to the sum of the speeds of the input objects - <b>Car1</b> and <b>Car2</b>. Finally, the new object is returned. In this way, the addition of two objects can be accomplished. The same concept is used in Operator Overloading, except for the fact that the specialized function in their case are of the format <b>operator <operator></b>.</p> <p><i>Note: The logic inside the Add function is totally up to the the programmer.</i></p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br />12
<br />13
<br />14
<br />15
<br />16
<br />17
<br />18
<br />19
<br />20
<br />21
<br />22
<br />23
<br />24
<br />25
<br />26
<br />27
<br />
<br />28
<br />29
<br /></pre></td><td><pre><span style="color: rgb(6, 0, 255);">using</span> <span style="color: rgb(0, 128, 128);">System</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Program
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car Car1 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car Car2 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car1.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">30</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> Car2.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">70</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />
<br /> Car Car3 <span style="color: rgb(0, 128, 0);">=</span> Car1 <span style="color: rgb(0, 128, 0);">+</span> Car2<span style="color: rgb(0, 128, 0);">;</span>
<br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Car3's Speed = {0}"</span>, Car3.<span style="color: rgb(0, 0, 255);">Speed</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Console.<span style="color: rgb(0, 0, 255);">Read</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Car
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> Speed<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> Car <span style="color: rgb(6, 0, 255);">operator</span> <span style="color: rgb(0, 128, 0);">+</span><span style="color: rgb(0, 0, 0);">(</span>Car Car1, Car Car2<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car NewCar <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> NewCar.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">=</span> Car1.<span style="color: rgb(0, 0, 255);">Speed</span> <span style="color: rgb(0, 128, 0);">+</span> Car2.<span style="color: rgb(0, 0, 255);">Speed</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> NewCar<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr> </tbody></table></div> <p>As you can see, the + operator utilizes a function in the background to do its neat work. Although the concept in both the cases is same, using operators allows much greater ease. The code <b>Car Car3 = Car1 + Car2;</b> is much closer to the real world and its easier to type, isn’t it?</p> <p>Here’s a table showing which operators can/cannot be overloaded in C#.</p> <table> <tbody><tr> <th>Operators</th> <th>Description</th> </tr> <tr> <td>+ - ! ~ ++ –</td> <td>These being unary operators take one operand and can be overloaded.</td> </tr> <tr> <td>+ - * / %</td> <td>Binary arithmetic operators take two operands and can be overloaded.</td> </tr> <tr> <td>== != < > <= >=</td> <td>Comparison operators take two parameters and can also be overloaded.</td> </tr> <tr> <td>&& ||</td> <td>These need to be overloaded indirectly using the & and |</td> </tr> <tr> <td>+= -= *= /= %=</td> <td>Arithmetic assignment operators cannot be overloaded.</td> </tr> <tr> <td>= . ?: -> new is sizeof typeof</td> <td>These special operators cannot be overloaded.</td> </tr> </tbody></table> <p><i>Note: The overloading methods must be declared as <b>public</b> and <b>static</b>.</i></p> <h5>Overloading Prefix Unary Operators</h5> <p>Below is the logic to accomplish unary - operator overloading. This operator changes the sign of the relative speed and is used as: <b>-<object></b></p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br />12
<br />13
<br />14
<br />15
<br />16
<br />17
<br />18
<br />19
<br />20
<br />21
<br />22
<br />23
<br />24
<br /></pre></td><td> <pre><span style="color: rgb(6, 0, 255);">using</span> <span style="color: rgb(0, 128, 128);">System</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Program
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car Car1 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car1.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">30</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> Car Car2 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">-</span>Car1<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Car
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> RelativeSpeed<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> Car <span style="color: rgb(6, 0, 255);">operator</span> <span style="color: rgb(0, 128, 0);">-</span><span style="color: rgb(0, 0, 0);">(</span>Car CarObj<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car NewCar <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> NewCar.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">-</span>CarObj.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> NewCar<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr> </tbody></table></div> <p>Notice, that the overloaded function takes only a single parameter. If another parameter was specified, this function would overload the binary - operator. Structures being user-defined data types can also be overloaded in this fashion. The only difference is that structures being value types, can be implemented in an easier way.</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">struct</span> Car
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> RelativeSpeed<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> Car <span style="color: rgb(6, 0, 255);">operator</span> <span style="color: rgb(0, 128, 0);">-</span><span style="color: rgb(0, 0, 0);">(</span>Car CarObj<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> CarObj.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">-</span>CarObj.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> CarObj<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr> </tbody></table></div> <p>If the same implementation of the Operator - function was used in a class, both <strong>Car1</strong> and <strong>Car2</strong> would have the same RelativeSpeed of -30 after line 9. So, in the class implementation we have created a new object of the Car class.</p> <h5>Overloading Pre & Post Increment Operators</h5> <p>Unlike, C++, C# handles the Pre & Post Increment Operators by itself. Hence, we don’t need to overload them separately. Below is the implementation of the ++ operator in the <strong>Car</strong> structure.</p> <div><table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br />12
<br />13
<br />14
<br />15
<br />16
<br />17
<br />18
<br />19
<br />20
<br />21
<br />22
<br />23
<br />24
<br />25
<br />26
<br />27
<br />
<br /></pre></td><td><pre><span style="color: rgb(6, 0, 255);">using</span> <span style="color: rgb(0, 128, 128);">System</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Program
<br />
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car Car1 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car1.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">30</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> Car Car2 <span style="color: rgb(0, 128, 0);">=</span> Car1<span style="color: rgb(0, 128, 0);">++;</span>
<br />
<br /> Car Car3 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">++</span>Car1<span style="color: rgb(0, 128, 0);">;</span>
<br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Relative speed of Car1 = {0}, Car2 = {1} and Car3 = {2}"</span>
<br />
<br /> , Car1.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span>, Car2.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span>, Car3.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Console.<span style="color: rgb(0, 0, 255);">Read</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">struct</span> Car
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> RelativeSpeed<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> Car <span style="color: rgb(6, 0, 255);">operator</span> <span style="color: rgb(0, 128, 0);">++</span><span style="color: rgb(0, 0, 0);">(</span>Car CarObj<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> CarObj.<span style="color: rgb(0, 0, 255);">RelativeSpeed</span><span style="color: rgb(0, 128, 0);">++;;</span>
<br /> <span style="color: rgb(6, 0, 255);">return</span> CarObj<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>At line 9, the overloaded function for the object<strong> Car1</strong> is invoked. The operation being post increment, <strong>Car2</strong> gets assigned the current value of <strong>Car1</strong> which has a relative speed of 30. After this the <strong>RelativeSpeed</strong> is incremented by 1. So, <strong>Car1</strong> has a relative speed of 31 now. In the next line, pre increment results in the value of <strong>Car1</strong> to be incremented by 1 before the value is assigned to <strong>Car3</strong>. Car1’s <strong>RelativeSpeed</strong> is now equal to 32. This value gets copied in Car3. So, the output of the code is: Relative speed of Car1 = 32, Car2 = 30 and Car3 = 32.</p> <p>If the same logic was used in the <strong>Car</strong> Class’s overloaded function, the output would be: Relative speed of Car1 = 32, Car2 = 32 and Car3 = 32. Why does this happen? As mentioned before, the class is a reference type. Hence, when we say Car1 = Car2, it implies that <strong>Car1</strong> now points to the same object in the memory as does <strong>Car2</strong>. In structures, the same statement would be equivalent to Copy the value of <strong>Car2</strong> in <strong>Car1</strong>.</p> <h5>Arithmetic Assignment Operators</h5> <p>Recall that, the Arithmetic Assignment operators ( += -= *= /= %= ) cannot be overloaded. This is because <strong>A += B</strong> is equivalent to<strong> A = A + B</strong>, <strong>A -= B</strong> is equivalent to <strong>A = A - B</strong> and so on. Once, you overload the binary + operator, you can perform the <strong>+=</strong> operation on the objects of the class. Same is true for the rest of the Arithmetic operators.</p> <h5>Logical Operators</h5> <p>Overloading Logical Operators is a bit tricky. Firstly, to overload the && operator the function name should be <strong>operator &</strong> and for || operator it should be <strong>operator |</strong>. Secondly, before performing these boolean short-circuit operations, the <strong>true</strong> and <strong>false</strong> operators need to be defined.</p> <table><tbody><tr><td><pre>1
<br />2
<br />3
<br />4
<br />5
<br />6
<br />7
<br />8
<br />9
<br />10
<br />11
<br />12
<br />13
<br />14
<br />15
<br />16
<br />17
<br />18
<br />19
<br />20
<br />21
<br />22
<br />23
<br />24
<br />25
<br />26
<br />27
<br />28
<br />29
<br />30
<br />31
<br />
<br />32
<br />33
<br />34
<br />35
<br />36
<br />37
<br />38
<br /></pre></td><td><pre><span style="color: rgb(6, 0, 255);">using</span> <span style="color: rgb(0, 128, 128);">System</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Program
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car Car1 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car Car2 <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Car1.<span style="color: rgb(0, 0, 255);">Running</span> <span style="color: rgb(0, 128, 0);">=</span> true<span style="color: rgb(0, 128, 0);">;</span>
<br /> Car2.<span style="color: rgb(0, 0, 255);">Running</span> <span style="color: rgb(0, 128, 0);">=</span> false<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />
<br /> Car Car3 <span style="color: rgb(0, 128, 0);">=</span> Car1 <span style="color: rgb(0, 128, 0);">&&</span> Car2<span style="color: rgb(0, 128, 0);">;</span>
<br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span>Car3.<span style="color: rgb(0, 0, 255);">Running</span><span style="color: rgb(0, 0, 0);"><wbr>)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> Console.<span style="color: rgb(0, 0, 255);">Read</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /><span style="color: rgb(255, 0, 0);">class</span> Car
<br /><span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">bool</span> Running<span style="color: rgb(0, 128, 0);">;</span>
<br />
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> Car <span style="color: rgb(6, 0, 255);">operator</span> <span style="color: rgb(0, 128, 0);">&</span><span style="color: rgb(0, 0, 0);">(</span>Car Car1, Car Car2<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> Car NewCar <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> NewCar.<span style="color: rgb(0, 0, 255);">Running</span> <span style="color: rgb(0, 128, 0);">=</span> Car1.<span style="color: rgb(0, 0, 255);">Running</span> <span style="color: rgb(0, 128, 0);">&&</span> Car2.<span style="color: rgb(0, 0, 255);">Running</span><span style="color: rgb(0, 128, 0);">;</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">return</span> NewCar<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(255, 0, 0);">bool</span> <span style="color: rgb(6, 0, 255);">operator</span> <span style="color: rgb(6, 0, 255);">true</span><span style="color: rgb(0, 0, 0);">(</span>Car CarObj<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">return</span> true<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br />
<br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(255, 0, 0);">bool</span> <span style="color: rgb(6, 0, 255);">operator</span> <span style="color: rgb(6, 0, 255);">false</span><span style="color: rgb(0, 0, 0);">(</span>Car CarObj<span style="color: rgb(0, 0, 0);">)</span>
<br />
<br /> <span style="color: rgb(0, 0, 0);">{</span>
<br /> <span style="color: rgb(6, 0, 255);">return</span> false<span style="color: rgb(0, 128, 0);">;</span>
<br /> <span style="color: rgb(0, 0, 0);">}</span>
<br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-60145385493536504632009-03-10T05:14:00.000-07:002009-03-10T05:15:48.910-07:00Difference between Pre & Post Increment/Decrement<div id=":1oc" class="ii gt"><p><strong>Difference between Pre & Post Increment/Decrement</strong><br />Consider the following code snippet:-</p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">int</span> A <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">0</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><span style="color: rgb(255, 0, 0);">int</span> B <span style="color: rgb(0, 128, 0);">=</span> A<span style="color: rgb(0, 128, 0);">++;</span><br /><span style="color: rgb(255, 0, 0);">int</span> C <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">++</span>A<span style="color: rgb(0, 128, 0);">;</span></pre> </td></tr></tbody></table></div> <p>At the very first line, we have used the Arithmetic Assignment operator, <strong>=</strong> to assign the value of 0 to A. In the proceeding lines we have used both Pre & Post increment. At line 2 <strong>int B = A++;</strong> the operation being post increment, the value of A i.e 0 is assigned to B followed by the increment of A’s value. At line 3 <strong>int C = ++A;</strong> the current value of A, i.e. 1 is incremented by 1 following which the new value of A is assigned to C. Therefore, the value of A = 2, B = 0 and C = 2.</p> <h3><a href="http://maxotek.net/blog/csharp-tutorial-lesson-5-encapsulation-abstraction-t31.html" target="_blank"><em>Maxotek Blog</em> » <em>C# Tutorial</em></a></h3><p><br /></p><p>What will be the output of the following code?</p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">int</span> A <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">5</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><span style="color: rgb(255, 0, 0);">int</span> B <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 0, 0);">(</span>A<span style="color: rgb(0, 128, 0);">++</span><span style="color: rgb(0, 0, 0);">)</span> <span style="color: rgb(0, 128, 0);">+</span> <span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 128, 0);">--</span>A<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br />Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Value of B = {0}"</span>, B<span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span></pre> </td></tr></tbody></table></div> <p>At line, 1, A gets initialized to 5. The next line is a bit tricky. Here, The RHS should be evaluated like 5 + 4 because A++ is post increment and this operation should occur after the line of statement. But, this is not the case, instead it takes place in the same line but after the evaluation of the sub-expression (A++). Hence, the expression will be evaluated as 5 + 5 and the output will be 10.</p> </div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0tag:blogger.com,1999:blog-6052374310229468906.post-39462776569285134402009-03-10T05:13:00.000-07:002009-03-10T05:14:51.155-07:00multilevel inheritance in C#<p>One of the important aspects of the <a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=30#cOOP" target="_blank">Object Oriented Methodology</a> is relationship. <a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=30#cObject" target="_blank">Objects</a> do not exist as isolated entities, rather, they exhibit some kind of relationship with other objects. Some of the common relationships between the classes are listed below:-</p><h5>Instantiation Relationship</h5><p>This is the relationship that exists between a <a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=30#cClass" target="_blank">class</a> and its instance or object. Real world examples of such a relationship can be:-</p><ul><li>A Ferari is a Car </li><li>A Mobile Phone is a type of electronic device </li></ul><div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">class</span> Car<br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Model<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Company<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> SerialNumber<span style="color: rgb(0, 128, 0);">;</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span><br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /> Car MyCar <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span> <span style="color: rgb(0, 128, 128); font-style: italic;">// Instantiation Relationship between MyCar & Car</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div><h5>Composition Relationship</h5><p>Classes can be nested i.e a Class can contain another class. The relationship between two such classes is called composition relationship.</p><p><img title="Click to Enlarge" alt="Composition" src="http://csharp-tutorial-lesson-12-inheritance-t47_files/composition.png" /></p><p>The following code represents the Composition relationship that is depicted in the above diagram.</p><div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">class</span> Car<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">string</span> SerialNumber<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Model<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> Color<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">class</span> Engine<br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> Type<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Model<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(255, 0, 0);">class</span> Wheel<br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">int</span> Width<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> Manufacturer<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td> </tr></tbody></table></div><h5>Utilization Relationship</h5><p>The concept of OOP allows a class to make use of another class i.e delegate some portion of its work to another specialized class. The relationship between these two classes is termed as utilization. Ferari an object of the car class, is driven by Michael, an object of the driver class. These two entities have a utilization relationship between them.</p><p>The following code snippet demonstrates the utilization relationship between the <b>Sorter</b> and the <b>Swapper</b> class.</p><div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /><br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">class</span> Sorter<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Sort<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> A<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">for</span> <span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> I <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">0</span><span style="color: rgb(0, 128, 0);">;</span> I <span style="color: rgb(0, 128, 0);"><</span> A.<span style="color: rgb(0, 0, 255);">Length</span> <span style="color: rgb(0, 128, 0);">-</span> <span style="color: rgb(255, 0, 0);">1</span><span style="color: rgb(0, 128, 0);">;</span> I<span style="color: rgb(0, 128, 0);">++</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">for</span> <span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> J <span style="color: rgb(0, 128, 0);">=</span> I <span style="color: rgb(0, 128, 0);">+</span> <span style="color: rgb(255, 0, 0);">1</span><span style="color: rgb(0, 128, 0);">;</span> J <span style="color: rgb(0, 128, 0);"><</span> A.<span style="color: rgb(0, 0, 255);">Length</span><span style="color: rgb(0, 128, 0);">;</span> J<span style="color: rgb(0, 128, 0);">++</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">if</span> <span style="color: rgb(0, 0, 0);">(</span>A<span style="color: rgb(0, 0, 0);">[</span>I<span style="color: rgb(0, 0, 0);">]</span> <span style="color: rgb(0, 128, 0);">></span> A<span style="color: rgb(0, 0, 0);">[</span>J<span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Utilizes the Swapper Class to do the swapping</span><br /> Swapper.<span style="color: rgb(0, 0, 255);">Swap</span><span style="color: rgb(0, 0, 0);">(</span>A<span style="color: rgb(0, 0, 0);">[</span>I<span style="color: rgb(0, 0, 0);">]</span>, A<span style="color: rgb(0, 0, 0);">[</span>J<span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> Swapper<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Swap<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(6, 0, 255);">ref</span> <span style="color: rgb(255, 0, 0);">int</span> Num1, <span style="color: rgb(6, 0, 255);">ref</span> <span style="color: rgb(255, 0, 0);">int</span> Num2<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">int</span> Temp <span style="color: rgb(0, 128, 0);">=</span> Num1<span style="color: rgb(0, 128, 0);">;</span><br /> Num1 <span style="color: rgb(0, 128, 0);">=</span> Num2<span style="color: rgb(0, 128, 0);">;</span><br /><br /> Num2 <span style="color: rgb(0, 128, 0);">=</span> Temp<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr> </tbody></table></div><p>This example uses the bubble sort algorithm to sort an array of integers in the ascending order. While sorting, two elements of the list need to be swapped when they are not arranged ascendingly. The Sorter class employs the Swapper class for this job thus utilizing it. </p><h5>Inheritance</h5><p>Just as a child inherits qualities from his/her parents, a class can inherit data members and functions from another class. Consider the following class diagram:-</p><p><img title="Click to Enlarge" src="http://csharp-tutorial-lesson-12-inheritance-t47_files/inheritance01.png" /></p><p>The Mammals class is the base class as it inherits its attributes to other classes. Dogs, cats & Humans are its child classes. This hierarchy is derived from the common set of attributes that the classes share. Mammals, for example are warm blooded, vertebrates, possess external ears and have hair on their body. These characteristics also pertain to Dogs, Cats, Humans, Lions, Tigers and Leopards, thus making them mammals. In C#, a class can have multiple child classes but only 1 base class. Multiple inheritance which existed in languages such as C++ has been scrapped because they tend to cause more problems than they solve.</p><p>Some key terms related to Inheritance are listed below.</p><ul><li><b>Base(Super) Class</b> - The class that inherits its properties to other classes. </li><li><b>Child(Sub) Class</b> - The class that inherits its properties from other classes. </li><li><b>Multi-level Inheritance</b> - A class which inherits from another class, serves as the base class for a third class. In the preeceding diagram, Lions, Tigers & Leopards are derived from the Cats class which itself is derived from the Mammals class. This is called multi-level inheritance. </li><li><b>Generalization</b> - Classes that inherit from the same base class have certain common attributes which have been inherited from the common base class. This relationship is called Generalization. </li><li><b>Specialization</b> - It refers to the uncommon characteristics of a sub class, those that make it different from others. When we say that Human is a kind of Mammal, we imply that they have the common properties of Mammals along with some specialized characteristics that make them different from other Mammals - They walk on two legs. Specialization is the opposite of Generalization. </li></ul><h5>Implementing Inheritance</h5><p><br /></p><div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br /><br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></pre></td><td><pre><div class="im"><span style="color: rgb(6, 0, 255);">namespace</span> ConsoleApplication1<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(255, 0, 0);">class</span> Program<br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Cars MyFerari <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /></div><br /> MyFerari.<span style="color: rgb(0, 0, 255);">NumberOfWheels</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">4</span><span style="color: rgb(0, 128, 0);">;</span><br /> MyFerari.<span style="color: rgb(0, 0, 255);">Drive</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Vehicles<br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">private</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> NumberOfWheels<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">void</span> Drive<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Cars <span style="color: rgb(0, 128, 0);">:</span> Vehicles<br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div><p>In this example, the Cars class is a sub class which is derived from the Vehicles class. The Cars class inherits the data member NumberOfWheels and the member function - Drive() from the Vehicles class. So, the MyFerari object of the Car class has access to these members.</p><p><i>Note: Private members are not accessible from the sub class. So, the follwoing code would cause a <b>‘<a href="http://consoleapplication1.vehicles.name/" target="_blank">ConsoleApplication1.Vehicles.<wbr>Name</a>’ is inaccessible due to its protection level.</b> error.</i></p><div><div><pre>MyFerari.<span style="color: rgb(0, 0, 255);">Name</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(102, 102, 102);">"Ferari"</span><span style="color: rgb(0, 128, 0);">;</span></pre> </div></div><h5>Determining Inheritance Hierarchies</h5><p>This process is very simple as the only thing one needs to remember is that the sub class should be a type of the base class. For example: Human is a type of Mammal, Car is a type of vehicle and so on.</p><p><i>Note: Improper usage of Inheritance will not result in any syntactical error. But, the design model for the program would be at fault.</i></p><div class="im"><h5>Constructor Inovking Order</h5><p><a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=39#cConstructor" target="_blank">Constructors</a> being unique to a class are not inherited. Whenever an object of a child class is created, the constructor of both the parent and the child class is invoked. The parent class must come into existence before its child class can. Therefore, the constructor of the base class is invoked first followed by the constructor of the derived class. The destructors are invoked in the opposite order - derived to base. This is because the child class must be destroyed before the parent class.</p><p>The following program confirms these two order.</p></div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br /><br />26<br />27<br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br /></pre></td><td><pre><span style="color: rgb(6, 0, 255);">using</span> <span style="color: rgb(0, 128, 128);">System</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><br /><span style="color: rgb(6, 0, 255);">namespace</span> ConsoleApplication1<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">class</span> Program<br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Cars MyFerari <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> Console.<span style="color: rgb(0, 0, 255);">ReadLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Vehicles<br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> Vehicles<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Vehicles -> Constructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> ~Vehicles<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Vehicles -> Destructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Cars <span style="color: rgb(0, 128, 0);">:</span> Vehicles<br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Cars -> Constructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> ~Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Cars -> Destructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}<br /><br /></span></pre><div id=":1mz" class="ii gt"><h5>Abstract Class</h5> <p>Consider the term Vehicle. It does not have an existence of its own. However, types of vehicles; namely, Car, Aeroplane, Bus, etc do. Similarly, we can have Abstract classes which cannot be instantiated thus exhibiting the abstract behavior. They merely contain the skeleton of the class but not its implementation. The abstract <b>keyword</b> is used to declare such a class.</p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></pre></td><td><pre>abstract <span style="color: rgb(255, 0, 0);">class</span> Vehicle<div class="im"><br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span><br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /></div> <span style="color: rgb(0, 128, 128); font-style: italic;">// Abstract Class cannot be instantiated</span><br /> Vehicle obj <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Vehicle<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span> <span style="color: rgb(0, 128, 128); font-style: italic;">// Shows Compilation Error.</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div><div><div><span id="q_11febf8490358d84_5" class="h4">- Show quoted text -</span></div><div class="h5"> <p>One of the important aspects of the <a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=30#cOOP" target="_blank">Object Oriented Methodology</a> is relationship. <a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=30#cObject" target="_blank">Objects</a> do not exist as isolated entities, rather, they exhibit some kind of relationship with other objects. Some of the common relationships between the classes are listed below:-</p> <h5>Instantiation Relationship</h5> <p>This is the relationship that exists between a <a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=30#cClass" target="_blank">class</a> and its instance or object. Real world examples of such a relationship can be:-</p> <ul><li>A Ferari is a Car</li><li>A Mobile Phone is a type of electronic device</li></ul> <div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">class</span> Car<br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Model<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Company<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> SerialNumber<span style="color: rgb(0, 128, 0);">;</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span><br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /> Car MyCar <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Car<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span> <span style="color: rgb(0, 128, 128); font-style: italic;">// Instantiation Relationship between MyCar & Car</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <h5>Composition Relationship</h5> <p>Classes can be nested i.e a Class can contain another class. The relationship between two such classes is called composition relationship.</p> <p><img src="http://maxotek.net/blog/images/tutorials/csharp/lesson12/composition.png" alt="Composition" title="Click to Enlarge" /></p> <p>The following code represents the Composition relationship that is depicted in the above diagram.</p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">class</span> Car<br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">string</span> SerialNumber<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Model<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> Color<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">class</span> Engine<br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> Type<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(255, 0, 0);">string</span> Model<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(255, 0, 0);">class</span> Wheel<br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">int</span> Width<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(255, 0, 0);">string</span> Manufacturer<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td> </tr></tbody></table></div> <h5>Utilization Relationship</h5> <p>The concept of OOP allows a class to make use of another class i.e delegate some portion of its work to another specialized class. The relationship between these two classes is termed as utilization. Ferari an object of the car class, is driven by Michael, an object of the driver class. These two entities have a utilization relationship between them.</p> <p>The following code snippet demonstrates the utilization relationship between the <b>Sorter</b> and the <b>Swapper</b> class.</p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /><br /></pre></td><td><pre><span style="color: rgb(255, 0, 0);">class</span> Sorter<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Sort<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> A<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">for</span> <span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> I <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">0</span><span style="color: rgb(0, 128, 0);">;</span> I <span style="color: rgb(0, 128, 0);"><</span> A.<span style="color: rgb(0, 0, 255);">Length</span> <span style="color: rgb(0, 128, 0);">-</span> <span style="color: rgb(255, 0, 0);">1</span><span style="color: rgb(0, 128, 0);">;</span> I<span style="color: rgb(0, 128, 0);">++</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">for</span> <span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">int</span> J <span style="color: rgb(0, 128, 0);">=</span> I <span style="color: rgb(0, 128, 0);">+</span> <span style="color: rgb(255, 0, 0);">1</span><span style="color: rgb(0, 128, 0);">;</span> J <span style="color: rgb(0, 128, 0);"><</span> A.<span style="color: rgb(0, 0, 255);">Length</span><span style="color: rgb(0, 128, 0);">;</span> J<span style="color: rgb(0, 128, 0);">++</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">if</span> <span style="color: rgb(0, 0, 0);">(</span>A<span style="color: rgb(0, 0, 0);">[</span>I<span style="color: rgb(0, 0, 0);">]</span> <span style="color: rgb(0, 128, 0);">></span> A<span style="color: rgb(0, 0, 0);">[</span>J<span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Utilizes the Swapper Class to do the swapping</span><br /> Swapper.<span style="color: rgb(0, 0, 255);">Swap</span><span style="color: rgb(0, 0, 0);">(</span>A<span style="color: rgb(0, 0, 0);">[</span>I<span style="color: rgb(0, 0, 0);">]</span>, A<span style="color: rgb(0, 0, 0);">[</span>J<span style="color: rgb(0, 0, 0);">]</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> Swapper<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Swap<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(6, 0, 255);">ref</span> <span style="color: rgb(255, 0, 0);">int</span> Num1, <span style="color: rgb(6, 0, 255);">ref</span> <span style="color: rgb(255, 0, 0);">int</span> Num2<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">int</span> Temp <span style="color: rgb(0, 128, 0);">=</span> Num1<span style="color: rgb(0, 128, 0);">;</span><br /> Num1 <span style="color: rgb(0, 128, 0);">=</span> Num2<span style="color: rgb(0, 128, 0);">;</span><br /><br /> Num2 <span style="color: rgb(0, 128, 0);">=</span> Temp<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr> </tbody></table></div> <p>This example uses the bubble sort algorithm to sort an array of integers in the ascending order. While sorting, two elements of the list need to be swapped when they are not arranged ascendingly. The Sorter class employs the Swapper class for this job thus utilizing it. </p> <h5>Inheritance</h5> <p>Just as a child inherits qualities from his/her parents, a class can inherit data members and functions from another class. Consider the following class diagram:-</p> <p><img src="http://maxotek.net/blog/images/tutorials/csharp/lesson12/inheritance01.png" title="Click to Enlarge" /></p> <p>The Mammals class is the base class as it inherits its attributes to other classes. Dogs, cats & Humans are its child classes. This hierarchy is derived from the common set of attributes that the classes share. Mammals, for example are warm blooded, vertebrates, possess external ears and have hair on their body. These characteristics also pertain to Dogs, Cats, Humans, Lions, Tigers and Leopards, thus making them mammals. In C#, a class can have multiple child classes but only 1 base class. Multiple inheritance which existed in languages such as C++ has been scrapped because they tend to cause more problems than they solve.</p> <p>Some key terms related to Inheritance are listed below.</p> <ul><li> <b>Base(Super) Class</b> - The class that inherits its properties to other classes.</li><li> <b>Child(Sub) Class</b> - The class that inherits its properties from other classes.</li><li> <b>Multi-level Inheritance</b> - A class which inherits from another class, serves as the base class for a third class. In the preeceding diagram, Lions, Tigers & Leopards are derived from the Cats class which itself is derived from the Mammals class. This is called multi-level inheritance.</li><li> <b>Generalization</b> - Classes that inherit from the same base class have certain common attributes which have been inherited from the common base class. This relationship is called Generalization.</li><li> <b>Specialization</b> - It refers to the uncommon characteristics of a sub class, those that make it different from others. When we say that Human is a kind of Mammal, we imply that they have the common properties of Mammals along with some specialized characteristics that make them different from other Mammals - They walk on two legs. Specialization is the opposite of Generalization.</li></ul> <h5>Implementing Inheritance</h5> <p><br /></p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br /></pre> </td><td><pre><span style="color: rgb(6, 0, 255);">namespace</span> ConsoleApplication1<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">class</span> Program<br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Cars MyFerari <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> MyFerari.<span style="color: rgb(0, 0, 255);">NumberOfWheels</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(255, 0, 0);">4</span><span style="color: rgb(0, 128, 0);">;</span><br /> MyFerari.<span style="color: rgb(0, 0, 255);">Drive</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Vehicles<br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">private</span> <span style="color: rgb(255, 0, 0);">string</span> Name<span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">int</span> NumberOfWheels<span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">void</span> Drive<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Cars <span style="color: rgb(0, 128, 0);">:</span> Vehicles<br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>In this example, the Cars class is a sub class which is derived from the Vehicles class. The Cars class inherits the data member NumberOfWheels and the member function - Drive() from the Vehicles class. So, the MyFerari object of the Car class has access to these members.</p> <p><i>Note: Private members are not accessible from the sub class. So, the follwoing code would cause a <b>‘<a href="http://consoleapplication1.vehicles.name/" target="_blank">ConsoleApplication1.Vehicles.<wbr>Name</a>’ is inaccessible due to its protection level.</b> error.</i></p> <div><div><pre>MyFerari.<span style="color: rgb(0, 0, 255);">Name</span> <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(102, 102, 102);">"Ferari"</span><span style="color: rgb(0, 128, 0);">;</span></pre> </div></div> <h5>Determining Inheritance Hierarchies</h5> <p>This process is very simple as the only thing one needs to remember is that the sub class should be a type of the base class. For example: Human is a type of Mammal, Car is a type of vehicle and so on.</p> <p><i>Note: Improper usage of Inheritance will not result in any syntactical error. But, the design model for the program would be at fault.</i></p> <h5>Constructor Inovking Order</h5> <p><a href="http://maxotek.net/blog/csharp-tutorial-lesson-12-inheritance-t47.html?p=39#cConstructor" target="_blank">Constructors</a> being unique to a class are not inherited. Whenever an object of a child class is created, the constructor of both the parent and the child class is invoked. The parent class must come into existence before its child class can. Therefore, the constructor of the base class is invoked first followed by the constructor of the derived class. The destructors are invoked in the opposite order - derived to base. This is because the child class must be destroyed before the parent class.</p> <p>The following program confirms these two order.</p> <table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br />28<br />29<br />30<br />31<br /><br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br /></pre></td><td><pre><span style="color: rgb(6, 0, 255);">using</span> <span style="color: rgb(0, 128, 128);">System</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><br /><span style="color: rgb(6, 0, 255);">namespace</span> ConsoleApplication1<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(255, 0, 0);">class</span> Program<br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(6, 0, 255);">static</span> <span style="color: rgb(6, 0, 255);">void</span> Main<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(255, 0, 0);">string</span><span style="color: rgb(0, 0, 0);">[</span><span style="color: rgb(0, 0, 0);">]</span> args<span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Cars MyFerari <span style="color: rgb(0, 128, 0);">=</span> <span style="color: rgb(0, 128, 0);">new</span> Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> Console.<span style="color: rgb(0, 0, 255);">ReadLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Vehicles<br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> Vehicles<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Vehicles -> Constructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> ~Vehicles<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Vehicles -> Destructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(255, 0, 0);">class</span> Cars <span style="color: rgb(0, 128, 0);">:</span> Vehicles<br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Cars -> Constructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> ~Cars<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Cars -> Destructor Invoked"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table><h5><br /></h5><h5><br /></h5></div></div><h5>Abstract Methods</h5> <p>Abstract methods contain the function signature and return type, but no body. A child class can override the abstract method thus providing its implementation. Abstract methods are also declared by using the <b>abstract</b> keyword.</p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br /></pre></td><td><pre>abstract <span style="color: rgb(255, 0, 0);">class</span> Vehicle<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> abstract <span style="color: rgb(6, 0, 255);">void</span> Run<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> Car <span style="color: rgb(0, 128, 0);">:</span> Vehicle<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">override</span> <span style="color: rgb(6, 0, 255);">void</span> Run<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Run the Car"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> Bus <span style="color: rgb(0, 128, 0);">:</span> Vehicle<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">override</span> <span style="color: rgb(6, 0, 255);">void</span> Run<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Run the Bus"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>In this example, the abstract method Run() is declared in the Vehicle class. Notice the lack of the { } braces which marks the lack of a body. Since the Vehicle class cannot be instantiated, it does not need to have an implementation for the Run() method. The actual implementation is contained in its derived classes - Car, Bus. Thus, the abstract class only forms the skeleton of the child classes which exhibit specialization by overriding and implementing the abstract methods.</p> <p><i>Note: Abstract methods can only be defined inside an abstract class.</i></p> <h5>Overriding Methods</h5> <p>In the previous example the <b>override</b> keyword is used. A parent class method can be overridden by a child class. In this way it provides its own implementation shadowing the one of the base class. A method must be declared as <b>abstract</b> or <b>virtual</b> to be overridden inside the child class.</p> <h5>Virtual Functions</h5> <p>The difference between a virtual function/method and an abstract method is that while the latter does not provide an implementation, the former does. If a virtual function of the parent class is not overridden, the method is inherited as it is, inside the child class. Again, we use the <b>virtual</b> keyword for declaring virtual functions.</p> <p>The following example shows various cases when a method can/cannot be overridden.</p> <div><table><tbody><tr><td><pre><div><div><span id="q_11febf8490358d84_9" class="h4">- Show quoted text -</span></div><div class="h5">1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /><br />28<br />29<br />30<br />31<br />32<br />33<br />34<br />35<br />36<br />37<br />38<br />39<br /></div></div>40<br />41<br />42<br />43<br />44<br />45<br />46<br />47<br />48<br />49<br /></pre></td><td><pre>abstract <span style="color: rgb(255, 0, 0);">class</span> Vehicle<br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Abstract Method. Contains no body.</span><br /> <span style="color: rgb(6, 0, 255);">public</span> abstract <span style="color: rgb(6, 0, 255);">void</span> Run<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> Car <span style="color: rgb(0, 128, 0);">:</span> Vehicle<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Abstract method is overridden.</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">override</span> <span style="color: rgb(6, 0, 255);">void</span> Run<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Run the Car"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Normal Method. Cannot be overridden.</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">void</span> Brake<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Stop the Car"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Virtual Method. Can be overridden.</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">virtual</span> <span style="color: rgb(6, 0, 255);">void</span> Accelerate<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Step on the gas"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> BMW <span style="color: rgb(0, 128, 0);">:</span> Car<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// An overridden method can be further overridden.</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">override</span> <span style="color: rgb(6, 0, 255);">void</span> Run<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Run the BMW"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Shows Compilation Error.</span><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// The Brake method of Car is</span><br /><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// not declared as virtual or abstract.</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">override</span> <span style="color: rgb(6, 0, 255);">void</span> Brake<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Stop the Car"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><br /> <span style="color: rgb(0, 128, 128); font-style: italic;">// Virtual method is overridden.</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">override</span> <span style="color: rgb(6, 0, 255);">void</span> Accelerate<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> Console.<span style="color: rgb(0, 0, 255);">WriteLine</span><span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(102, 102, 102);">"Step on the gas"</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>From the following you can deduce that for a method to be overridden, it must be declared as <b>abstract</b> or <b>virtual</b>. An overridden method can be further overridden because it carries over the virtual modifier.</p> <h5>Sealed Classes</h5> <p>So many ways to modify a class but none to protect? Fear not, <b>sealed</b> classes are here to the rescue. This modifier prevents a class from being tampered by not allowing other classes to inherit from it.</p> <div><table><tbody><tr><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br /></pre></td><td><pre><span style="color: rgb(6, 0, 255);">sealed</span> <span style="color: rgb(255, 0, 0);">class</span> Ferari<br /><br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(0, 128, 128); font-style: italic;">// Shows Error. Cannot inherit from sealed class.</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> McLaren <span style="color: rgb(0, 128, 0);">:</span> Ferari<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr> </tbody></table></div> <h5>Sealed Methods</h5> <p>Use the sealed modifier to prevent a method from being overridden. Normally, you do not need to use this modifier as the methods are not overridable by default. However, if you want to protect an overridden method from being further overridden, you should use the sealed method instead of sealing off the entire class.</p> <h5>Interfaces</h5> <p>Remember that C# does not support multiple inheritance? Multiple inheritance tends to cause more problems than it solves. However, the ability to derive methods and properties from multiple sources is present in C#. This is done using Interfaces. Interfaces only contain the declaration part of a class. The actual definition which comprises of the body of the method is present inside the class which implements the interface.</p> <h5>Declaring Interfaces</h5> <p>They are declared similar to how classes are. Only differences are that they can only contain methods and properties (no variables), they do not contain the definition for these methods/properties and off-course the interface keyword.</p> <div><div><pre><span style="color: rgb(255, 0, 0);">interface</span> Flyer<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">void</span> Fly<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></div></div> <h5>Implementing Interfaces</h5> <p>Classes do not inherit from interfaces, rather implement them. Although, the process of doing this is the same.</p> <div><div><pre><span style="color: rgb(255, 0, 0);">class</span> Aeroplane <span style="color: rgb(0, 128, 0);">:</span> Flyer<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></div></div> <p>Multiple interfaces can be implemented as follows:-</p> <div><div><pre><span style="color: rgb(255, 0, 0);">class</span> Aeroplane <span style="color: rgb(0, 128, 0);">:</span> Flyer, Vehicle<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></div></div> <p><i>Here, Vehicle is also assumed to be an interface.</i></p> <p>A class can inherit from another class and implement an interface in a similar fashion:-</p> <div><div><pre><span style="color: rgb(255, 0, 0);">class</span> Bird <span style="color: rgb(0, 128, 0);">:</span> Mammal, Flyer<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></div></div> <p><i>Note: Mammal is a class here.</i></p> <h5>Inheriting Interfaces</h5> <p>Interfaces themselves can inherit from other interfaces. Again, the process is the same.</p> <div><div><pre><span style="color: rgb(255, 0, 0);">interface</span> MechanicalFlyer <span style="color: rgb(0, 128, 0);">:</span> Flyer<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></div></div> <h5>Why use interfaces?</h5> <p>Interfaces provide the skeletal structure of the classes which implement them. They separate the definition of objects from their implementation.</p> <h5>Why not just use Abstract classes?</h5> <p>Abstract classes are meant to be used when you want only some of the methods/properties to be implemented by the sub class. Besides, a class cannot inherit from multiple classes but it can implement multiple interfaces.</p> <p>The following example depicts the need for interfaces.</p> <p><img src="http://maxotek.net/blog/images/tutorials/csharp/lesson13/interfaces.png" title="Click to Enlarge" /></p> <div><table><tbody><tr><div><div><span id="q_11febf8490358d84_13" class="h4">- Show quoted text -</span></div></div><td><pre>1<br />2<br />3<br />4<br />5<br />6<br />7<br />8<br />9<br />10<br />11<br />12<br />13<br />14<br />15<br />16<br />17<br />18<br />19<br />20<br />21<br />22<br />23<br />24<br />25<br />26<br />27<br /><br />28<br /></pre></td><td><pre>abstract <span style="color: rgb(255, 0, 0);">class</span> Animal<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">void</span> Eat<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /><br /> <span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br />abstract <span style="color: rgb(255, 0, 0);">class</span> Vehicle<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">void</span> Run<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><br /> <span style="color: rgb(0, 0, 0);">{</span><br /><br /> <span style="color: rgb(0, 0, 0);">}</span><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">interface</span> Flyer<br /><span style="color: rgb(0, 0, 0);">{</span><br /> <span style="color: rgb(6, 0, 255);">public</span> <span style="color: rgb(6, 0, 255);">void</span> Fly<span style="color: rgb(0, 0, 0);">(</span><span style="color: rgb(0, 0, 0);">)</span><span style="color: rgb(0, 128, 0);">;</span><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> Aeroplane <span style="color: rgb(0, 128, 0);">:</span> Vehicle, Flyer<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><br /><span style="color: rgb(0, 0, 0);">}</span><br /><br /><span style="color: rgb(255, 0, 0);">class</span> Bird <span style="color: rgb(0, 128, 0);">:</span> Animal, Flyer<br /><span style="color: rgb(0, 0, 0);">{</span><br /><br /><br /><span style="color: rgb(0, 0, 0);">}</span></pre></td></tr></tbody></table></div> <p>As you can see, the two sub classes Bird and Aeroplane derive from the Animal and Vehicle classes respectively. Both have the characteristics of their respective base classes. The Bird like any other animal, eats while the Aeroplane being a vehicle, runs. However, they both share a common trait - the ability to fly. This ability is neither possessed by all animals nor by all vehicles. So it cannot be defined in either of the base classes. Again, it is not only possessed by the Aeroplane and Bird, some insects, baloons and other types of vehicles such as the Helicopter also possess it. It wouldn’t be effective to define this ability in each of them. Actually, it will be defined individually in each of these classes because each have their own way of flying, the bird flaps the wings, whereas the helicopter roatates its through a mechanical engine. However, this ability is declared in the Flyer interface so that any class which implements this interface would have to define the Fly() method by overriding it.</p> </div><pre><br /></pre></td></tr></tbody></table>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com1tag:blogger.com,1999:blog-6052374310229468906.post-74516488720664777102009-03-10T05:12:00.002-07:002009-03-10T05:13:00.214-07:00Windows Communication Foundation FAQ quick starter<pre style="margin-top: 0pt;"><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx" target="_blank">http://www.codeproject.com/KB/<wbr>aspnet/WCF.aspx</a><br /><br />Title: Windows Communication Foundation FAQ quick starter<br />Author: Shivprasad Koirala<br /><br />Email: <a href="mailto:shiv_koirala@yahoo.com" target="_blank">shiv_koirala@yahoo.com</a><br />Language: C#<br />Level: Beginner<br />Description: Windows Communication Foundation FAQ quick starter<br /><br />Update :- With links of WCF-Part 2, WPF and WWF.<br /><br /><br /></pre><h3>Windows Communication Foundation FAQ quick starter</h3> <p><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#Introduction" target="_blank">Introduction</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhatisNET3" target="_blank">What is .NET 3.0?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhatisWindowsCardSpace" target="_blank">What is Windows Card Space?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhatisWCF" target="_blank">What is WCF?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhataretheimportantprinciplesofSOAServiceorientedArchitecture" target="_blank">What are the important principles of SOA (Service oriented Architecture)?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#Whatareendscontractaddressandbindings" target="_blank">What are ends, contract, address, and bindings?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhichspecificationsdoesWCFfollow" target="_blank">Which specifications does WCF follow?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhatarethemaincomponentsofWCF" name="11fd34593cf49d7a_Introduction" target="_blank">What are the main components of WCF?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#ExplainhowEndsContractAddressandBindingsaredoneinWCF" name="11fd34593cf49d7a_Introduction" target="_blank">Explain how Ends, Contract, Address, and Bindings are done in WCF?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#whatisaserviceclass" name="11fd34593cf49d7a_Introduction" target="_blank">what is a service class?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#whatisaservicecontractoperationcontractandDataContract" name="11fd34593cf49d7a_Introduction" target="_blank">what is a service contract, operation contract and Data Contract?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#whatarethevariouswaysofhostingaWCFservice" target="_blank">what are the various ways of hosting a WCF service?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#HowdowehostaWCFserviceinIIS" target="_blank">How do we host a WCF service in IIS?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#whataretheadvantagesofhostingWCFServicesinIISascomparedtoselfhosting" target="_blank">what are the advantages of hosting WCF Services in IIS as compared to self-hosting?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#whatarethemajordifferencesbetweenservicesandWebservices" target="_blank">what are the major differences between services and Web services?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhatisthedifferenceWCFandWebservices" name="11fd34593cf49d7a_Introduction" target="_blank">What is the difference WCF and Web services?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#Whataredifferentbindingssupported%20byWCF" target="_blank">What are different bindings supported by WCF?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#WhicharethevariousprogrammingapproachesforWCF" target="_blank">Which are the various programming approaches for WCF?</a><br /><br /><a href="http://www.codeproject.com/KB/aspnet/WCF.aspx#Whatisonewayoperation" name="11fd34593cf49d7a_Introduction" target="_blank">What is one-way operation?</a></p> <h3><a name="11fd34593cf49d7a_Introduction">Introduction</a></h3> <p><br />In this section we will run through a quick FAQ for WCF. I am sure after reading this you will get a good understanding of the fundamentals of WCF.<br />In case you like the article or your think I need improvements please send me a message at <a href="http://www.questpond.com/" target="_blank">http://www.questpond.com</a> . I am sure every one needs improvements.<br />Enjoy…<br /><br />Click <a href="http://www.codeproject.com/KB/aspnet/WCFPart2.aspx" target="_blank">here</a> to see Windows Communication Framework (WCF) - Part 2</p> <p>Click <a href="http://www.codeproject.com/KB/WPF/BeginnerWPF.aspx" target="_blank">here</a> to see Windows Presentation Foundation (WPF)</p> <p>Click <a href="http://www.codeproject.com/KB/WF/WWF.aspx" target="_blank">here</a> to see Windows Workflow Foundation (WWF)</p> <h3><a name="11fd34593cf49d7a_WhatisNET3">What is .NET 3.0?</a></h3> <p><br />In one simple equation .NET 3.0 = .NET 2.0 + Windows Communication Foundation + Windows Presentation Foundation + Windows Workflow Foundation + Windows Card Space.<br /> </p> <h3><a name="11fd34593cf49d7a_WhatisWindowsCardSpace">What is Windows Card Space?</a></h3> <p><br />It was previously known by its codename Info Card. It is a framework by Microsoft, which securely stores digital identities of a user and provides a unified interface to choose the identity for a particular transaction, such as logging in to a website. Windows Card Space is a central part of Microsoft’s effort to create an identity met system, or a unified, secure and interoperable identity layer for the internet.<br /> </p> <h3><a name="11fd34593cf49d7a_WhatisWCF">What is WCF?</a></h3> <p><br />First let us give a short answer to this: - “WCF (Indigo was the code name for WCF) is a unification of .NET framework communication technologies “.WCF is a unification technology, which unites the following technologies:-<br />• NET remoting<br />• MSMQ<br />• Web services<br />• COM+.<br />Below figure depicts WCF fundamentals pictorially.</p> <p> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/1.JPG" border="0" height="328" width="396" /></p> <p align="center"><strong>Figure: 1 - WCF Components</strong></p> <h3 align="left"><br /><a name="11fd34593cf49d7a_WhataretheimportantprinciplesofSOAServiceorientedArchitecture">What are the important principles of SOA (Service oriented Architecture)?</a></h3> <p align="left"><br />WCF is based on SOA. All big companies are playing big bets on SOA. So how can Microsoft remain behind? So in order to implement SOA architecture easily you need to use WCF.<br />SOA is based on four important concepts:-<br /> </p> <p align="left"><strong>• Boundaries are well defined</strong></p> <p align="left"><br />In SOA, everything is formalized. The client who is consuming the service does not need to know how the implementation of the service is done. If you look at some old methodologies of communication like DCOM. Any changes at server level the client also has to change. Therefore, the server and client implementation was so much bound that changes need to be done at all places. In SOA, the rule is if you do enhancement you do not need to change anything at the client. SOA based application only understands that there is an end point, contract, and bindings.<br /> </p> <p align="left"><em><strong>Note: - Just to clarify shortly about end point and contract. Any SOA service is exposed through an end point. End point defines three important aspects What, Where and How. We will understand more details of the same in the later questions.</strong></em></p> <p align="left"><br /><strong>• Services evolve</strong></p> <p align="left"><br />Change is the law of nature and services will evolve. In SOA, services can be versioned and you can host those services in new ends. For instance, you have a service called as “Search Tickets (Ticket Number) “which gives details based on Ticket Number and its exposed on end point “ep1”. Tomorrow you want make your Search Tickets service more useful by also providing an extra option of allowing him to search by passenger name. Therefore, you just declare a new end “ep2” with service “Search Tickets (Ticket Number, Passenger Name)”. So the client who is consuming the service at end ep1 continues and at the other end, we have evolved our service by adding new ends ep2.<br /> </p> <p align="left"><strong>• Services share only schemas and contracts</strong></p> <p align="left"><br />Services use Schemas to represent data and contracts to understand behavior. They do not use language dependent types or classes in order to understand data and behavior. XML is used to define schemas and contracts. Due to this, there is not heavy coupling between environments.<br /> </p> <p align="left"><strong>• Service compatibility is policy based</strong></p> <p align="left"><br />Policy describes the capabilities of the system. Depending on policies, the service can degrade to match the service for the client. For instance your service needs to be hosted for two types of client one which uses Remoting as the communication methodology while other client uses DCOM. An ideal SOA service can cater to both of them according to there communication policies.<br /> </p> <p align="left"><em><strong>Note: - Many people assume Web services are the base for SOA. The answer is 50 % right. What web services lack is the policy based Service compatibility. If you host a web service it can only serve with HTTP communication channel and SOAP message. Any other type of client trying to communicate he will not degrade it self. This is what is provided by WCF. You can host the service in one or more mode. For instance you can host a WCF service using remoting and ASMX.<br /> </strong></em></p> <h3 align="left"><a name="11fd34593cf49d7a_Whatareendscontractaddressandbindings">What are ends, contract, address, and bindings?</a></h3> <p align="left"><br />The above terminologies are the core on which SOA stands. Every service must expose one or more ends by which the service can be available to the client. End consists of three important things where, what and how:-<br /> </p> <p align="left"><strong>• Contract (What)</strong></p> <p align="left"><br />Contract is an agreement between two or more parties. It defines the protocol how client should communicate with your service. Technically, it describes parameters and return values for a method.<br /> </p> <p align="left"><strong>• Address (Where)</strong></p> <p align="left"><br />An Address indicates where we can find this service. Address is a URL, which points to the location of the service.<br /> </p> <p align="left"><strong>• Binding (How)</strong></p> <p align="left"><br />Bindings determine how this end can be accessed. It determines how communications is done. For instance, you expose your service, which can be accessed using SOAP over HTTP or BINARY over TCP. So for each of these communications medium two bindings will be created.<br />Below figure, show the three main components of end. You can see the stock ticker is the service class, which has an end hosted on <a href="http://www.soa.com/" target="_blank">www.soa.com</a> with HTTP and TCP binding support and using Stock Ticker interface type.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/2.JPG" border="0" height="279" width="508" /></p> <p align="center"><strong>Figure 2: - Endpoint Architecture</strong></p> <p align="left"><br /><em><strong>Note: - You can also remember the end point by ABC where A stands for Address, B for bindings and C for Contract.<br /> </strong></em></p> <h3 align="left"><a name="11fd34593cf49d7a_WhichspecificationsdoesWCFfollow">Which specifications does WCF follow?</a></h3> <p align="left"><br />WCF supports specifications defined by WS-* specifications. WS-* specifications are defined together by Microsoft, IBM, SUN and many other big companies so that they can expose there service through a common protocol. WCF supports all specifications defined we will understand them one by one.<br /><strong><br />• Messaging (WS-Addressing):-</strong> SOAP is the fundamental protocol for web services. WS Addressing defines some extra additions to SOAP headers, which makes SOAP free from underlying transport protocol. One of the good things about Message transmission is MTOM, also termed as Message Transmission Optimization Mechanism. They optimize transmission format for SOAP messages in XML-Binary formant using XML optimized packaging (XOP). Because the data will sent in binary and optimized format, it will give us huge performance gain.<br /><strong><br />• Security (WS-Security, WS-Trust, and WS-Secure Conversation):- </strong>All the three WS- define authentication, security, data integrity and<br />privacy features for a service.<br />• Reliability (WS-Reliable Messaging):- This specification ensures end-to-end communication when we want SOAP messages to be traversed back and forth many times.<br /><br /><strong>• Transactions (WS-Coordination and WS-Atomic Transaction):-</strong> These two specifications enable transaction with SOAP messages.<br /><br /><strong>• Metadata (WS-Policy and WS-Metadata exchange):-</strong> WSDL is a implementation of WS-Metadata Exchange protocol. WS-Policy defines more dynamic features of a service, which cannot be expressed by WSDL.<br />We have stressed on the WS-* specification as it is a specification which a service has to follow to be compatible with other languages. Because WCF follows WS-* specifications other languages like JAVA , C++ can also exploit features like Messaging , Security , Reliability and transactions written in C# or <a href="http://vb.net/" target="_blank">VB.NET</a>. This is the biggest achievement of WCF to integrate the above features with other languages.<br /> </p> <p align="left"><em><strong>Note: - During interview the interviewer expects that you know what WS-* specification are supported by WCF and its advantages with respect to interacting with other languages.</strong></em></p> <h3 align="left"><br /><a name="11fd34593cf49d7a_WhatarethemaincomponentsofWCF">What are the main components of WCF?</a></h3> <p align="left"><br />We need to define three main components in WCF:-<br />• Service class.<br />• Hosting environment<br />• End point<br /> </p> <h3 align="left"><a name="11fd34593cf49d7a_ExplainhowEndsContractAddressandBindingsaredoneinWCF">Explain how Ends, Contract, Address, and Bindings are done in WCF?</a></h3> <h3 align="left"><br /><a name="11fd34593cf49d7a_whatisaserviceclass">what is a service class?</a></h3> <h3 align="left"><br /><a name="11fd34593cf49d7a_whatisaservicecontractoperationcontractandDataContract">what is a service contract, operation contract and Data Contract?</a></h3> <p align="left"><br />In this example, we will make simple service, which displays the total cost of the complete product group. In simple words, this service will take three parameters per product cost, number of products and the product name. In return the service will return the total cost of all the products by multiplying number of products * cost per product. As we go ahead in this explanation, we will try to understand all the terminologies, which are asked in the above question.<br />First, you need to create a Winfx service project. You can see in the below figure we have selected the Winfx project.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/3.JPG" border="0" height="536" width="730" /></p> <p align="center"><strong>Figure 3: - Create new WinFX Service class</strong></p> <p align="left"><br />In this project, we add a new class and name it as “serviceGetCost.cs”. This class will have our core implementation and this is the class, which has all the action. The service class, which has to be exposed to the external client. We need to use the Service Contract attribute to mark it as a service class.<br />Service Contract attribute define saying which application interface will be exposed as a service.<br />You can see in the below code snippet we have made an interface and marked it as Service Contract. It is not essential that you need to use an interface you can also use a simple class and mark it as Service but interface represent a contract and do not have implementation. In short, they stand at a very higher level of abstraction. So as a good design practice-using interface to represent a service contract makes more sense.<br />The next thing to note is the Operation Contract attribute.<br />Operation Contract dictates which methods should be exposed to the external client using this service.<br />It defines individual exchange or request and replies. In the current sample, we have defined GetTotalCost method, which will be used by the end client to get the total cost results.<br />The next thing to note in the code snippet is the Data Contract attribute. In the previous two steps, we have exposed class as a service by using Service Contract and methods by using Operation Contract. Every operation will definitely do some kind of data transfer.<br />Data Contract attributes defines which type of complex data will be exchanged between the client and the service. They determine which parameters to be serialized.<br />When you are using simple data types like int, bolo etc it is not necessary that you need to mark the data contract attribute. Because you will always find matching types on the client. However, complex structure like one shown in the below code snippet you will need to define a data contract. Remember data contract define how this data will be passed during transmission. In short data contract attribute define how data will be serialized will transmission.<br />In the below sample we have marked the structure product data to be serialized.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/4.JPG" border="0" height="422" width="718" /></p> <p align="center"><strong>Figure 4:- The Service class</strong></p> <p align="left"><br />As data contract are all about serialization you need to import System.Runtime.Serialization name space.<br />In the next step, we implement the GetTotalCost function. It just returns a simple string with product name and the total cost of all products.<br />Once our service class is done its time to host this service. There are various ways of hosting a WCF service we will look in to the same in the next question. For the current example, we will host in their own process.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/5.JPG" border="0" height="453" width="679" /></p> <p align="center"><strong>Figure 5: - Hosting the service</strong></p> <p align="left"><br />Hosting the WCF service needs two things one is the config file and second is the hosting code on startup. Because we are hosting this service in its own application process this needs to be a windows application. So first let us have a look what entries do, we need to make in the App.config file. In the above figure, everything is clear but let us understands all the section defined in the App.config file.<br />In the configuration section, we need to add a new section <system.servicemodel>. The most important part of <system.servicemodel> is the endpoint tag. As said in the previous answer End gives three important answers Where, What and How. In short where is the service, what the contract of the service is and how do we communicate with the service.<br />In the above code snippet, we have only defined the contract i.e. what and how that is bindings. The where is defined in the application entry point static void main ().<br />Therefore, the contract attribute defines the interface and binding says that the end clients can communicate using “HTTP” protocol.<br />In Static void Main method, we create an object of Service Host class and use the open method to host the service. We have used the URI object to define the address where the service will be hosted.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/6.JPG" border="0" height="156" width="375" /></p> <p align="center"><strong>Figure 6: - Service Started</strong></p> <p align="left"><br />If you compile the project, you will see something as shown in the above figure. This says that the service is up and running and ready to serve any WCF client. Now its time to develop consumer, which will consume this WCF service. Microsoft has provided a decent automation to generate the client. Therefore, below figure depicts the various steps.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/7.JPG" border="0" height="388" width="554" /></p> <p align="center"><strong>Figure 7: - svcutil in action</strong></p> <p align="left"><br />Go to command prompt of windows SDK and run the following command:-<br />Svcutil <service><br />In the above command <service> is the URI on which the service is hosted. One you run the command against the URI it will generate two files one is the config file and the other is the proxy. You can see in the above figure two files are generated serviceGetCost.cs and output.config file. With the help of these two files, we will make our client.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/8.JPG" border="0" height="427" width="713" /></p> <p align="center"><strong>Figure 8: - Client code walkthrough</strong></p> <p align="left"><br />You can see in the above figure we have made WFCClientGetCost project. In that, we have added output.config and serviceGetCost.cs to the client project. We have renamed output.config to app.config.<br />Once we have done with everything, its time to write the client code, which calls the proxy who in turn will call the service hosted. In the above figure, you can see we have the client code also. It is a simple code we first created the object of the data structure set the values. Then we create the object of the service and call the GetTotalCost function.<br />If everything is compiled and you run the server and client, you should get your output as shown below.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/9.JPG" border="0" height="83" width="473" /></p> <p align="center"><strong>Figure 9: - Output of WCF service</strong></p> <h3 align="left"><br /><a name="11fd34593cf49d7a_whatarethevariouswaysofhostingaWCFservice">what are the various ways of hosting a WCF service?</a></h3> <p align="left"><br />There are three major ways to host a WCF service:-<br />• Self-hosting the service in his own application domain. This we have already covered in the first section. The service comes in to existence when you create the object of Service Host class and the service closes when you call the Close of the Service Host class.<br />• Host in application domain or process provided by IIS Server.<br />• Host in Application domain and process provided by WAS (Windows Activation Service) Server.<br /> </p> <h3 align="left"><a name="11fd34593cf49d7a_HowdowehostaWCFserviceinIIS">How do we host a WCF service in IIS?</a></h3> <p align="left"><br /><em><strong>Note: - The best to know how to host a WCF in IIS is by doing a small sample. So what we will do is host the same GetCost sample which was self hosted in the previous question.</strong></em></p> <p align="left"><br />First thing you will need is to create the SVC file, which exposes the service class. SVC file contains the pointer to the class. You can see from the figure below the class attribute points to the class whose interface is exposed by the service.svc.cs file. Also, note the actual interface is in service.svc.cs file. Below figure, have both the files service.svc, which has the class attribute which points to the service class, and the interface, which resides in service.svc.cs file. We have taken the same sample, which was self-hosted in the previous question.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/10.JPG" border="0" height="450" width="535" /></p> <p align="center"><strong>Figure 10: - The SVC file and the behind code</strong></p> <p align="left"><br />We also need to provide implementation for the interface. So we have made a class ServiceGetCost which has the actual implementation. Below figure shows the same in detail. In the below figure you can also see the solution files.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/11.JPG" border="0" height="419" width="593" /></p> <p align="center"><strong>Figure 11: - Implementation of Service.svc.cs</strong></p> <p align="left"><br />We also need to specify the service type and endpoint in web.config file. Also, note we have specified HTTP binding because we will be hosting the service on IIS.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/12.JPG" border="0" height="371" width="668" /></p> <p align="center"><strong>Figure 12: - Web.config file for hosting service on IIS</strong></p> <p align="left"><br />Now that we are done with the coding part. We need to create the virtual directory in IIS. In the below figure in Step1 and Step2 we have shown how to create the virtual directory in IIS. One important thing to note while creating virtual directory set the access permission to execute.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/13.JPG" border="0" height="549" width="770" /></p> <p align="center"><strong>Figure 13:- IIS Configuration</strong></p> <p align="left"><br />In the third step, we will publish the website to our virtual directory. Note the fourth step in which we have copied the svc file so that the service can be requested.<br />Note: - <a href="http://asp.net/" target="_blank">ASP.NET</a> compilation has changed in <a href="http://asp.net/" target="_blank">ASP.NET</a> 2.0. In 2.0 there is no concept of solution files. So if you want to have full compiled DLL you need to publish the project to a virtual directory.<br />Once you have hosted the SVC file you can test the same by request the service.svc file. If everything works fine you will get something as shown in the below figure<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/14.JPG" border="0" height="439" width="617" /></p> <p align="center"><strong>Figure 14:- IIS WCF client</strong></p> <p align="left"><br />Using the Svcutil.exe, you will need to generate the proxy class and the config file. The proxy and config will be same, as we had done for self-hosting. The one important change is the address. The config file URL now points to the service.svc, which is hosted on IIS. You can run the same client, which we had created for self-hosting. The only change you will need to do is change the endpoint address.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/15.JPG" border="0" height="82" width="474" /></p> <p align="center"><strong>Figure 15:- Output of WCF client at IIS</strong></p> <p align="left"><br />LOL…You should get the same output, which we had received, for self-hosting.<br /> </p> <h3 align="left"><a name="11fd34593cf49d7a_whataretheadvantagesofhostingWCFServicesinIISascomparedtoselfhosting">what are the advantages of hosting WCF Services in IIS as compared to self-hosting?</a></h3> <p align="left"><br />There are two main advantages of using IIS over self-hosting:-<br /> </p> <p align="left"><strong>Automatic activation</strong></p> <p align="left"><br />IIS provides automatic activation that means the service is not necessary to be running in advance. When any message is received by the service it then launches and fulfills the request. But in case of self hosting the service should always be running.<br /> </p> <p align="left"><strong>Process recycling</strong></p> <p align="left"><br />If IIS finds that a service is not healthy that means if it has memory leaks etc, IIS recycles the process. Ok let us try to understand what is recycling in IIS process. For every browser instance, a worker process is spawned and the request is serviced. When the browser disconnects the worker, process stops and you loose all information. IIS also restarts the worker process. By default, the worker process is recycled at around 120 minutes. So why does IIS recycle. By restarting the worker process it ensures any bad code or memory leak do not cause issue to the whole system.<br />In case of self-hosting both the above features, you will need to code yourself. Lot of work right!!. That is why IIS is the best option for hosting services until you are really doing something custom.<br />Below figure shows where the recycle option is located in IIS. You need to click on the DefaultAppool and then Properties.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/16.JPG" border="0" height="429" width="672" /></p> <p align="center"><strong>Figure 16:- IIS recycle option</strong></p> <h3 align="left"><br /><a name="11fd34593cf49d7a_whatarethemajordifferencesbetweenservicesandWebservices">what are the major differences between services and Web services?</a></h3> <h3 align="left"><br /><a name="11fd34593cf49d7a_WhatisthedifferenceWCFandWebservices">What is the difference WCF and Web services?</a></h3> <p align="left"><br />Web services can only be invoked by HTTP. While Service or a WCF component can be invoked by any protocol and any transport type. Second web services are not flexible. However, Services are flexible. If you make a new version of the service then you need to just expose a new end. Therefore, services are agile and which is a very practical approach looking at the current business trends.<br /> </p> <h3 align="left"><a name="11fd34593cf49d7a_Whataredifferentbindingssupported byWCF">What are different bindings supported by WCF?</a></h3> <p align="left"><br />WCF includes predefined bindings. They cover most of bindings widely needed in day-to-day application. However, just incase you find that you need to define something custom WCF does not stop you. So let us try to understand what each binding provides.<br />BasicHttpBinding: - This binding is used when we need to use SOAP over HTTP. This binding can also be configured to be used as HTTPS. It can be also configured to send data in plain text or in optimized form like MTOM.<br /> </p> <p align="left"><em><strong>Note: - MTOM is discussed in one of the pervious questions in this chapter.</strong></em></p> <p align="left"><br /><strong>WsHttpBinding:</strong> - It is same like BasicHttpBinding. In short, it uses SOAP over HTTP. But with it also supports reliable message transfer, security and transaction. WS-Reliable Messaging, security with WS-Security, and transactions with WS-Atomic Transaction supports reliable message.<br /><strong>NetTcpBinding:</strong> - This binding sends binary-encoded SOAP, including support for reliable message transfer, security, and transactions, directly over TCP. The biggest disadvantage of NetTcpBinding is that both server and client should be also made in .NET language.<br /><strong>NetNamedPipesBinding:</strong>-Ths binding Sends binary-encoded SOAP over named pipes. This binding is only usable for WCF-to-WCF communication between processes on the same Windows-based machine.<br /> </p> <p align="left"><em><strong>Note: - An interprocess control (IPC) protocol is used for exchanging information between two applications, possibly running on different computers in a network. The difference between Named pipes and TCP is that named pipes have good performance in terms of communication with in processes. But when it comes to communicate across network TCP holds the best choice. So if you are using WCF to communicate with process it’s the best choice to use in terms for performance. Named pipes do not perform when the traffic is heavy as compared to TCPIP.</strong></em></p> <p align="left"><br /><strong>NetMsmqBinding:</strong> - This binding sends binary-encoded SOAP over MSMQ. This binding can only be used for WCF-to-WCF communication.<br /> </p> <h3 align="left"><a name="11fd34593cf49d7a_WhicharethevariousprogrammingapproachesforWCF">Which are the various programming approaches for WCF?</a></h3> <h3 align="left"><br /><a name="11fd34593cf49d7a_Whatisonewayoperation">What is one-way operation?</a><br /> </h3> <p align="left">IsOneWay equal to true ensures that the client does not have to wait for the response. So methods marked by IsOneWay to true should always return void. In this, the caller does not get anything in return so it is called as one-way communication.<br />In order to understand one-way implementation in WCF lets make a code walkthrough of a sample.<br />Note: - You can find code for the same in “WCFIsOneWay” folder in CD.<br /> </p> <p align="center"><img src="http://www.codeproject.com/KB/aspnet/WCF/17.JPG" border="0" height="555" width="564" /></p> <p align="center"><strong>Figure 17: - One-Way in action</strong></p> <p align="left"><br />Above is the code snippet, which describes practically how one way works in WCF. The above given code snippet is numbered. Below is the explanation according to the numbers marked in figure:-<br />1 - This is the code snippet of the server service. We have created a method called as doHugeTask. DoHugeTask makes the method sleep for 5000 MS and then displays the time when the task is completed.<br />2 - This code snippet is for client. It creates a proxy object of serviceIsOneWay and calls the doHugeTask method. After calling the doHugeTask, the client execution continues ahead. So as a proof, we display the time when the method calling was completed.<br />3 - This screen shot shows the output given by both server and client. The top window displays the server output and the below windows displays the client output.<br /> </p> <p align="left"><em><strong>Note: - You can find the code for the same in WCFIsOneWay folder. For generating the proxies you have to follow the same steps which are shown in the previous steps.<br /> </strong></em></p> <p align="left">So run the server program first i.e. ServiceIsOneWay and run the client later. You will see the client runs the doHugeTask and moves ahead. Therefore, the client completion time is less than the server is. One more thing to understand is that one way does not give any notification back of completion. Therefore, it is like fire and forgets.<br /> </p> <div> <input name="__VIEWSTATE" value="/wEPDwULLTEwMDUyNjYzMjgPZBYCZg9kFgQCCw9kFgYCAw8PFgIeB1Zpc2libGVnZGQCCQ8PFgIfAGdkZAIMDw8WAh8AZ2RkAgwPZBYIAgcPZBYQAgEPZBYCZg8WAh4LXyFJdGVtQ291bnRmZAIDD2QWCmYPDxYCHgtOYXZpZ2F0ZVVybAUhL0tCL2FzcG5ldC9XQ0YuYXNweD9kaXNwbGF5PVByaW50ZGQCAQ8PFgIfAgUmL3NjcmlwdC9BcnRpY2xlcy9SZXBvcnQuYXNweD9haWQ9Mjk0NzVkZAICDw8WAh8AaGRkAgMPDxYCHwBoZGQCBQ8PFgIfAgUxL3NjcmlwdC9jb21tb24vVGVsbEZyaWVuZC5hc3B4P29idGlkPTImb2JpZD0yOTQ3NWRkAgUPZBYEAgEPZBYCAgEPDxYCHgRUZXh0BRo0MiB2b3RlcyBmb3IgdGhpcyBBcnRpY2xlLmRkAgYPZBYCZg9kFgQCAQ8PFgQfAwUQUG9wdWxhcml0eTogNS43OR8CBSkvc2NyaXB0L0FydGljbGVzL1RvcEFydGljbGVzLmFzcHg/dGFfc289MWRkAgUPFgIfAwUcUmF0aW5nOiA8Yj4zLjU2PC9iPiBvdXQgb2YgNWQCEQ9kFgICAQ8PFgIfAgUmL3NjcmlwdC9BcnRpY2xlcy9SZXBvcnQuYXNweD9haWQ9Mjk0NzVkZAIZD2QWCgIBD2QWBAIBDxYCHglpbm5lcmh0bWwFtgE8cD5UaGlzIGFydGljbGUsIGFsb25nIHdpdGggYW55IGFzc29jaWF0ZWQgc291cmNlIGNvZGUgYW5kIGZpbGVzLCBpcyBsaWNlbnNlZCB1bmRlciA8YSBocmVmPSJodHRwOi8vd3d3LmNvZGVwcm9qZWN0LmNvbS9pbmZvL2Nwb2wxMC5hc3B4Ij5UaGUgQ29kZSBQcm9qZWN0IE9wZW4gTGljZW5zZSAoQ1BPTCk8L2E+PC9wPmQCAg9kFgICAQ8QZGQWAGQCBQ8WAh8BAgFkAgcPFgIfAwXjCDxoMj5PdGhlciBwb3B1bGFyIEFwcGxpY2F0aW9ucyAmIFRvb2xzIGFydGljbGVzOjwvaDI+PHVsPjxsaT48YSBocmVmPSIvS0IvYXBwbGljYXRpb25zL3RvZG9saXN0Mi5hc3B4Ij5Ub0RvTGlzdCA1LjcuMiAtIEEgc2ltcGxlIGJ1dCBlZmZlY3RpdmUgd2F5IHRvIGtlZXAgb24gdG9wIG9mIHlvdXIgdGFza3M8L2E+PGRpdiBjbGFzcz0iU21hbGxUZXh0Ij5BIGhpZXJhcmNoaWNhbCB0YXNrIG1hbmFnZXIgd2l0aCBuYXRpdmUgWE1MIHN1cHBvcnQgZm9yIGN1c3RvbSByZXBvcnRpbmcuPC9kaXY+PC9saT48bGk+PGEgaHJlZj0iL0tCL21pc2NjdHJsL2dyaWRjdHJsLmFzcHgiPk1GQyBHcmlkIGNvbnRyb2wgMi4yNjwvYT48ZGl2IGNsYXNzPSJTbWFsbFRleHQiPkEgZnVsbHkgZmVhdHVyZWQgTUZDIGdyaWQgY29udHJvbCBmb3IgZGlzcGxheWluZyB0YWJ1bGFyIGRhdGEuIFRoZSBncmlkIGlzIGEgY3VzdG9tIGNvbnRyb2wgZGVyaXZlZCBmcm9tIENXbmQ8L2Rpdj48L2xpPjxsaT48YSBocmVmPSIvS0IvdGlwcy9TZWxmLWdlbmVyYXRpbmctY29kZS5hc3B4Ij5Qcm9ncmFtbWluZyBTZWxmLWdlbmVyYXRpbmcgQ29kZSBmb3IgV2luZG93cyBBcHBsaWNhdGlvbnM8L2E+PGRpdiBjbGFzcz0iU21hbGxUZXh0Ij5FeGVjdXRpbmcgVkMrKyBjb2RlcyBpbiBTVEFDSyBvciBIRUFQPC9kaXY+PC9saT48bGk+PGEgaHJlZj0iL0tCL2NzL0FzeW5jTWV0aG9kSW52b2NhdGlvbi5hc3B4Ij5Bc3luY2hyb25vdXMgTWV0aG9kIEludm9jYXRpb248L2E+PGRpdiBjbGFzcz0iU21hbGxUZXh0Ij5Ib3cgdG8gdXNlIC5ORVQgdG8gY2FsbCBtZXRob2RzIGluIGEgbm9uLWJsb2NraW5nIG1vZGUuPC9kaXY+PC9saT48bGk+PGEgaHJlZj0iL0tCL2dyYXBoaWNzL3plZGdyYXBoLmFzcHgiPkEgZmxleGlibGUgY2hhcnRpbmcgbGlicmFyeSBmb3IgLk5FVDwvYT48ZGl2IGNsYXNzPSJTbWFsbFRleHQiPkxvb2tpbmcgZm9yIGEgd2F5IHRvIGRyYXcgMkQgbGluZSBncmFwaHMgd2l0aCBDIz8gSGVyZSdzIHlldCBhbm90aGVyIGNoYXJ0aW5nIGNsYXNzIGxpYnJhcnkgd2l0aCBhIGhpZ2ggZGVncmVlIG9mIGNvbmZpZ3VyYWJpbGl0eSwgdGhhdCBpcyBhbHNvIGVhc3kgdG8gdXNlLjwvZGl2PjwvbGk+PC91bD5kAgkPDxYCHwBnZGQCDQ8WAh4FY2xhc3MFFUFydGljbGVVbmVkaXRlZEhlYWRlchYCZg9kFgICAQ9kFgJmD2QWAgIJDxYCHwBoFgICAQ8QZGQWAGQCGw8PFgIfAGdkZAIdDw8WAh8AZ2RkAiUPFgIfAGhkAgkPDxYCHwIFJy9zY3JpcHQvQXJ0aWNsZXMvQXJ0aWNsZS5hc3B4P2FpZD0yOTQ3NWRkAg8PFgIfAwULMjUgRmViIDIwMDlkAhMPFgIfAwUkQ29weXJpZ2h0IDIwMDggYnkgU2hpdnByYXNhZCBrb2lyYWxhZGQ9ds2YcBMSG+/CPrzQ9KuO1kwHnA==" type="hidden"> </div> <h2>License</h2> <div><p>This article, along with any associated source code and files, is licensed under <a href="http://www.codeproject.com/info/cpol10.aspx" target="_blank">The Code Project Open License (CPOL)</a></p></div>Dennishttp://www.blogger.com/profile/07159229129253305624noreply@blogger.com0