Posts Tagged ‘Visual C++’

Fast Open… for Visual Studio 2005/2008

When there are a lot of files in a project, it is pretty hard to find where the file is. In such case, I desperately wanted to have Xcode’s Fast Open… feature for Visual Studio 2005/2008.

So, while finding some plugins for Visual Studio, I found one tip.

What you should do is to type

>of [file name]

in the Find field.

Even intellisense works there!

Why MFC is bad

Well, MFC has lots of weird aspects. Basically MFC is a framework. What is a framework? Framework is a wrapper of API to make the API easier to use.
However, when MFC is compared to ToolBox which was most popular during similar period of time, MFC is not as easy to use as ToolBox. ToolBox is, however, API not framework.

Here I would like to show one example why MFC is bad and why its design is bad. Let’s think about CListCtrl. It is a list control or table control if you think of it in the context of Mac OS X. What do you want to do with it?
Let’s summarize some of them.

  • Populate ClistCtrl
  • Retrieve row item or column data
  • Change properties like text color, background color, font and so on for row items.
  • Customizing the UI
  • and so on

First, to manipulate the data or to populate the CListCtrl, this class itself doesn’t provide consistency. Why am I talking about consistency? Let’s take a look at CStatic or CEdit. On Windows, you can set a control variable for them or data variable for them. A control variable is like :

CEdit *editBox

, while data variable is like :

CString editBoxString

To manipulate the value itself, data variable is easier. However to control the widget itself, you should use the control value.
With Cocoa, you don’t need to have this separate mechanism. In Windows point of view, it is like to declare CEdit variable and the CEdit class provides all the methods to manipulate the data value. Or with Cocoa binding, things can be done much more easily.

It does not mean that it is impossible to manipulate data with the control variable. With some widget, or control, it is not easy or is not possible at all.

Here, with CListCtrl, there is no “data” variable unlike that of CEdit or CStatic. So, you should manipulate the data with the CListCtrl itself. So, there is no consistency.

Second, it is very difficult to retrieve row item or data.
GetItem() is for that, but if you look up MSDN document for it, it is not clear how to retrieve an item you want.
Here is explanation on what it does.

Retrieves some or all of a list view item’s attributes.

The LVITEM structure specifies or receives the attributes of a list view item.

However, it doesn’t say about how to do so.

There is something which is even worse.
Let’s take a look at the LVITEM parameter.
What is lParam? What does it supposed to contain? There is no explanation about it in MSDN document.

Let’s assume that you want to customize the CListCtrl. You want to set a bold font for a specific row item or column. Does CListCtrl provide such method? No. Also, there is no each way to retrieve ith item on a CListCtrl. Among them, one easy thing is to set a text color or a background color of a item. Well.. how to to so? There is no explanation about it.
Well.. you can implement a message handler for WM_CUSTOMDRAW message. However the MFC document for CListCtrl doesn’t even contain link for the message. You should look up Win32 document. Isn’t it strange? Framework is a wrapper for API to make API easy to use. However, For MFC, if you want to do some common thing like this, the API, or Win32, should be revealed.

Third. Let’s think about a situation in which you want to set a bold font for some items. There seems to be no way to do so.
Creating a CListCtrl Class with Item Style Features (CListCtrlStyled Class) from CodeGuru introduces a customized CListCtrl clas to do that.

Let’s take a look at some source codes from the class.

void CListCtrlStyled::SetItemStyle(int nItem,int nSubItem,DWORD Style,bool redraw)
{
	// We must retrieve the Style info structure of this item
	//
	LVITEM pItem;
	InitLVITEM(nItem,0,&pItem);

	LS_item * lpLS_item = NULL;
	lpLS_item = (LS_item*) pItem.lParam;

	if(nSubItem > 0)
		lpLS_item = lpLS_item->subitems[ nSubItem - 1];

	// no we can update the style
	//
	lpLS_item->StyleFlag = Style;

	DWORD mask = LIS_BOLD | LIS_ITALIC | LIS_UNDERLINE| LIS_STROKE ;
	lpLS_item->in_use = (Style & mask) > 0;

	// if any font exist for this item then delete it
	//
	this->Free_LS_font(lpLS_item);

	// Redraw it
	if(redraw)	CListCtrl::Update(nItem);
}

void CListCtrlStyled::InitLVITEM(int nItem,int nSubItem,LVITEM * pItem)
{ /*
  typedef struct _LV_ITEM {
    UINT   mask;         // see below
    int    iItem;        // see below
    int    iSubItem;     // see below
    UINT   state;        // see below
    UINT   stateMask;    // see below
    LPSTR  pszText;      // see below
    int    cchTextMax;   // see below
    int    iImage;       // see below
    LPARAM lParam;       // 32-bit value to associate with item
   } LV_ITEM;
  */
	pItem->mask = LVIF_PARAM;
	pItem->iItem = nItem;
	pItem->iSubItem = nSubItem;
	pItem->state = NULL;
	pItem->stateMask = NULL;
	pItem->pszText = NULL;
	pItem->cchTextMax = NULL;
	pItem->iImage = NULL;
	pItem->lParam = NULL;
	CListCtrl::GetItem(pItem);
}

In InitLVITEM() method, it calls GetItem(). What it does is to retrieve lParam value in LVITEM. Then in SetItemStyle(), it calls :

	LS_item * lpLS_item = NULL;
	lpLS_item = (LS_item*) pItem.lParam;

	if(nSubItem > 0)
		lpLS_item = lpLS_item->subitems[ nSubItem - 1];

Hmm.. lpLS_item is once set to lParam. And it is set to lParam’s subitems[].
Then based on the value, it tries modify the variable to set a font face.
To do this, you should know that what the lParam means and the data structure lParam contains. Also, you need to know howdata structure its subitems[] looks like.

But where is explanation on them is? I can’t find anything on MSDN.

There are a lot of things in MFC like this.
Classes are not prepared to handle things easily, and its MFC documentation doesn’t have any link or explanation.

I don’t understand why MS doesn’t provide good documentation about its classes. The bad design of MFC can be understood if we consider when it was designed. However, if MFC designer at MS still want to keep the MFC for native environment, they should do something about it.

Visual C++ 2008 resource editing and control variable annoyance

Hmmm.. It was strange that VC++ 2008 add variables wizard didn’t let a “value” variable of a radio button. With VC++ 6, it was possible as far as I remember.

So, I searched to find out what changed since VC++ 6.

What I found are :

However, the most official document is :
Grouping Radio Buttons on a Dialog Box

People are confused by the different way of setting variable for a radio button to they way you do with its previous version, and MS didn’t seem to present “What is changed and How is changed” document.

So, the way it manipulate resources was changed. No, problem. However again MS’s approach shows problems.

  1. In the resource editor, there is no way to group radio boxes visually
  2. Because only one radio buttons is to be turned on exclusively in its group, there should be a visual way to make a series of radio buttons grouped. However, a group is defined by setting the order of radio buttons in series and only the first radio button is flagged as “Group”.

  3. Setting only the first radio button as “Grouped” is not reasonable.
  4. Basically there are multiple radio buttons in a group. Then all should be “grouped”. But MS want you to set only the 1st radio button as “grouped”. Then all the following radio buttons are grouped. It doesn’t feel natural.

  5. Setting the variable to the first radio button
  6. So, a variable for a group should be declared for the group. But a variable for the 1st button is declared and treated like that it is the representative button for the group.

All of them don’t look natural and reasonable.

I think this is why people get confused and couldn’t get a clue on how to make set a variable for radio buttons.

TerminateThread() and its consequence (Windows)

Usually when it is required to quit a thread from outside of its thread function, you declare a variable like shouldQuit, and it checks if the shouldQuit is set inside of the thread function. From outside of the thread function, you set the shouldQuit to tell the thread to quit.

However, if a function in a DLL is called inside of the thread function, and somehow it stucks in the DLL function, the thread function even can’t check whether the shouldQuit is set or not. Eventually, the DLL function may return, but in that case, it is abnormal. Then.. what can you do?
You don’t want to wait until it returns.

Then you are tempted to use TerminateThread() function.
However, MSDN warns its use. Let’s quick test what can happen.

// The one and only application object
CWinApp theApp;

using namespace std;

CEvent g_threadTerminatedEvent;
bool g_shouldStop;

UINT __cdecl myThreadFunc( LPVOID pParam );
void SetThreadName( DWORD dwThreadID, char* threadName);

int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
	int nRetCode = 0;

	// initialize MFC and print and error on failure
	if (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
	{
		// TODO: change error code to suit your needs
		_tprintf(_T("Fatal Error: MFC initialization failed\n"));
		nRetCode = 1;
	}
	else
	{
		// TODO: code your application's behavior here.
		g_shouldStop = false;

		CWinThread *pThread = AfxBeginThread( myThreadFunc, NULL );
		HANDLE handleForThread = pThread->m_hThread;
		DWORD threadID = pThread->m_nThreadID;

		SetThreadName( threadID, "My Thread!");

		BOOL isSuccessful;
		DWORD exitCode, error;
		isSuccessful = GetExitCodeThread( handleForThread, &exitCode );
		if( !isSuccessful )
		{
			error = GetLastError();
		}

		DWORD result;
		Sleep( 10000 );
		
		//g_shouldStop = true;
		//result = WaitForSingleObject( g_threadTerminatedEvent, INFINITE );
		//switch( result )
		//{
		//case WAIT_OBJECT_0 :
		//	_tprintf(_T("Thread quits.\n" ));
		//	break;

		//case WAIT_ABANDONED :
		//case WAIT_TIMEOUT :
		//default :
		//	break;
		//}

		// Force quit
		isSuccessful = TerminateThread( handleForThread, exitCode );
		if( !isSuccessful )
		{
			error = GetLastError();
		}

		Sleep(5000);
		_tprintf(_T("Hmm.. is finished?\n") );
	}

	return nRetCode;
}

UINT __cdecl myThreadFunc( LPVOID pParam )
{
	int i = 0;
	while( !g_shouldStop )
	{
		_tprintf(_T("[%3d] Thread is running.\n"), (i++)%1000  );
	}

	_tprintf(_T("Bye bye...\n" ));

	g_threadTerminatedEvent.SetEvent();

	return TRUE;
}

#define MS_VC_EXCEPTION 0x406D1388

#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
   DWORD dwType; // Must be 0x1000.
   LPCSTR szName; // Pointer to name (in user addr space).
   DWORD dwThreadID; // Thread ID (-1=caller thread).
   DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)

void SetThreadName( DWORD dwThreadID, char* threadName)
{
   Sleep(10);
   THREADNAME_INFO info;
   info.dwType = 0x1000;
   info.szName = threadName;
   info.dwThreadID = dwThreadID;
   info.dwFlags = 0;

   __try
   {
      RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   }
}

Then when the TerminateThread() is called, the myThreadFunc thread is terminated. However, its main function is finished and the program itself is stucked.
Take a look at this.
force_quit

If you go ahead by hitting F5, you will have this problem.
error

I think it is better not to use TerminateThread() as MSDN suggests.
However, what if you should use it, but knows that this problem happens in advance?
Does anyone know how to solve this problem?

Setting a name to a thread (MSDN)

It is pretty hard to identify threads when you debug codes.
So, for the Visual C++, MSDN says there is a way to set a name to a thread.
Here is the codes from MSDN.

//
// Usage: SetThreadName (-1, "MainThread");
//
#include <windows.h>
#define MS_VC_EXCEPTION 0x406D1388

#pragma pack(push,8)
typedef struct tagTHREADNAME_INFO
{
   DWORD dwType; // Must be 0x1000.
   LPCSTR szName; // Pointer to name (in user addr space).
   DWORD dwThreadID; // Thread ID (-1=caller thread).
   DWORD dwFlags; // Reserved for future use, must be zero.
} THREADNAME_INFO;
#pragma pack(pop)

void SetThreadName( DWORD dwThreadID, char* threadName)
{
   Sleep(10);
   THREADNAME_INFO info;
   info.dwType = 0x1000;
   info.szName = threadName;
   info.dwThreadID = dwThreadID;
   info.dwFlags = 0;

   __try
   {
      RaiseException( MS_VC_EXCEPTION, 0, sizeof(info)/sizeof(ULONG_PTR), (ULONG_PTR*)&info );
   }
   __except(EXCEPTION_EXECUTE_HANDLER)
   {
   }
}

Inconsistent GUI programming of Visual Studio

    The Visual C++ 6.0 has existed for long time compared to unfortunate Visual Studio .NET 2003. The 2000 versin changed a lot in respect to GUI and it introduced .NET. The 2005 version was somewhat stabilized, and 2008 version looks to continue its tendency.

    With this Visual Studio products, there are some problems. They are :

  1. GUI was changed too much.
  2. Approach in respect to GUI programming is not consistent

    The GUI was changed too much. Visual C++ 6.0 provided easy approach for dynamic data exchange on its class view dialog box. You could select what messages would be handled by a selected class on the same dialog box.

    2003 version was changed a lot, so adoption rate was not good.
From 2005 version, things were streamlined well. However there are still lots of difference.

    For example, does the 2005/2008 version provide a way to set up window message handler? It is pretty difficult to find it.
But here it is.

Inconsistent_VC

After selecting a class, open its property pane. Then you can find where you can set up message handlers.

    Second, the way to add / modify event handler is different.
At least adding one is same.

EventHandler

    However, to browse existing event handler, you cannot double click a button. As far as I remember, Visual C++ 6.0 allowed it, existing event handler was opened.
Also, most importantly, the way to add message handler and event handler are very different. Why classes like dialog is in resource file to be represented visually and thus provides a way to add event handler by clicking, while those for views are not visually represented in resource file and its message handler can’t be added/modified by clicking?
This is very important inconsistency.

    So, for .NET, MS introduced “form” programming, whcih is property programming. With property programming paradigm, setting properties, or class member variable, is enough to set up things, e.g. fonts, etc. Also, view classes in .NET framework are also visualized in its resource file.
This was originally pushed by Borland. As far as I know, MS hired a Borland programmer to implement “form programming” paradigm for Visual Studio.

    Because this difference, it is confusing to prepare code with VS from time to time. However, thanks to .NET framework, programming for Windows feels similar to that for Mac nowadays. For last two years, I tried .NET programming. It was quite easy to learn it and found out that .NET classes and its approach is very similar to that of Cocoa/Objective-C.
So, I decided that I could easily start writing in .NET. So, I kept focusing on MFC.

    By the way, I couldn’t decide whether to post this to my Hot Potato blog or here, but this is more about development. So I decided to post it here.

How to prepare a target windows machine for debugging : Windows Side by Side Assemblies

With the Visual C++ 2005, MS introduced very weird entities to relieve the DLL hell. It is called Windows Side by Side Assemblies of Windows SxS.

However, it gives you another headache. It is like to bring foxes to expel tigers. It is very annoying to set-up target machine for debugging. If you have only one target machine, there is no such headache. But while you are at work, you would have many target machines at your software quality assurance team.

However, the MSDN doesn’t provide short and easy explanation how to setup debug version of their SxS. Many articles at the MSDN contains just vague explanation or something that does not really matter.

Especially, the last one is the most important article. However, it doesn’t really explain what is supposed to do clearly.

Instead, I would like to show how to prepare target machines for debugging.

Here is the step.

  1. Copy debug SxS to target machine’s directory where your program to be debugged is copied to.

That’s it!

Then what files/directories to copy?
which_folder_to_copy

Copy those to where your program to be debugged is.
preparing-sxs-fordebugging

%d bloggers like this: