Let me explain what you are seeing. First off, a little about the EVENT_SELECTION_CHANGE event on the tree control. If you read the help for this event, you will see that it is fired every time an item is selected OR unselected. The reason for this is that the tree control supports selecting multiple items. If you are holding down CTRL, for example, it will select a new item, without unselecting the previous item (just like in Windows Explorer). Because of this, for normal selecting of items (without CTRL or SHIFT), you will get TWO EVENT_SELECTION_CHANGE events. One for the previous item being unselected, and one for the item you clicked on being selected.
So, that means your program is getting 2 events that are calling this callback. This is the
first part of the problem. The second part is the way you set up the thread lock. When you created the thread lock, you specified that you wanted it to process events while waiting for the lock by passing the constant OPT_TL_PROCESS_EVENTS_WHILE_WAITING to the function. This means that when you call CmtGetLock it will internally be processing events while waiting for the lock. It's kind of like putting a ProcessSystemEvents() in your code at that spot. So, what is happening is, your code is getting to the CmtGetLock function which is internally processing the next event (which is another EVENT_SELECTION_CHANGE), so your callback function gets called again re-entrantly. This means that CmtGetLock gets called again, and now the lock is already held, so it blocks the thread there.
Fun stuff, huh? Anyway, you can easily resolve this by creating you lock to not process messages while waiting with:
CmtNewLock (NULL, 0, &hTestLock);
Or, if you really need it to process mess
ages, you would have to protect your callback from the re-entrant situation using a status flag or something similar.
Best Regards,
Chris Matthews
National Instruments