If you want to find an item in a tree control (CTreeCtrl from MFC) by its name you need a recursive function. Below is a function that does that. How does it work: you pass the text of the item to search, the tree reference and an item in the tree. The function will search through the sub-tree of that item for a match. If it finds it, it returns the tree item, otherwise NULL. To search the entire tree, pass the root of the tree. If your tree has more than just one root and you want to search the entire tree, you’d have to call it once for each root item.

// name - the name of the item that is searched for
// tree - a reference to the tree control
// hRoot - the handle to the item where the search begins
HTREEITEM FindItem(const CString& name, CTreeCtrl& tree, HTREEITEM hRoot)
{
	// check whether the current item is the searched one
	CString text = tree.GetItemText(hRoot);
	if (text.Compare(name) == 0)
		return hRoot; 

	// get a handle to the first child item
	HTREEITEM hSub = tree.GetChildItem(hRoot);
	// iterate as long a new item is found
	while (hSub)
	{
		// check the children of the current item
		HTREEITEM hFound = FindItem(name, tree, hSub);
		if (hFound)
			return hFound; 

		// get the next sibling of the current item
		hSub = tree.GetNextSiblingItem(hSub);
	} 

	// return NULL if nothing was found
	return NULL;
}

[Update]
To search the entire tree you can use this helper function, which will work regardless how many roots the tree has.

HTREEITEM CTreeDemoDlg::FindItem(const CString& name, CTreeCtrl& tree)
{
   HTREEITEM root = m_tree.GetRootItem();
   while(root != NULL)
   {
      HTREEITEM hFound = FindItem(name, tree, root);
      if (hFound)
         return hFound; 

      root = tree.GetNextSiblingItem(root);
   }

   return NULL;
}
Hits for this post: 13074 .

I was writing today about the movie Pirates of the Caribbeans, naming the post “Pirates at their Worst“. In the meanwhile I found this article on the APC Magazine’s web site, called Romania: a global hotspot for eBay fraud. It reported that the Australian office of eBay has organized a news conference to talk about the frauds commited by Romanians. According to a report from 2006 of the IC3.GOV Internet Crime Complaint Center, Romanian ring crime scammed eBay users for $5,000,000. Out of the sudden, pirats are no longer romantic heroes, looking for adventure, driven by honor and best rolemodels our kids can have.

Mat Henley, of the eBay global fraud investigation team said that:

We discovered that Romania had a huge technology gap between generations. It was enormous: 25-30 year old criminals were some of the brightest people we’ve dealt with, but when you mix in the prosecutors, law enforcement and magistrates, some of them had never been on a computer – period.

To tackle the perpetrators, eBay had to buy computers and digital cameras for the Romanian police and involve US agents working in Romania. The result were “hundreds” of arrests being made, though he refused to give any figures about the actual impact on the internet fraud.

Now, what I have to say about that: yes, Romanians were involved in many frauds, but I doubt that eBay bought computers for the Romanian Police and they made hundreds of arrests in Romania. The news conference was rather a way to make publicity for the company and calm down the unrest among Australian users about frauds on eBay. If you read the report I mentioned above, you’ll see that Romania takes only the 5th place, accounting for only 1.6% of fraud.

Top Ten Countries – Perpetrator
1. United States – 60.9%
2. United Kingdom – 15.9%
3. Nigeria – 5.9%
4. Canada – 5.6%
5. Romania – 1.6%
6. Italy – 1.2%
7. Netherlands – 1.2%
8. Russia– 1.1%
9. Germany – 0.7%
10. South Africa – 0.6%

Most of Romanians operated from countries such as US or UK. I don’t think they had to buy computers to the Police in these countries. So, without a real report from eBay or Romanian Police about the frauds made from Romania, I call the eBay announcements a scam.

And as an interesting thing, I read in the report that:

Pruette is a Romanian national and is currently being held by the Immigration and Naturalization Service. He is believed to be part of a multi-state cell which sends funds to Romania and other countries to support terrorist efforts.

So, according to people that investigate internet crime, Romania might be a terorrist heaven. Let’s only hope that after the Middle East, they won’t focus on us to counter terrorism and bring democracy to the area.

Hits for this post: 8316 .

ATTENTION:  MOVIE SPOILER!

Last night I’ve seen Pirates of the Caribbeans: At World’s End, the last of movie of series and I haven’t been that disappointed in a movie for years. First and foremost it sends the wrong message, especially to children: being pirate is great. In this series the good guys are actually bad, and the bad guys are good. Depicted as romantic heros, the pirats are a symbol of freedom, couraje and honour. They make our kids that see the movies or play with the toys to think like that. They failed to show anything of the true nature of pirates. And then Disney fights media piracy. If you download the movie from the net and don’t buy the original DVD they label you as a media pirate, fight you, and if possible make you pay for it. What a hypocrisy!

As for the movie itself, after the 1 billion sales of the second, they could have hired a better screenwriter. Or an army of them. The screen play was so bad, it almost made me scream. Let me point some things:

  • no explanation on how the monster Kraken died or was killed;
  • no explanation on how the gang led by Elizabeth, Barbosa and Will enters the other realm and Davy Jones’ chest to find Jack Sparrow;
  • in the most intense moment of the action, the cool and calculated Lord Becket cracks and fails to give any command to his man; but on the other hand he climbs down the stairs on his ship while everything explodes around him; yeah, sure;
  • a huge armada of warships runs away from the 9 pirate ships after the English admiral ship is destroyed;
  • Elizabeth and Will accept to live a life of awaiting; and their child waits for his romantic pirate father to come one day every ten years to meet him and his mother; and his so happy about it; proabably a first essential moment in his becoming of a pirate.

In other words, the script really sucked. Pitty for the performing of the actors, which was great, once again.

Hits for this post: 8371 .

You might be interested in this topic if you experienced the following problem:

  • developed your VC++ application with Visual Studio 2005, it worked ok on your computer and when you put it on another it does not run, or
  • your application run both on your machine and other machines (without VS 2005 installed), but after installing SV 2005 SP1 and rebuild, it no longer worked.

Let me start with the first: any application has dependencies on assemblies (DLLs). An MFC application (in a release build) depends at least on the CRT (msvcr80.dll, msvcp80.dll) and MFC (mfc80.dll or mfc80u.dll) assemblies. You have them on your machine because you have VS 2005 installed. But a machine without it, may not have them. In order to be able to run the application on such machines you have to redistribute them (notice you can only redistribute release builds of the assemblies).

Visual C++ 2005 supports a new deployment model for Windows client applications based on isolated applications and side-by-side assemblies. Basically, assemblies can be:

  • shared (they are globally registered in the system, installed in the Global Assembly Cache – GAC folder in Windows – and available to all applications) or
  • side-by-side, described with a manifest, distributed with the application and available only to that application

In Visual C++ 2005, library assemblies (such as MFC, ATL, CRT) have been rebuilt as shared side-by-side assemblies and installed in the native assembly cache, WinSxS folder in Windows. That means they are not globally registered in the system, but are globally available to the applications that specify a dependency with a manifest file.

By default, Visual C++ 2005 builds all native C/C++ applications as isolated applications; such an application is a self-describing one, that uses a manifest file to describe its dependencies. A manifest is an XML file that describes the application and its dependencies.

Such a manifest should have the same name as the application and the extension “manifest” and should specify the version number of your assembly (executable or dynamic library), processor architecture, name of the assembly and platform type; a description of your assembly is also recommended. And example is shown bellow:

< ?xml version='1.0' encoding='UTF-8' standalone='yes'?>
< assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
< assemblyIdentity
  version="1.0.0.0"
  processorArchitecture="X86"
  name="CompanyName.ProductName"
  type="win32"
 /> 

 < description>Description of your application.< /description>

You specify a dependency in the manifest file by adding a dependency element. If you want to specify the use of Win-XP styles for your controls, you need to add a dependency to Microsoft.Windows.Common-Controls:

< ?xml version='1.0' encoding='UTF-8' standalone='yes'?>
< assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
< assemblyIdentity
  version="1.0.0.0"
  processorArchitecture="X86"
  name="CompanyName.ProductName"
  type="win32"
 /> 

 < description>Description of your application.< /description>

< dependency>
  < dependentAssembly>
   < assemblyIdentity
    type="win32"
    name="Microsoft.Windows.Common-Controls"
    version="6.0.0.0"
    processorArchitecture="X86"
    publicKeyToken="6595b64144ccf1df"
    language="*"
   />
  < /dependentAssembly>
 < /dependency>

< /assembly>

Now, going back the to problem: in the first case you either install the Microsoft Visual C++ Redistributable Package on the target machine, so that the assemblies are made available to your application from the WinSxS folder, or you put them in the same folder with your application and use a manifest file to describe the dependencies.

However, you have to notice that if the DLLs are also present in the WinSxS folder, the system will prefer these DLLs to the ones in the same folder with the application. This is different from the folder deployment model, that appear with Windows 2000, when the system first checked the working folder of the application and after that the system folder (system32).

This is one of the causes of the second problems I mentioned above: you developed your application with VC++ 2005, deployed it as I explained above and it worked. But then, after installing VS 2005 SP1 and rebuilding and re-deploying the application no longer worked on the other machines. The root of the problem are the assemblies version: prior to SP1, the assemblies version was 8.0.50727.42. You deployed them on the target machine or had them installed with the redistributable package (downloadable from http://www.microsoft.com/downloads/details.aspx?familyid=32bc1bee-a3f9-4c13-9c99-220b62a191ee&displaylang=en). But after SP1 on your machine a new version was avaiable: 8.0.50727.762. Your new builds now depends on this version of assemblies (CRT, MFC). If you run your application in debugger, you’ll see that the DLLs from WinSxS are loaded:

'testapp.exe': Loaded
'C:WINDOWSWinSxSx86_Microsoft.VC80.DebugMFC_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_257740a4mfc80d.dll', Symbols loaded. 

'testapp.exe': Loaded
'C:WINDOWSWinSxSx86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9fmsvcr80d.dll', Symbols loaded.



The listing shows that MFC80D.dll was loaded from folder x86_Microsoft.VC80.DebugMFC_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_257740a4 in WinSxS and MSVCR80D.dll from x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.762_x-ww_5490cd9f. These are the debug builds for MFC and CRT. The behaviour is the same with the release ones. The name of the folder includes the platform (x86), the assembly name (Microsoft.VC80.DebugMFC, Microsoft.VC80.DebugCRT), the public token (1fc8b3b9a1e18e3b) and the version number (8.0.50727.762). On a machines with VS 2005 SP1 you have both versions 8.0.50727.42 and 8.0.50727.762, but when you redistribute it to one without the later, the application does not run, unless:

As I explained earlier, in case you have the required assemblies both in WinSxS and your application folder, the ones from WinSxS will be loaded. However, there is a workaround for that, as found by Andre Stille: removing the publicKeyToken attribute from the manifest files. For your application manifest that looked like this

< ?xml version='1.0' encoding='UTF-8' standalone='yes'?>
< assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
< assemblyIdentity  version="1.0.0.0"
  processorArchitecture="X86"
  name="CompanyName.ProductName"
  type="win32"
 />
< description>Description of your application.< /description>

< dependency>
    < dependentAssembly>
      < assemblyIdentity
       type='win32'
       name='Microsoft.VC80.CRT'
       version='8.0.50727.762'
       processorArchitecture='x86'
       publicKeyToken='1fc8b3b9a1e18e3b' />
    < /dependentAssembly>
  < /dependency>   

< /assembly>

you have to change it to:

< ?xml version='1.0' encoding='UTF-8' standalone='yes'?>
< assembly xmlns='urn:schemas-microsoft-com:asm.v1' manifestVersion='1.0'>
< assemblyIdentity  version="1.0.0.0"
  processorArchitecture="X86"
  name="CompanyName.ProductName"
  type="win32"
 />
< description>Description of your application.< /description>

< dependency>
    < dependentAssembly>
      < assemblyIdentity
       type='win32'
       name='Microsoft.VC80.CRT'
       version='8.0.50727.762'
       processorArchitecture='x86' />
    < /dependentAssembly>
  < /dependency>   

< /assembly>



Also, the change is necessary for the CRT manifest, that originally looked like this:

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
< assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    < noInheritable>< /noInheritable>
    < assemblyIdentity type="win32"
      name="Microsoft.VC80.CRT"
      version="8.0.50727.762"
      processorArchitecture="x86"
      publicKeyToken="1fc8b3b9a1e18e3b">
    < /assemblyIdentity>
    < file name="msvcr80.dll"
          hash="10f4cb2831f1e9288a73387a8734a8b604e5beaa"
          hashalg="SHA1">
      < asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
          xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        < dsig:Transforms>
          < dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity">
          < /dsig:Transform>
        < /dsig:Transforms>
        < dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
        < /dsig:DigestMethod>
        < dsig:DigestValue>n9On8FItNsK/DmT8UQxu6jYDtWQ=
        < /dsig:DigestValue>
      < /asmv2:hash>
    < /file>
    < file name="msvcp80.dll"
          hash="b2082dfd3009365c5b287448dcb3b4e2158a6d26"
          hashalg="SHA1">
      < asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
          xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        < dsig:Transforms>
          < dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity">
          < /dsig:Transform>
        < /dsig:Transforms>
        < dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
        < /dsig:DigestMethod>
        < dsig:DigestValue>0KJ/VTwP4OUHx98HlIW2AdW1kuY=
        < /dsig:DigestValue>
      < /asmv2:hash>
    < /file>
    < file name="msvcm80.dll"
          hash="542490d0fcf8615c46d0ca487033ccaeb3941f0b"
          hashalg="SHA1">
      < asmv2:hash xmlns:asmv2="urn:schemas-microsoft-com:asm.v2"
          xmlns:dsig="http://www.w3.org/2000/09/xmldsig#">
        < dsig:Transforms>
          < dsig:Transform Algorithm="urn:schemas-microsoft-com:HashTransforms.Identity">
          < /dsig:Transform>
        < /dsig:Transforms>
        < dsig:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1">
        < /dsig:DigestMethod>
        < dsig:DigestValue>YJuB+9Os2oxW4mY+2oC/r8lICZE=
        < /dsig:DigestValue>
      < /asmv2:hash>
    < /file>
< /assembly>



It should be modified to

< ?xml version="1.0" encoding="UTF-8" standalone="yes"?>
< assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
    < noInheritable>
    < assemblyIdentity type="win32"
      name="Microsoft.VC80.CRT"
      version="8.0.50727.762"
      processorArchitecture="x86"
      publicKeyToken="1fc8b3b9a1e18e3b">
    < /assemblyIdentity>

   < file name="msvcr80.dll">< /file>
   < file name="msvcp80.dll">< /file>
   < file name="msvcm80.dll">< /file>
< /assembly>


Hits for this post: 30617 .

The Oxford meeting of the ISO C++ standards committee between 15-20 April resulted in new features beeing into the draft paper of the C++0x standard.

One of the features refer to Unicode support: a new header, called <cuchar>, was introduced. This header makes available new built-in types char16_t and char32_t, as well as new prefixes u and U to designate UTF-16 and UTF-32 encoded characters and strings.

char16_t c16 = u'A'; 

char32_t c32 = U'A';  

char16_t* str16 = u"this is a UTF-16 encoded string";  

char32_t* str32 = U"this is a UTF-32 encoded string";

A list of all papers submited before the Oxford meeting can be found here.

More about the results of the Oxford meeting can be found in:

Hits for this post: 4542 .

The New Your Times has recently published an article called “Google Keeps Tweaking Its Search Engine” about the Google search engine and the people working on it. A reporter from the magazine was allowed to spend a day with Amit Singhal, the mastermind behind the ranking algorithm and his collegues.

As Amit Singhal put it, the search has moved from “give me what I type” to “give me what I want”. For instance, someone typing “apple” is more likely to look for products from the Apple company than information about the fruit. Google uses hungreds of thousands of computers to index the web (basically indexing every single word from every page on the web, as well as compositions of words) and applies thousands of mathematical formulas to provide the best results.

Google uses a system of more than 200 types of information, called signals, to rank pages. Such signals could be words, links, images, history, data patterns extracted from queries. Then these signals are feed into formulas, called classifiers, that are doing the inference of useful information and provide the results. The results must offer a certain degree of diversity, because if one has more perspective the chances to find what is actually looked for are bigger.

Of course, the details about the search engine are the biggest kept secret at Google, but the article really worth reading.

Hits for this post: 3549 .

Monday, June 4, Microsoft announced during the TechEd 2007 conference in Orlando, Florida, that Visual Studio code-named ‘Orcas’ was renamed Visual Studio 2008. They also announced that a second beta version will be available by the end of the summer, and it will include Visual Studio Shell, which allows developers to create an distribute tools built on top of Visual Studio.

Though Microsoft still plans (or hopes) to release it later this year, it is expected to be purchased by most companies and people in 2008, hence the name. Or at least that’s what they said. Personnaly, I think this is a hint that it will only be released at the beginning of 2008. I guess, we will see.

Hits for this post: 6017 .

Recently CodeGuru published the last part of my introductory series of articles on LINQ. Here are the links to the articles:

I hope you’ll enjoy and benefit from the reading.

Hits for this post: 10012 .