MFC and .NET Explorations

21 December 2006

Moved blog...

I moved this blog from here to there

18 December 2006

What I listened to this week #5

Labels:

16 December 2006

Books I currently flip through #2

Software Engineering...

Web Services...

Database...

Misc

Labels:

10 December 2006

What I listened to this week #4

Last week

Labels:

05 December 2006

Handy Collections

  • Generic key/value pair collection that automatically sorts based on the key:
    SortedList<TKey,TValue>
  • Same as above but without the automatic sorting and better performance with large number of items:
    Dictionary<TKey,TValue>

http://msdn2.microsoft.com/en-us/library/5tbh8a42.aspx


Declare either of them it as follows:

        public SortedList<int, Antenna> antennas;

To iterate through it:

        for each (KeyValuePair<int, Antenna^> kvp in rigging->antennas)
        {
            Antenna^ antenna = kvp.Value;
 
            CString antennaId;
            antennaId.Format(_T("%d"), kvp.Key);
 
            (...)
        }
 

  • I'm using key/value pair collections because I want to be able to retrieve an element given its key. But it is possible to perform much more complex retrievals in a very elegant way. Anything that implements IEnumerable can be searched.

04 December 2006

Code tips to re-use

03 December 2006

What I listened to this week #3

Vista

SOA

Misc

Last week

Labels:

30 November 2006

C# or C++/CLI?

Advantages of C#

  • no cpp/h, just one file
  • better IDE support:
    • better intellisense
    • code auto-complete
    • refactoring (auto rename, method extraction, ...)
    • code snippets
    • compile errors displayed as you type
  • no, it's not Microsoft proprietary, there is an ECMA standard for it.
Advantages of C++/CLI

  • support for mixing managed and unmanaged code. Excellent for re-use of legacy code.
  • cool language extensions (e.g. for each, ...)
  • no, it's not Microsoft proprietary, there is an ECMA standard for it

29 November 2006

Create an event in C++/CLI

It's easy in C#, you just write:
        public event QueryReturnedHandler QueryReturned;

How does it work in C++/CLI though?

http://msdn2.microsoft.com/en-us/library/xey702bw.aspx

26 November 2006

What I listened to this week #2

Last Week

Labels:

21 November 2006

Marshal a string from managed to unmanaged

I need to pass a string from C++/CLI managed to C++ unmanaged code.
The unmanaged function takes a LPCTSTR as parameter and I want to pass a String^. How do I do that?

The answer here:
http://msdn2.microsoft.com/en-gb/library/ms235282(VS.80).aspx

And a function to do it easily:

    LPCTSTR MarshalString(String^ managedString)
    {
        return (LPCTSTR)Marshal::StringToHGlobalUni (managedString).ToPointer();
    }
 

and back:


    String^  DiagramContainer::MarshalString(LPCTSTR nativeString)
    {
        return Marshal::PtrToStringAuto(IntPtr((void *)nativeString));
    }

19 November 2006

Books I currently flip through...

Code...

Architecture...

Others...

Labels:

Mixing legacy MFC code with Windows Forms (Part 2)

I know how to call unmanaged code from a managed class.

How to do the opposite?

This piece of code

    public class DiagramContainer
    {
 
    private:
        // Managed reference to some data
        Rigging^ m_rigging;
    };

returns the following error:

Error 1 error C3265: cannot declare a managed 'm_rigging' in an unmanaged 'MFCControls::DiagramContainer'

Hints:
http://www.ondotnet.com/pub/a/dotnet/2003/03/03/mcppp2.html?page=last

Solution:
Use gcroot

    public class DiagramContainer 
    {
    private:
        // Managed reference to some data. gcroot makes it look like an unmanaged type
        gcroot<rigging^ > m_rigging;
    };


m_rigging can be used as a usual Rigging^ object. You reach the members using ->

18 November 2006

What I listened to this week #1

Labels:

01 June 2006

Mixing legacy MFC code with Windows Forms (Part 1)

I am looking into how to run legacy MFC code within a nice-looking Windows Forms framework. I built an MDI with Windows Forms and C# using ADO.NET. I have a large code base in C++: rather than rewriting the complete application from scratch (and therefore having to maintain and deploy 2 distinct applications, one in Windows Forms, one in MFC), I'd like to integrate the legacy code inside the new Windows Forms framework. This would allow for a smooth transition from MFC to Windows Forms.

I must solve two problems:

  • use an MFC property sheet from a C# app
  • manage ODBC and ADO.NET connections in a single exe

Backgrounders:

Getting closer:

What I have tried so far:

  • Subclass System.Windows.Forms.Control

As a starting point I used http://www.codeproject.com/managedcpp/mfcandwindowsforms.asp, which explains how to drag and drop into the Windows Forms designer a control based on legacy MFC code. This technique relies on subclassing: the Windows Forms control is created first, then its handle is passed to the MFC class which is then responsible for drawing the control. It works well as long as the MFC class derives from CWnd.

Subclass a Windows forms control with an MFC CWnd

The Winforms C# App calls a C++ managed wrapper (derived from System::Windows::Forms::Control). Upon creation of its handle, the wrapper associates the handle with a CWnd-derived MFC class. The original code from the Codeproject article used C++ managed extensions. I compiled it with VS2005 so I had to translate it from C++ managed extensions to C++/CLI and it worked just fine.

This technique works ok with a CWnd-derived class. Unfortunately our legacy MFC code is based on property sheets so this is not going to be enough, but it’s a start.

  • One single C++/CLI App containing MFC legacy source and dialog templates.

Created a C++ Windows Forms project. Added the MFC property sheets and property pages sources files to it. Also added the dialog templates associated with each page. The app consisted of a windows form that launches the MFC property sheet when you click a button. It worked.

However for some reason only the Release version of the executable worked. The Debug version kept displaying the following assertion,

Error

an instead of displaying the appropriate line of code just got my machine to thrash.

Anyway this is still not quite what I want to do: my Windows Forms MDI framework is written in C#, not in C++. The legacy code must reside a DLL compiled in mixed mode.

  • A C# Windows Forms project calls a dialog residing inside a mixed-mode exe

Attempt2

I created the MFC dialog project with the Wizard then modified its properties:

    • Changed to DLL
    • Switched on /clr
    • Disabled pre-compiled headers.

Got the following error:

Fixups

  1. Created an MFC MDI App with Visual Studio 2005.
  2. Added MFCAppAdapter.cpp (copied from Alexey Shalnov’s article).
  3. Changed MFCAppAdapter.cpp compile options to /clr (at the file level, not the project level).
  4. Set Code Generation option: set to default.
  5. Set Enable Minimal Rebuild option to No.
  6. Set Enable C++ Exceptions to Yes with SEH
  7. Set Debug Information Format to Zi
  8. Add references to System and System.Windows.Forms

TBC

28 December 2005

Things to Read

In this column, I'm going to explain how this common use of thread synchronization is exposed via the .NET Framework. Specifically, I'm going to explain the motivation for why SyncBlocks and Monitors were designed the way they are and how they work. Then, at the end of this column, I'm going to explain why this design is horrible and show you how to use this mechanism in a good, safe fashion


21 December 2005

Usefull Add-Ins

18 December 2005

Why vs 2003 cannot use .NET Framework 2.0

Fashion

17 December 2005

Using Windows Forms Controls in MFC

16 December 2005

PropertyGrid

Read this:

15 December 2005

Visual Studio 2005

  • How much does it cost?

http://msdn.microsoft.com/howtobuy/vs2005/editions/pro/

  • Product lines

http://lab.msdn.microsoft.com/vs2005/productinfo/productline/default.aspx

  • Upgrades are possible from

http://msdn.microsoft.com/vstudio/howtobuy/renewal/#up_pro

27 October 2005

Auto-update

  • AppUpdater Component

http://www.theserverside.net/articles/showarticle.tss?id=AppUpdater

  • Updater Application Block
http://www.theserverside.net/articles/showarticle.tss?id=UpdateAppBlock

  • ClickOnce in .NET 2.0

http://www.ondotnet.com/pub/a/dotnet/2004/10/11/clickonce.html

http://www.caparea.net/Meetings+and+Events/202.aspx

http://dnjonline.com/article.aspx?ID=dotNET2_winforms

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwinforms/html/clickonce.asp

ClickOnce does not require the end-user to have admin rights to the client machine.

http://msdn.microsoft.com/msdnmag/issues/04/05/ClickOnce/

16 October 2005

Oracle and .NET

  • Oracle and .NET
http://www.oracle.com/technology/pub/articles/mastering_dotnet_oracle/index.html
  • Security and .NET

http://www.oracle.com/technology/pub/articles/mastering_dotnet_oracle/cook_masteringdotnet.html

07 September 2005

Calling stored procedures from C#

.NET: Looking for C# GUI libraries

Trying to build a list of C# GUI libraries.

  • Catalogue of libraries on http://www.componentsource.com/. Click here.
  • http://www.dotnetmagic.com/ Went through the demo app. They provide Office 2003 menus.
  • Xceed Smart UI for .NET - $341 - classic, Office and Office 2003 controls - looks very good and complete. I started evaluating it. Created a small app with it. Very easy to use. Apps created with the demo version of the libraries will fail to run/compile after the license has expired (45 days). However if you re-install the demo, a new license key will be generated, giving 45 days again, so you can take your time to evaluate.
    The code samples are a little bit weak.
    http://www.xceedsoft.com/download/downloadform.aspx?produitID=289
Bumped into the Windows XP Visual Guidelines: http://www.microsoft.com/whdc/hwdev/windowsxp/downloads/default.mspx.

18 August 2005

Smart Clients

  • Smart Client Architecture and Design Guide

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnpag/html/SCAG.asp

  • Smart Clients in .NET 2.0: very interesting article that talks about command pattern, multithreading, auto-update, one-click deployment...

http://www.codeproject.com/smartclient/SmartClientSOA.asp


  • An example of Smart Client: RSS Feeder

http://www.codeproject.com/smartclient/rssfeeder.asp

Web services

08 August 2005

RSS Feeder source code

C# source code for a RSS client

http://www.codeproject.com/smartclient/rssfeeder.asp

 

05 August 2005

ADO.NET and MFC

Wow! It is possible to use ADO.NET from a C++ MFC project…

http://www.codeproject.com/managedcpp/adonetinmfc.asp

29 July 2005

Why use C++ with .NET?

It's true, why?
http://www.codeproject.com/managedcpp/whycppcli.asp

16 January 2005

Cool Things in .NET

C# Language

  • Explicit cast automatically raises exception if run-time type conversion is not possible.
  • Use of the “is” keyword in C# to check run time type.
  • Fields in a class can be initialised inline. ex: class blob { int member = 2; }
    You don't have to write the initialisation in the constructor. One of those things you instinctively tried to do in C++.

CLR

  • Documentation: list of class members include inherited members (which is very convenient, no need to navigate through the base classes)
  • C# supports floating point Point class. The MFC CPoint only supports integers.
  • When instantiating an object, the memory allocated to it is automatically zeroed out.
  • String interning: the CLR automatically groups equivalent strings in the same memory location.

IDE:

  • When adding a source file to a project (.cs file), if the source file is outside the solution directory then it is automatically copied to the solution directory.
  • When deleting a source file from the project, the actual file on disk is deleted as well.
  • It is possible to add an external file to a project by creating a link rather than copying it (choose Link File from the Open combo-button in the Add Existing Item window).

Intellisense:

  • To override a base method, just type protected override and choose the method from the Intellisense window.
  • When creating new event handler: after typing +=, pressing TAB automatically adds the typical delegate associated with event. Pressing TAB again inserts event handler.

08 January 2005

C++ MFC GUI Libraries

  • Professional User Interface Suite

http://www.codeproject.com/docking/prod_profuis.asp
http://www.prof-uis.com/

  • BCGSoft Library

http://www.bcgsoft.com/bcgcontrolbar.htm

11 December 2004

Trying out Xceed SmartUI

I'm starting to bump against a few limitations of the Xceed library:
  • I spent some time trying to work out why maximised MDI child windows add a standard menu bar on top of the Xceed menu bar. The fix for this in not in the documentation for SmartMenuBar. You have to set the HandleMdiControlButtons property to true.
  • Xceed MenuItem does not derive from System.Windows.Forms.MenuItem, and some of the functionality of the Microsoft MenuItem is missing. For instance the MdiList list property is missing: there is no built-in way of automatically listing the titles of MDI child windows in the Window menu item.
    http://www.xceedsoft.com/Forums/ShowPost.aspx?PostID=1896

15 November 2004

Looking for tool to automate GUI unit testing

 
So far this is the most interesting I found: it records mouse and keyboards events and replays them. It is possible to replay with a higher speed.
 

26 October 2004

How to control whether a toolbar appears above or below a menu bar?

If you add a toolbar and a menubar to the designer, they both get the Dock property set to Top by default. It can be quite frustrating to control which one appears on top of the other using the designer.

In InitializeComponent(), the following 2 lines add the controls to the main form:

this.Controls.Add(this.smartToolBar2);             

this.Controls.Add(this.smartMenuBar1);

Using the order above, the toolbar will be on top of the menu bar.

14 October 2004

To Read: C++ under .NET in Visual Studio 2005

Moving to .NET and WinFX: a Roadmap for C/C++ Applications
Review guidelines for moving to the .NET Framework without leaving behind the investment in existing code, and why you should consider moving to the .NET Framework not only for new development, but for existing applications as well. by Kate Gregory on 07/10/2004 08:00
 

10 October 2004

Tooltips and List View

About tooltips and how to create per sub-item tooltips.

Create the tool tip control using CtoolTipCtrl::Create function.

Many tools (for instance subitems in a list control) can be attached to the same tool tip using AddTool. Each tool is given an id. It is possible to change the rect of the tool using SetToolRect. Can be usefull with a list control.

How to update tooltips when the columns of a ClistCtrl are resized?

Use OnCustomDraw to catch the repaint of a subitem as in:

void CListCtrlEx::OnCustomDraw(NMHDR* pNMHDR, LRESULT* pResult)

{

    LPNMLVCUSTOMDRAW  lplvcd = (LPNMLVCUSTOMDRAW)pNMHDR;

    int iCol = lplvcd->iSubItem;

    int iRow = lplvcd->nmcd.dwItemSpec;

 

    switch(lplvcd->nmcd.dwDrawStage)

    { 

          case CDDS_PREPAINT:

                *pResult = CDRF_NOTIFYSUBITEMDRAW|CDRF_NOTIFYPOSTPAINT;   // ask for subitem notifications.

                break;

          case CDDS_ITEMPREPAINT:

                // Necessary for CDDS_ITEMPREPAINT|CDDS_SUBITEM to be called

                *pResult = CDRF_NOTIFYSUBITEMDRAW|CDRF_NOTIFYPOSTPAINT;

                break;

          case CDDS_ITEMPREPAINT|CDDS_SUBITEM:

                *pResult = CDRF_NOTIFYPOSTPAINT | CDRF_NOTIFYSUBITEMDRAW | CDRF_DODEFAULT;

case CDDS_ITEMPREPAINT|CDDS_SUBITEM could be a good place to resize the tool for the tooltip.

First make sure that the tool exists using CToolTipCtrl::GetToolInfo then get the size of the current subitem with ClistCtrl::GetSubItemRect. Then call SetToolRect to change the registered rectangle of the tool.

Tried it… It works!

09 October 2004

Things to read

Optimized ADO.NET
 
 
 
 

08 October 2004

Windows Forms: how to make a form behave like a modeless dialog?

Define a class deriving from Form. Declare it within the form that will be its parent:

          // Site Query window (modeless)

          private SiteQuery siteQuery = null;

When a button of the parent form toolbar is clicked, instantiate, show and activate the form:

          private void siteToolBar_ButtonClick(object sender, System.Windows.Forms.ToolBarButtonClickEventArgs e)

          {

                switch(siteToolBar.Buttons.IndexOf(e.Button))

                {

                      case 0: // Open Site

                            // Check SiteQuery windows exists

                           

                            if (siteQuery == null)

                            {

                                  siteQuery = new SiteQuery();

                            }

 

                            if (!siteQuery.Visible)

                                  siteQuery.Show();

                            siteQuery.Activate();

 

                            break;

 

By default when a form is closed, Form.Dispose() is called which then makes it impossible to call the Show() method. To avoid this, handle the Closing event:

          private void SiteQuery_Closing(object sender, System.ComponentModel.CancelEventArgs e)

          {

                e.Cancel = true;

               

                // Hide the form instead of closing it

                this.Hide();

          }

07 October 2004

Things to read

Building robust middle tier
 
 
 
C++: The Most Powerful Language for .NET Framework Programming
 

04 October 2004

Things to read

IUIs and Web-Style Navigation in Windows Forms, Part 1




IUIs and Web-Style Navigation in Windows Forms, Part 2



Microsoft Inductive User Interface Guidelines

03 October 2004

MFC: modeless dialogs

Had issue with modeless dialogs that did not draw properly. Only the non client part was drawn and the rest was transparent and messy...
Eventually solved the problem by setting the Style property of the dialog template to Popup instead of Child.