In perioada 6-8 aprilie va avea loc la Bucuresti la sediul Uzinexport un training de Introducere in .NET, sponsorizat de Microsoft Romania. Dupa cum explica Zoli pe blogul sau, acest training este

dedicat programatorilor începatori, juniorilor din firmele de software, programatorilor de FoxPro, Visual Basic, Java, dar si programatorilor care nu au reusit sa treaca de primele versiuni de .NET (1.0, 1.1…). Sunt bineveniti si programatorii de aplicatii web, care dezvolta în PHP, Ruby, Python, Perl etc, si care vor sa se familiarizeze in ASP.NET, Silverlight si restul platformei Microsoft.

Subiectele tratate in curs vor fi:

  • Programarea Orientata Obiect (OOP) cu C#
  • Platforma .NET
  • Limbajul C#
  • Programarea web cu ASP.NET
  • Programare vizuala
  • ADO.NET si acces la date
  • SQL Server si elemente de Business Intelligence
  • Dezvoltarea de servicii web si elemente de SOA
  • Programare pe SharePoint
  • Programare pe Windows Mobile
  • Dezvoltarea de Rich Internet Applications (RIA) cu Silverlight
  • Dezvoltarea de aplicatii compatibile cu Windows 7 si Windows Vista

Cursul fiind sponsorizat de Microsoft Romania, taxa de participare este de doar 150lei (lei noi, include TVA).

Informatii detaliate despre acest eveniment gasiti pe blog-ul lui Zoli.

, , , , Hits for this post: 15316 .

On March 28, turn off lights for one hour starting at 20:30. This way you can tell the world leaders they have to take real action against the global warming and climate changes.

This year, Earth Hour has been transformed into the world’s first global election, between Earth and global warming. For the first time in history, people of all ages, nationalities, race and background have the opportunity to use their light switch as their vote – Switching off your lights is a vote for Earth, or leaving them on is a vote for global warming. WWF are urging the world to VOTE EARTH and reach the target of 1 billion votes, which will be presented to world leaders at the Global Climate Change Conference in Copenhagen 2009. This meeting will determine official government policies to take action against global warming, which will replace the Kyoto Protocol. It is the chance for the people of the world to make their voice heard.

You can find all the details about this campaign at www.voteearth2009.org and www.earthhour.org.

Sign up for Earth Hour! - I VOTE EARTH: Marius Bancila

   Earth Hour 2009 by WWF – Sign up for Earth Hour!

Be one of the one billion people to turn off lights on March 28!

, , Hits for this post: 6767 .

The new MFC library from Visual Studo 2010 supports another Vista specific feature, the task dialog. This is meant as a replacement for the classic dialog box, and can display command links, customized buttons, customized icons, and a footer.

Here is an example of such a dialog (from Windows Server 2008).

MFC contains a new class called CTaskDialog that implements the task dialog. You must include afxtaskdialog.h in your files to be able to use it. Since the task dialog is available only on Vista or newer versions (Server 2003, Server 2008, Windows 7) you must check whether you can use it or not. For that the class CTaskDialog provides a static method called IsSupported() that returns true if the task dialog is available on the running operating system. In addition, the task dialog is only available when you build for UNICODE.

The code below shows how to create and display the task dialog from the previous image.

void CTasksDemoDlg::OnBnClickedButtonTasks1()
{
   CString strMessage("Do you want to save your changes to the document?");
   CString strDialogTitle("Save document");
   CString strMainInstruction("Save document options");

   CString expandedLabel("Hide extra information");
   CString collapsedLabel("Show extra information");
   CString expansionInfo("You can select to save your document either as XML or binary. You should prefer to save as XML as this is the new standard format.");

   if (CTaskDialog::IsSupported())
   {
      CTaskDialog taskDialog(strMessage, strMainInstruction, strDialogTitle, TDCBF_OK_BUTTON);
      taskDialog.SetMainIcon(TD_INFORMATION_ICON);

      taskDialog.SetCommonButtons(TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON);
      taskDialog.LoadCommandControls(IDS_SAVE_OPTION1, IDS_SAVE_OPTION2);
      taskDialog.SetExpansionArea(expansionInfo, collapsedLabel, expandedLabel);
      taskDialog.SetFooterText(L"Note: If you don't chose to save your changes will be lost.");
      taskDialog.SetVerificationCheckboxText(L"Remember your selection");

      INT_PTR result = taskDialog.DoModal();

      if (taskDialog.GetVerificationCheckboxState() )
      {
         // PROCESS IF the user selects the verification checkbox
      }

      switch (result)
      {
         case IDS_SAVE_OPTION1:
            AfxMessageBox(L"You chose to save as XML");
            break;
         case IDS_SAVE_OPTION2:
            AfxMessageBox(L"You chose to save as binary");
            break;
         case IDNO:
            AfxMessageBox(L"You chose not to save");
            break;
         case IDCANCEL:
            AfxMessageBox(L"You chose to cancel");
            break;
         default:
            // this case should not be hit
            ASSERT(FALSE);
            break;
      }

   }
   else
   {
      AfxMessageBox(strMessage);
   }
}

In this sample IDS_SAVE_OPTION1 (“Save in XML based format”) and IDS_SAVE_OPTION2 (“Save in binary format (old version)”) are two strings defined in the string table from the Resource editor.

There are several predefined icons in commctrl.h that can be used as the main icon.

#define TD_WARNING_ICON         MAKEINTRESOURCEW(-1)
#define TD_ERROR_ICON           MAKEINTRESOURCEW(-2)
#define TD_INFORMATION_ICON     MAKEINTRESOURCEW(-3)
#define TD_SHIELD_ICON          MAKEINTRESOURCEW(-4)

The following flags for default buttons are defined in the same header:

enum _TASKDIALOG_COMMON_BUTTON_FLAGS
{
    TDCBF_OK_BUTTON            = 0x0001, // selected control return value IDOK
    TDCBF_YES_BUTTON           = 0x0002, // selected control return value IDYES
    TDCBF_NO_BUTTON            = 0x0004, // selected control return value IDNO
    TDCBF_CANCEL_BUTTON        = 0x0008, // selected control return value IDCANCEL
    TDCBF_RETRY_BUTTON         = 0x0010, // selected control return value IDRETRY
    TDCBF_CLOSE_BUTTON         = 0x0020  // selected control return value IDCLOSE
};
typedef int TASKDIALOG_COMMON_BUTTON_FLAGS;

An easier way to create a task dialog, but with fewer customization options is using the static method ShowDialog() from CTaskDialog. The following example displays a dialog similar to the first one.

void CTasksDemoDlg::OnBnClickedButtonTasks2()
{
   HRESULT result2 = CTaskDialog::ShowDialog(
      L"Do you want to save your changes to the document?",
      L"Save document options",
      L"Save document",
      IDS_SAVE_OPTION1,
      IDS_SAVE_OPTION2,
      TDCBF_NO_BUTTON | TDCBF_CANCEL_BUTTON,
      TDF_ENABLE_HYPERLINKS | TDF_USE_COMMAND_LINKS,
      L"Note: If you don't chose to save your changes will be lost.");
}

, , Hits for this post: 25617 .

One of the new features available in MFC in the Visual Studio 2010 CTP is the Restart Manager. This was introduced with Windows Vista to offer support for restarting application when a crash occurs or when an automatic update needs to close and then restart an application.

When you create a new MFC project in Visual Studio 2010, in the Advanced Features property page you can specify the level of support you want for the restart manager.

You can select one of the following:

  • Support Restart Manager: restarts after crash or upgrade
  • Reopen previously open documents: reopens previously open documents
  • Support application recovery: recovers auto saved documents

There are three flags defined for these three options:

  • AFX_RESTART_MANAGER_SUPPORT_RESTART for Support Restart Manager
  • AFX_RESTART_MANAGER_SUPPORT_RESTART_ASPECTS for Reopen previously open documents
  • AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS for Support application recovery

These are defined in the afxwin.h header.

// Restart Manager support flags
#define AFX_RESTART_MANAGER_SUPPORT_RESTART           0x01  // restart support, means application is registered via RegisterApplicationRestart
#define AFX_RESTART_MANAGER_SUPPORT_RECOVERY          0x02  // recovery support, means application is registered via RegisterApplicationRecoveryCallback
#define AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART       0x04  // auto-save support is enabled, documents will be autosaved at restart by restart manager
#define AFX_RESTART_MANAGER_AUTOSAVE_AT_INTERVAL      0x08  // auto-save support is enabled, documents will be autosaved periodically for crash recovery
#define AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES     0x10  // reopen of previously opened documents is enabled, on restart all previous documents will be opened
#define AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES   0x20  // restoration of auto-saved documents is enabled, on restart user will be prompted to open auto-saved documents intead of last saved
#define AFX_RESTART_MANAGER_SUPPORT_NO_AUTOSAVE       AFX_RESTART_MANAGER_SUPPORT_RESTART |
                                                      AFX_RESTART_MANAGER_SUPPORT_RECOVERY |
                                                      AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES
#define AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS       AFX_RESTART_MANAGER_SUPPORT_NO_AUTOSAVE |
                                                      AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART |
                                                      AFX_RESTART_MANAGER_AUTOSAVE_AT_INTERVAL |
                                                      AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES
#define AFX_RESTART_MANAGER_SUPPORT_RESTART_ASPECTS   AFX_RESTART_MANAGER_SUPPORT_RESTART |
                                                      AFX_RESTART_MANAGER_AUTOSAVE_AT_RESTART |
                                                      AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES |
                                                      AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES
#define AFX_RESTART_MANAGER_SUPPORT_RECOVERY_ASPECTS  AFX_RESTART_MANAGER_SUPPORT_RECOVERY |
                                                      AFX_RESTART_MANAGER_AUTOSAVE_AT_INTERVAL |
                                                      AFX_RESTART_MANAGER_REOPEN_PREVIOUS_FILES |
                                                      AFX_RESTART_MANAGER_RESTORE_AUTOSAVED_FILES

Enabling this support is done with a single line in the constructor of the CWinAppEx derived class.

CRecoveryDemoApp::CRecoveryDemoApp()
{
	m_bHiColorIcons = TRUE;

	// support Restart Manager
	m_dwRestartManagerSupportFlags = AFX_RESTART_MANAGER_SUPPORT_ALL_ASPECTS;

	// TODO: add construction code here,
	// Place all significant initialization in InitInstance
}

Here is an application with the full support for restart enabled. There are two opened documents, one that is saved (on the left) and one that is not saved (on the right).

When I hit the crash button, the application uses a null pointer and crashes.

Now, when I press the Ignore button of the crash report window, I get the restart manager window tha allows me to Restart the program.

The restart manager will attempt to restart the program and reopen my documents, which it successfully does.

However, you can see that though the support for recovering auto saved documents was enabled, the second, unsaved document was not recovered. The reason was that this document was not auto saved, because the default interval for the auto save is 5 minutes and I crashed the program immediatelly after writing into the document. This default interval can be changed by calling the SetAutosaveInterval() method of the data recovery handler. In the following example I change this interval to one minute.

BOOL CRecoveryDemoApp::InitInstance()
{
   // ...

   CDataRecoveryHandler* autohandler = AfxGetApp()->GetDataRecoveryHandler();
   autohandler->SetAutosaveInterval(60000);

   return TRUE;
}

Here is another instance of the application with the first document saved, and the second not directly saved, but auto saved after one minute of inactivity.

When the application restarts, because there was an auto saved document that can be recovered, a new window is displayed.

If I choose Recover the auto-saved documents my unsaved (but auto saved) document is recovered.

These options for restarting the application and saving and loading the application data (documents) are exposed through virtual methods in the CWinAppEx class.

virtual void PreLoadState() {}    // called before anything is loaded
virtual void LoadCustomState() {} // called after everything is loaded
virtual void PreSaveState() {}    // called before anything is saved
virtual void SaveCustomState() {} // called after everything is saved

You can override these methods in your application for custom handling of the save and load operations.

To learn more about this new feature I suggest you read the Visual C++ team’s blog.

, , Hits for this post: 21423 .

One of the new features in .NET 4.0 is the BigInteger class. This was suppose to be part of 3.5 framework, but after the CTP it was gone. Now it’s back. This big integer is a really large integer representation. However, I was not able to find the precision documented anywhere.

The class is available in the System.Numerics namespace and provides overloaded operators, parsing methods and other utility features for bit integer numbers.

Not very long ago, on codexpert.ro we launched a contest for finding the biggest pair of amicable numbers. One of the members (crystyce) that submited a solution found this big pair (2724918040393706557785752240819405848576, 2724918040396184856306258038787235905536) with a C++ implementation using a 3rd party BigInt class. I decided to put that in C# 4.0 and use BigInteger. Maybe you can find things to optimize in the below code, but that’s not the point here. I’m showing you this code just to get a feeling of BitInteger.

using System.Numerics;

namespace cs_test
{
   static class Amicable
   {
      public static BigInteger Pow2(BigInteger exp)
      {
         BigInteger res = 1;

         for (BigInteger i = 0; i < exp; i++)
            res *= 2;

         return res;
      }

      public static BigInteger ExpMod(BigInteger value, BigInteger exp, BigInteger mod)
      {
         BigInteger ullResult = 1;
         BigInteger ullValue = value;

         while (exp > 0)
         {
            if (exp % 2 != 0)
            { // odd
               ullResult *= ullValue;
               ullResult %= mod;
            }

            ullValue *= ullValue;
            ullValue %= mod;
            exp /= 2;
         }

         return (ullResult);
      }

      static public bool IsMillerRabinPrime(BigInteger prime)
      {
         // randomWitness = witness that the "prime" is NOT composite
         // 1 < randomWitness < prime-1
         long totalWitness = 15;
         BigInteger [] randomWitness = { 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 51001, 351011};
         BigInteger primeMinusOne = prime - 1;
         BigInteger oddMultiplier;
         long bitLength;
         long i, j;
         BigInteger result;
         // find oddMultiplier, defined as "prime - 1 = (2^B) * M"
         // get bitLength (B) and find the oddMultiplier (M)

         // init value multiplier
         oddMultiplier = primeMinusOne;

         bitLength = 0; // reset
         while(oddMultiplier % 2 == 0)
         {
            oddMultiplier /= 2;
            bitLength++;
         }
         for(i = 0; i < totalWitness; i++)
         {
            if (randomWitness[i] == prime)
               return true;

            // init value of result = (randomWitness ^ oddMultiplier) mod prime
            result = ExpMod(randomWitness[i], oddMultiplier, prime);

            // is y = 1 ?
            if(result == 1)
               continue; // maybe prime

            // is y = prime-1 ?
            if(result == primeMinusOne)
               continue; // maybe prime

            // loop to get AT LEAST one "result = primeMinusOne"
            for(j = 1; j <= bitLength; j++)
            {
               // square of result
               result = ExpMod(result, 2, prime);

               // is result = primeMinusOne ?
               if(result == primeMinusOne)
                  break; // maybe prime
            }

            if(result != primeMinusOne)
               return false; // COMPOSITE
         }

         // it may be pseudoprime/prime
         return true;
      }

   }

   class Program
   {
      const int STARTM = 1;
      const int STOPM = 100;
      const int STOPN = 30;

      static void Main(string[] args)
      {
         DateTime start = DateTime.Now;

         for (BigInteger m = STARTM ; m <= STOPM ; m++)
         {
            for (BigInteger n = m+1 ; n <= m+STOPN ; n++)
            {
               BigInteger p = Amicable.Pow2(n) + Amicable.Pow2(m) - 1;
               if (!Amicable.IsMillerRabinPrime(p)) continue;

               BigInteger q = Amicable.Pow2(2 * n - m) + Amicable.Pow2(n) - 1;
               if (!Amicable.IsMillerRabinPrime(q)) continue;

               BigInteger r = Amicable.Pow2(3 * n - m) +
                              Amicable.Pow2(n + m) +
                              Amicable.Pow2(2 * n + 1) - 1;
               if (!Amicable.IsMillerRabinPrime(r)) continue;

               BigInteger f1 = Amicable.Pow2(n) * p * q;
               BigInteger f2 = Amicable.Pow2(n) * r;

               DateTime end = DateTime.Now;
               Console.WriteLine(
                  "{2} ... {0}, {1}",
                  f1,
                  f2,
                  (end - start).Milliseconds / 1000.0);
            }
         }
      }
   }
}
0.017 ... 220, 284
0.021 ... 2172649216, 2181168896
0.028 ... 17296, 18416
0.040 ... 9363584, 9437056
0.138 ... 2.7249180403937065577857522408E+39, 2.7249180403961848563062580388E+39

As you can see, it was very fast finding the same big pair. Well it was at least on my 2 core machine.

The only thing I don't understand about the implementation is the presence of some helper functions in the BigInteger class.

public static BigInteger Abs(BigInteger value);
public static BigInteger Add(BigInteger left, BigInteger right);
public static BigInteger GreatestCommonDivisor(BigInteger left, BigInteger right);
public static BigInteger Divide(BigInteger dividend, BigInteger divisor);
public static BigInteger DivRem(BigInteger dividend, BigInteger divisor, out BigInteger remainder);
public static double Log(BigInteger value);
public static double Log(BigInteger value, double baseValue);
public static double Log10(BigInteger value);
public static BigInteger Max(BigInteger left, BigInteger right);
public static BigInteger Min(BigInteger left, BigInteger right);
public static BigInteger ModPow(BigInteger value, BigInteger exponent, BigInteger modulus);
public static BigInteger Multiply(BigInteger left, BigInteger right);
public static BigInteger Negate(BigInteger value);
public static BigInteger Pow(BigInteger value, int exponent);
public static BigInteger Remainder(BigInteger dividend, BigInteger divisor);
public static BigInteger Subtract(BigInteger left, BigInteger right);

That belongs to System.Math, or maybe to a System.Numerics.Math class. They are all helper functions, not specific to the implementation of the big integer; and the implementation does not depend on the existing of these functions. So they are clearly utility functions. They should go somewhere else. I have submitted this as feedback to Microsoft Connect. If you agree with it, vote for it here. Of course, if you have arguments for the current implementation, you can vote against it too.

, , , Hits for this post: 11481 .

The MVP Global Summit 2009 is talking place between 1 -4 March in Seattle and Redmond. Its going to be over 700 sessions during these 4 days. Last two years it was really good and it will probably be the same this time too. I’ll be mostly focused on sessions with the Visual C++ team about the new features in Visual Studio 2010.

We are seven MVPs from Romania. Here is a picture from yesterday dinner.

, , Hits for this post: 18959 .