Archive for the ‘MFC’ Category

Unexpected behavior of Win32 when checking serial ports.

I recently noticed very interesting behavior in ClearCommError() function of Win32.
This code returns how many bytes there are in incoming buffer for a serial port.

DWORD CSerialPort::BytesWaiting()
  //Validate our parameters

  //Check to see how many characters are unread
  COMSTAT stat;
  return stat.cbInQue;

void CSerialPort::GetStatus(COMSTAT& stat)
  //Validate our parameters

  DWORD dwErrors;
  if (!ClearCommError(m_hComm, &dwErrors, &stat))
    DWORD dwLastError = GetLastError();
    TRACE(_T("CSerialPort::GetStatus, Failed in call to ClearCommError, Error:%d\n"), dwLastError);

However, after actually debugging it I found out that there are cases where

  • The number of bytes in its incoming buffer doesn’t increase while it is calling BytesWaiting() to see if it received enough bytes to read. Then, it should read its incoming buffer for the given COM port to have BytesWaiting() starts to return accumulated number of bytes after reading.
  • When BytesWaiting() returns 0, you still need to read the buffer not to fail in detecting any further data arrived from the other side of communication. reading 0 bytes in this case, will cause the BytesWaiting() keeps returning the number of bytes read after that point.

Normally, whether you read or not, callying BytesWaiting() correctly reports the number of bytes in an incoming buffer.
However, if any of those listed above happens, it stops reporting correct number of bytes.

So, this code fails.

int CLensControllerDlg::ReadIncomingPacket(BYTE incomingBuffer[], int numOfBytesToRead, bool *pShouldGiveUp)
     DWORD bytesInReceptionQueue;
     int readNumOfBytes, extraReadNumOfBytes;

     readNumOfBytes = extraReadNumOfBytes = 0;

     // First read
     readNumOfBytes = m_pSerialPort->Read( incomingBuffer, numOfBytesToRead );
     int lengthToReadFurther;
     int secondTryReadLength = 0;

     static int trialCount = 0;

     // Check if it needs to read once more
     if( (incomingBuffer[ 0] == (BYTE) 0x50) &&
           (incomingBuffer[ 1] == (BYTE) 0xAF ))
           lengthToReadFurther = static_cast<int >(incomingBuffer[4]) + 1; // payload length + check sum
            // Read length + 1 more ( 1 is for checksum )

            //!!!!! [1] !!!!!
            // There are cases where bytesInReceptionQueue doesn't have accumulated number of
            // bytes in a reception bufffer.
            while( (bytesInReceptionQueue = m_pSerialPort->BytesWaiting()) < lengthToReadFurther )
                Sleep( 3 ); // 10 msec

                //!!!!! [2] !!!!!
                // So, if the bytesInReceptionQueue doesn't contain the accumulated number of bytes
                // through the iteration, try to read some.
                // Then it will start to work again.
                 if( trialCount > 10 )
                      if( bytesInReceptionQueue > 0 )
                            // Give another chance
                           secondTryReadLength = m_pSerialPort->Read( &incomingBuffer[readNumOfBytes], bytesInReceptionQueue );
                           readNumOfBytes += secondTryReadLength;

                           lengthToReadFurther -= secondTryReadLength;

                           trialCount = 0;

                            // let's see what it happens if try reading for 0 bytes and read further
                           BYTE temp[ 16];
                            int tempReadLength;

                            // bytesInReceptionQueue == 0
                           tempReadLength = m_pSerialPort->Read( &incomingBuffer[readNumOfBytes], bytesInReceptionQueue );
                           readNumOfBytes += tempReadLength;
                           lengthToReadFurther -= tempReadLength;

                            //// Once read, somehow, bytesInReceptionQueue starts to be accumulated again.
                            //bytesInReceptionQueue = m_pSerialPort->BytesWaiting();

                            //tempReadLength = m_pSerialPort->Read( &incomingBuffer[readNumOfBytes], bytesInReceptionQueue );
                            //readNumOfBytes += tempReadLength;
                            //lengthToReadFurther -= tempReadLength;

                           CString msgString;
                           msgString.Format( _T( ">> Will give up this incoming data : %x %x %x %x %x\r\n"),
                                                  incomingBuffer[0], incomingBuffer[1 ],
                                                  incomingBuffer[2], incomingBuffer[3 ],
                                                  incomingBuffer[4] );

                           WriteLogMessage( msgString );
                           TRACE( msgString );

                            if( pShouldGiveUp != NULL )
                                *pShouldGiveUp = true;

                           trialCount = 0;
                            return 0;

            // In the queue, now there are lengthToReadFurther or more to read.
           extraReadNumOfBytes = m_pSerialPort->Read( &incomingBuffer[readNumOfBytes], lengthToReadFurther );

     return (readNumOfBytes + extraReadNumOfBytes);

The code above was written while I was debugging. So, it’s not clean nor compact.
So, here is better version if you want to see.

int CLensControllerDlg::ReadIncomingPacket(BYTE incomingBuffer[], int numOfBytesToRead, bool *pShouldGiveUp)
     DWORD bytesInReceptionQueue;
     int readNumOfBytes, extraReadNumOfBytes;

     readNumOfBytes = extraReadNumOfBytes = 0;

     // First read
     readNumOfBytes = m_pSerialPort->Read( incomingBuffer, numOfBytesToRead );
     int lengthToReadFurther;
     int secondTryReadNumOfBytes = 0;

     // Check if it needs to read once more
     if( (incomingBuffer[0] == (BYTE)0x50) &&
          (incomingBuffer[1] == (BYTE)0xAF ))
          lengthToReadFurther = static_cast<int>(incomingBuffer[4]) + 1; // payload length + check sum
          // Read length + 1 more ( 1 is for checksum )
          while( lengthToReadFurther > 0 )
               Sleep( 1 ); // 10 msec

               bytesInReceptionQueue = m_pSerialPort->BytesWaiting();

               // If it's normal, just waiting until bytesInReceptionQueue >= lengthToReadFurther,
               // and read the whole "lengthToReadFurther" amount of data all at once.
               // However, sometimes the inbound buffer should be read to have further data accumulated.
               // If not,
               secondTryReadNumOfBytes = m_pSerialPort->Read( &incomingBuffer[readNumOfBytes], lengthToReadFurther );
               readNumOfBytes += secondTryReadNumOfBytes;

               lengthToReadFurther -= secondTryReadNumOfBytes;

     return readNumOfBytes;

CCheckListbox and item height

Well, MFC shows its age.

Although many fairly new programmers, who started to write code after the year 2000, think MFC is old, but in 90’s it was not.
It’s not as elegant as Cocoa or even new .NET ( with C#. .NET for C++ looks like too much overloaded truck with redundant stuffs on it. ).
However, it solves problems for its generation, and there was good reason for MS people to take such design.

However, they had to renovate it. There are many issues like control vs. view for similar components, inconsistent way to deal with widgets, etc.
Today I found a problem with item height for CCheckListBox. With VS resource editor, you can change “font size” of a dialog box or a window. What it actually does is not to change font size for widgets on them.

font size( I think it’s also a problem. What it actually does is to change “scale” of the coordinate system on that dialog box or window. Because the scale is changed, everything like button size is also changed as well as font size. So, it’s not right to name the property “Font(Size)”. )

Problem is that when an instance of CCheckListbox is instantiated and items are added to that, it checks whether each item height is bigger than its minimum size like this. ( Please focus on the last line. )

void CCheckListBox::DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct)
  // You must override DrawItem and MeasureItem for LBS_OWNERDRAWVARIABLE

  CDC* pDC = CDC::FromHandle(lpDrawItemStruct->hDC);

  if (((LONG)(lpDrawItemStruct->itemID) >= 0) &&
    (lpDrawItemStruct->itemAction & (ODA_DRAWENTIRE | ODA_SELECT)))
    int cyItem = GetItemHeight(lpDrawItemStruct->itemID);
    BOOL fDisabled = !IsWindowEnabled() || !IsEnabled(lpDrawItemStruct->itemID);

    COLORREF newTextColor = fDisabled ?
      RGB(0x80, 0x80, 0x80) : GetSysColor(COLOR_WINDOWTEXT);  // light gray
    COLORREF oldTextColor = pDC->SetTextColor(newTextColor);

    COLORREF newBkColor = GetSysColor(COLOR_WINDOW);
    COLORREF oldBkColor = pDC->SetBkColor(newBkColor);

    if (newTextColor == newBkColor)
      newTextColor = RGB(0xC0, 0xC0, 0xC0);   // dark gray

    if (!fDisabled && ((lpDrawItemStruct->itemState & ODS_SELECTED) != 0))

    if (m_cyText == 0)
      VERIFY(cyItem >= CalcMinimumItemHeight());

It turned out that cyItem, which is height of an interested item at that moment, is less than the minimum height if the font size is set to 12.
So, MFC is not updated to work with its visual resource editor or vice versa.
At least there should be some property to choose item height based on chosen “Font size” on the visual editor. If the code for MFC presents relevant error message when debugging, it can be even better.

Anyway, if you set the item height using SetItemHeight() sufficiently, its debugger will not complain again. This is not documented in the section for CCheckListBox at all.

We complain that Apple let Mac OS X and its Cocoa framework behind due to its focus on iOS. ( kernel is the same on the both and Cocoa is almost same to CocoaTouch, but still.. ) However, Apple people keep updating their tool set to work properly with their framework. MS doesn’t seem to be considerate on this long-lived-but-dependable MFC framework. Yes, model-wise, .NET is better. But I often notice that .NET with C++ is too bloated and .NET with C# is too weak. For native environment, MS doesn’t have new framework to replace MFC for C++.
Nowadays, it doesn’t seem to me that there are many S/W engineers working with MFC/C++. So, probably they don’t ask much to MS. Well, in the world of Web app, Java and C#, where people usually justify “computers are getting faster. So, bytecode/VM language like C#/Java are OK.”. I think it’s understandable argument. But still it’s not sufficient to me. It’s like to use 486 computers with the speed of 386 computers. For convenience of using and learning a language, MS gave up many things in C#/.NET, which can be done more easily with C++/MFC/Win32.

How much complete a framework can be : MS vs. Apple

As a person who major in CS, I have interest in fundamental technology or techniques like compilers, OS, 3D graphics, computer vision, parallel systems & distributed systems. So, one of the reason I started to work with 3 major OSes, i.e. Windows, Unix and Mac, and have had lots of interest in their architectural design. Therefore I like to work with different frameworks and compare their design or philosophy behind them.

I think OS architecture is like a whole picture, while frameworks are each part of the OSes. What architectural design an OS has is reflected to its frameworks. When overall architecture design affect how they work, how their components are related one another and so on, frameworks for them should be designed as such. This is one of the reason I think Apple should have filed with OS architectures than their visual UI design against MS and Google.

Here, I would like to show the very difference between .NET and Cocoa. If you have followed ToolBox API and Win32/MFC, you will see similarity between Apple’s and MS’s. Also, there are similarity between Cocoa and .NET. I think it is because Objective-C/Cocoa is in the SmallTalk camp which test OOP concept in academia and geared toward SE, while C++ is in Simula camp which is more for real industry field. Because C++ is for more real field, it should have been compromised with many restriction like CPU speed etc. Also the C++ has been evolved for everything for all people. So, although C++ was introduced as THE OOP language, it has many different concept like meta programming, ad-hoc polymorphism. Also, because of that it also contains its syntax which became somewhat bad and some concept got to have many semantics. (e.g. extern vs. static ) C# is not too different from C++ in that. Although MS streamlined C# from C++. (actually C# was influenced more by Java at first. But as its name suggests it has the face of C++. # in its name is somewhat amusing. When they call it, don’t forget that it is called “sharp” rather than “pound”. # in musical notation is half higher than a note it is attached too. So, C# is C++ in that sense. ) I can feel those philosophy to be all for all from C#.
However, Objective-C and Cocoa was evolved to be focused to increase productivity. So, when using Objective-C and Cocoa, you naturally become to focus on core logic rather than “how to achieve that”. Objective-C is more simple and Cocoa is designed to be very intuitive and powerful.

OK. Let’s see how Objective-C/Cocoa achieves “GUI code on main thread”.

- (IBAction)doInThread:(id)sender
    [NSThread detachNewThreadSelector:@selector(doSomethingMethod:)
                             toTarget:self withObject:nil];

// Thread method
- (void)doSomethingMethod:(id)object
    // Calls appendLogMessage: on main thread
    [self performSelector:@selector(appendLogMessage:)
                 onThread:[NSThread mainThread]
               withObject:@"Do something..."

- (void)appendLogMessage:(NSString *)messageString
    NSTextStorage *textStorage = [m_logBoxView textStorage];
    NSUInteger theLastPos = [textStorage length];

    [m_logBoxView setSelectedRange:NSMakeRange( theLastPos, 0 )];

    [m_logBoxView insertText:[NSString stringWithFormat:@"%@\n",

It’s very intuitive. (Don’t confuse with that you don’t understand Obj-C code. Once you get used to it, it is very easy and straightforward. ) The appendLogMessage: is written just like a normal message/method.

Now, let’s check how it looks in C#/.NET.

#region MSDN way
private void m_doSomethingButton_Click(object sender,EventArgs e)
    m_choreThread = new Thread(new ThreadStart(this.StartThreadLoop));

    m_choreThread.Name = "MSDN Thread";

// Thread method
private void StartThreadLoop()
    // This is a thread loop
    int i = 0;

    while (i < 10)
        // 1. Call WriteLogMessage()
        this.WriteLogMessage(String.Format("Do chores hard!!! {0} from {1}", i, m_choreThread.Name));



// 2. Visit this in the non-main thread space
// 5. Visit this in the main thread space
private void WriteLogMessage(string msgString)
    // 3. If it is still in the context of a non-main thread
    if (m_logTextBox.InvokeRequired)
        WriteLogMessageCallback writeLogMessageDelegate = new WriteLogMessageCallback(WriteLogMessage);

        // 4. Invoke in its main thread space
        this.Invoke(writeLogMessageDelegate, new object[] { msgString });
        // 6. Call this in the main thread space.
        m_logTextBox.AppendText(msgString + Environment.NewLine);

I commented how things are visited in the C#/.NET case to help your understanding. So, to you, who use the framework, .NET case prevent you from concentrating on the main logic. In other words, you should know how things work in C#/.NET.

One of the virtue of OOP is data hiding and encapsulation. Although it says “Data Hiding”, it’s not only about “Data” but also “how it works internally.” C#/.NET fails in this area seriously as you can see. In other words, you should be aware of in which thread context the WriteLogMessage() is called and the method should be implemented with that knowledge.
Compared to that, messages in Objective-C/Cocoa can be written just like usual messages.

Then, are they really different? Couldn’t MS make their .NET framework as elegant as Cocoa? No. I don’t think so. It looks to me that Cocoa’s underlying code could be similar to that of .NET. The difference is that how much Apple people refined their framework by considering people who actually use their framework and design the framework to let people to focus on their own logic not on how Apple implemented this and that.

Then, let’s try to make it look similar to that of Objective-C/Cocoa.

#region Cocoa Way
private void m_doSomethinginCocoaWayButton_Click(object sender, EventArgs e)
    WriteLogMessage2(Environment.NewLine + "----------------------------" + Environment.NewLine);
    m_choreThread = new Thread(new ThreadStart(this.StartThreadLoop2));
    m_choreThread.Name = "Cocoa Thread";

private void StartThreadLoop2()
    // This is a thread loop
    int i = 0;

    WriteLogMessageCallback writeLogMessageDelegate = new WriteLogMessageCallback(WriteLogMessage2);

    while (i < 10)
                                 new object[] { String.Format("Do chores hard!!! {0} from {1}", i, m_choreThread.Name) } );



private void performOnMainThread( WriteLogMessageCallback methodToInvoke, object[] parameter )
    if (m_logTextBox.InvokeRequired)
        this.Invoke(methodToInvoke, parameter);

private void WriteLogMessage2(string msgString)
    m_logTextBox.AppendText(msgString + Environment.NewLine);


Don’t bother with the method name “performOnMainThread“. It’s not our interest. Whatever the name is, it doesn’t matter. What we need to focus on here is the pattern of how WriteLogMessage2() is called.
Also, additionally assume that Object class in .NET framework, which all classes are inherited from, contains the performOnMainThread(). Then like Cocoa, you can ask an object to invoke a given method on main thread. Then you, as a application program developer, can write the method to be invoked without worrying about knowing how those invoke system works.

Similar things happens with timer invocation. If you want to invoke a message at certain intervals in Cocoa, the code is very straightforward and very clean. However, in Win32/MFC case, the OnTimer() handler should check what timer triggers this timer event. In this case, it looks to me that Apple people utilizes signals and events. (Signal is so-called H/W events while event is called S/W event, if you want to be specific about the terms. ) I will not show sample code for that here.

Point here is that the level of refinement is higher on Apple’s. Cocoa framework is designed for SE more in mind, while MFC/.NET are more about “Let’s put this on the market as quickly as possible.” Good news is that.NET is more similar to Cocoa than their previous frameworks, because NeXT showed a future a while ago and MS looked to adopted that.

I always wonder why MS simply adopted Objective-C/Cocoa for their platform development. Well, C#.NET was a kind of a gun toward Java and MS languages can share the same .NET framework. So, there is slight difference, but even with Objective-C/Cocoa, there is a language bind. Well.. it’s true that people should make their own Cocoa equivalent.. yeah.. that can be the major issue to MS.
( Well.. I know that not choosing Obj-C/Cocoa or OpenStep by MS was also due to market situation, marketing, etc, but here I would like to focus on technical side. )

I wonder how F-Script people and Ruby Cocoa people bridged their language to Cocoa. (Script Bridging tech.. )

Silverlight와 WPF의 미래

이번 글은, 요새 글들이 그렇긴 하지만, 소스 코드 하나 없고, 이쪽 S/W 산업의 동향을 생각해 보는 것이어서, HotPotato 블로그로 옮겼다.

Silverlight와 WPF의 미래



CreateEx() and Create() for CDockablePane

Historically CreateEx() has been thought as Create() with additional functionality like more styles.
So, if you take a look at many MFC classes which provide CreateEx() and Create(), you can see that CreateEx() calls Create() and do more chores to provide added functionality.

However, I found out that CDockablePane’s doesn’t.
Although MSDN document shows that there is CreateEx() for CDockablePane, it actually doesn’t exist.
So, you shouldn’t be fooled by the MSDN document and create CDockablePane with CreateEx() and wonder why it doesn’t work.

How to put CFormView on CDockableView

At StackOverflow, there is an inquiry,
How can I place a MFC CFormView inside a CDockablePane?

It is very popular question on the net. Try searching “CFormView on CDockablePane”, “How to put CFormView in CDockableView”, “CView on CDockableView” and so on. ( If CView can be on CDockablePane, CFormView can be too, because CFormView is a child class of CView. )
However I didn’t find anyone who was successful in doing so.

CDockablePane is part of MFC Feature Pack. Although MS distributes it as a part of Visual Studio Service Pack 1, but it was not made by MS. It was made by BCGsoft. I think the author did quite amazing job. However, as he said in the forum, it doesn’t support hosting of CView and its derivatives. One of the reason is said to be routing of window message. If you check all the CDockablePane related classes and all the panes on Visual Studio carefully, you will notice that all the widget on CDockablePane are controls not views.

(This is significant difference between Cocoa and MFC. With Cocoa NSView derivatives can be on any NSWindow/NSView. Actually NSView is derivative of NSWindow on Mac and vice versa on iPhone.

However on Windows, CView and its derivatives are not designed to be on CDialog and so on. So, that is why there are separate CView derivatives like CEditView, CListView, CRichEditView, CFormView, CHtmlEditView, CHtmlView, CTreeView and controls like CEdit, CListCtrl, CTreeCtrl. On dialog boxes, CView derivatives are not supposed to be put.

On Mac, on the other hand, any NSView derivatives can be put on any window and any NSView derivatives. Although NSOutlineView ( or whatever ) which contains a tree controller inside can be seen like the relationship between CListView and CListCtrl, but they are totally different. You use CListCtrl to put it on a dialog box, while you can make a new document window or some window as CListView with its own frame window. Also C*View utilizes the document template architecture, while *Ctrl don’t. However, on a Mac, to use tree control, COutlineView is used instead of its tree control. You can make your own view using the tree control, but if you want to use them as they are, you don’t need to handle the controls directly.

This makes GUI programming very easy on Mac. Very flexible, very powerful and very clean source codes are what you get.

In Cocoa Head LA, I was asked by others why I thought Mac was better than Windows. I would like to explain all this kind of things, but I couldn’t. First, I’m not good at casual talking in English. Second, they are subtle, so I couldn’t think of good example on MFC and Cocoa to compare. Once I run into this kind of issue, I can say “Ah.. this is it!”.

There is another good thing on Cocoa. With Interface Builder, you can see the containment of views visually. You will know how stressful to check someone else’s code which deals with GUI element connected as parent-child relationship a lot and to figure out what causes malfunctioning of the code. )

Anyway, lets go back to original topic.
However, it doesn’t mean that you CANNOT put CView derivatives on CDockablePane.

Here is how to.

For CMainFrame

int CMainFrame::OnCreate(LPCREATESTRUCT lpCreateStruct)
	if (CMDIFrameWndEx::OnCreate(lpCreateStruct) == -1)
		return -1;

	// enable Visual Studio 2005 style docking window behavior
	// enable Visual Studio 2005 style docking window auto-hide behavior

	// create docking windows
	if (!CreateDockingWindows())
		TRACE0("Failed to create docking windows\n");
		return -1;

	// JongAm
	m_myFormViewPane.EnableDocking( CBRS_ALIGN_ANY );
	DockPane( &m_myFormViewPane );

	return 0;

BOOL CMainFrame::CreateDockingWindows()
	BOOL bNameValid;

	// JongAm
	// Create MyFormViewPane

	CString strMyFormViewPane;
	bNameValid = strMyFormViewPane.LoadStringW( IDS_MYFORMVIEW_PANE );
	ASSERT( strMyFormViewPane );
	if( !m_myFormViewPane.Create( strMyFormViewPane, this, CRect( 0, 0, 205, 157 ), TRUE,
		TRACE0( "Failed to create My Form View Pane" );
		return -1;


	return TRUE;

Now for the Dockable pane

: m_pMyFormView(NULL)

int CDockableFormViewPane::OnCreate(LPCREATESTRUCT lpCreateStruct)
	if (CDockablePane::OnCreate(lpCreateStruct) == -1)
		return -1;

	// TODO:  Add your specialized creation code here

	m_pMyFormView = CMyFormView::CreateOne(this);

	return 0;

void CDockableFormViewPane::OnSize(UINT nType, int cx, int cy)
	CDockablePane::OnSize(nType, cx, cy);

	// TODO: Add your message handler code here

	if( m_pMyFormView )
		m_pMyFormView-&gt;SetWindowPos( NULL, 0, 0, cx, cy, SWP_NOZORDER );

And finally for CFormView

void CMyFormView::OnInitialUpdate()

	// TODO: Add your specialized code here and/or call the base class
	SetScrollSizes( MM_TEXT, CSize( 205, 157 ) );


CMyFormView *CMyFormView::CreateOne( CWnd *pParent )
	CMyFormView *pFormView = new CMyFormView;
	//CMyFormView *pFormView = NULL;
	//CRuntimeClass *pRuntimeClass = RUNTIME_CLASS(CMyFormView);
	//pFormView = (CMyFormView *)pRuntimeClass->CreateObject();

	CDockableFormViewAppDoc *pDoc = CDockableFormViewAppDoc::CreateOne();
	pFormView->m_pDocument = pDoc;

	CCreateContext *pContext = NULL;

#if 0
	if( !pFormView->CreateEx(0, NULL, NULL, WS_CHILD | WS_VISIBLE, CRect(0,0,205,157),
		pParent, -1, pContext ) )
	if (!pFormView->Create(NULL, NULL, WS_CHILD | WS_VISIBLE, CRect(0, 0, 205, 157), pParent, 0, pContext))
	//if( !pFormView->CreateEx( 0, AfxRegisterWndClass(0, 0, 0, 0), NULL,
	//	WS_CHILD | WS_VISIBLE, CRect( 0, 0, 205, 157), pParent, -1, pContext) )
		AfxMessageBox( _T("Failed in creating CMyFormView") );


	return pFormView;

int CMyFormView::OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message)
	// TODO: Add your message handler code here and/or call default

	int nResult = 0;

	CFrameWnd* pParentFrame = GetParentFrame();

	if( pParentFrame == pDesktopWnd )
		// When this is docked
		nResult = CFormView::OnMouseActivate(pDesktopWnd, nHitTest, message);
		// When this is not docked

		BOOL isMiniFrameWnd = pDesktopWnd->IsKindOf( RUNTIME_CLASS( CMiniFrameWnd ) );
		BOOL isPaneFrameWnd = pDesktopWnd->IsKindOf( RUNTIME_CLASS( CPaneFrameWnd ) );
		BOOL isMultiPaneFrameWnd = pDesktopWnd->IsKindOf( RUNTIME_CLASS( CMultiPaneFrameWnd ) );

		// pDesktopWnd is the frame window for CDockablePane

		nResult = CWnd::OnMouseActivate( pDesktopWnd, nHitTest, message );

		//nResult = CWnd::OnMouseActivate( pDesktopWnd, nHitTest, message );
		//if( nResult == MA_NOACTIVATE || nResult == MA_NOACTIVATEANDEAT )
		//	return nResult;

		//if (pDesktopWnd != NULL)
		//	// either re-activate the current view, or set this view to be active
		//	//CView* pView = pDesktopWnd->GetActiveView();
		//	//HWND hWndFocus = ::GetFocus();
		//	//if (pView == this &&
		//	//	m_hWnd != hWndFocus && !::IsChild(m_hWnd, hWndFocus))
		//	//{
		//	//	// re-activate this view
		//	//	OnActivateView(TRUE, this, this);
		//	//}
		//	//else
		//	//{
		//	//	// activate this view
		//	//	pDesktopWnd->SetActiveView(this);
		//	//}

	return nResult;

However, as the author of MFC Feature Pack mentioned, there are many issues about windows message routing. For example, OnMouseActivate() should be customized to prevent crash when you click a mouse button when the dockable pane on which CFormView resides is floating. Also, if the View on the dockable pane has more complicated structure like CSplitView, which contains multiple GUI widget which are needed to be updated to refresh their content, it becomes very complicated.

Currently I try to solve such problems.
However, here I at least showed how to put CFormView/View on CDockablePane. I hope this can save many people’s time to investigate how to solve this issue.

ADDED : Because one guy asked me how to implement the CreateOne() member function, I added it above and its header file here.

#pragma once

// CMyFormView form view

class CDockableFormViewAppDoc;

class CMyFormView : public CFormView

	CMyFormView();           // protected constructor used by dynamic creation
	virtual ~CMyFormView();

	static CMyFormView *CreateOne( CWnd *pParent );

	// return associated document
	CDockableFormViewAppDoc * GetDocument(void);

#ifdef _DEBUG
	virtual void AssertValid() const;
#ifndef _WIN32_WCE
	virtual void Dump(CDumpContext& dc) const;

	virtual void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support

	// points to linked document
	CDockableFormViewAppDoc *m_pDocument;

	virtual void OnInitialUpdate();
	afx_msg int OnMouseActivate(CWnd* pDesktopWnd, UINT nHitTest, UINT message);
	afx_msg void OnSizing(UINT fwSide, LPRECT pRect);

Sources :

Storing a pointer value in a non-pointer variable vs. Storing general value in a pointer variable : INT_PTR, LONG_PTR etc vs. MAKEINTRESOURCE

If you are a programmer who studied C/C++ after Windows 95, you may not know the existence of windows data types like INT_PTR, LONG_PTR, because you don’t really need to use it.

So, when you have a chance to port legacy codes to x64 platform, you may  fail in considering proper porting of variables declared with those or variables which don’t use them but semantically means the same.

At StackOverFlow, there is good explanation on this subject.


However, I would like to add more comment.

During MS DOS era, many programmers wrote codes in a way that the longest data type available on his/her machine to store addresses or pointer values. There were a little reason for that. For example, you want to do somewhat mathematical calculation with addresses without bordering with the width of the data type.
To me, it has been always better to calculate on addresses with the width of data type in mind, but there are some other cases you should have disregard the width of data type and just calculate something. It was kind of high technique for doing something weird. ( Some can be, while others are not. )

Some Windows API functions and member functions still require to use such convention. They ask you to pass address value to a variable which is not pointer variables. For that purpose, they use *_PTR.

So, I noticed that not a few programmers, who don’t know history, tended to fail in porting legacy code to x64.

Also, there is opposite example.
This time, it is to store non-pointer value to a pointer variable. Such an example is MAKEINTRESOURCE() macro.


So, it takes an integer number for a resource like resource ID for a bitmap or an icon, and converts it to pointer to string (LPTSTR).

So, if you are one of new guys who don’t know its history, just get familiar with this and don’t be puzzled!

LoadLibrary() can’t load a DLL, and have no clue why?

How do you link or load a DLL file?
My approach is to link a stub *.lib file to a host project. This approach supports best of dynamic load and static load. In other words, each DLL files can be maintained independently, while it is very easy to figure out what functions are not found properly and what functions are in conflict, etc.

However, if you really want to write a host program which can support plug-ins such that each plug-ins can be dropped in a given folder and the host program recognize the plug-in on the fly and starts to provide functionality defined in the plug-ins, you will want more dynamic approach.

Yes. MFC/Win32 provides such approach. With LoadLibrary(), anywhere in your source codes, DLL files can be loaded. Then you can define some common interface/parent class for pluggable architecture.
Neat, isn’t it?
However, there is one problem with LoadLibrary(). It can be difficult to troubleshoot. For example, if your DLL file can’t be loaded, you will check if the search path is correct, if the DLL file is really there, and so on. However, what if all those which affect visibility of the DLL are satisfied but the LoadLibrary() still fails?

Let’s take a look at such codes here.

// JongAm
// Let's try loading "Mediabase.dll". Why the hell WBMediabase started failing in finding the dll?

// Enable the line below to see what is wrong with LoadLibrary()
//SetErrorMode( 0 );

HMODULE dynamicLibrary_Handle = LoadLibrary( _T("MediaBase.dll") );

if( dynamicLibrary_Handle )
	AfxMessageBox( _T("Successful in finding Mediabase.dll") );
	TRACE( "Successful\n" );
	int lastError = GetLastError();

	CString message;
	message.Format( _T("Failed in finding Mediabase.dll (%d)"), lastError );
	AfxMessageBox( message );

	TRACE( "Can't find the mediabase.dll\n" );

Nothing special, right? However, it failed on me. Why? Later I found out that MediaBase.dll also required other DLL files, and those DLL files also require other DLLs. They are all loaded using LoadLibrary() functions. So, they were not detected with Dependency Walker. Hmmmm….
So, whenever you write LoadLibrary(), it is better to provide some feedback message when it fails loading DLL files like “Failed in loading Blah Blah.dll”.

However, what if you already have a few 3rd parth DLL files which you can’t control?
In such case, there is a really handy diagnosis function. It is the SetErrorMode(). If 0 is passed as its parameter, it will display a message box which tells what is wrong, like “X.dll is missing”.
So, for example, when you load a A.dll using LoadLibrary() but the A.dll also load A-1.dll and the A-1.dll loads A-2.dll and the A-2.dll is missing, the SetErrorMode(0) will make a message box which says “A-2.dll is missing” displayed.

Here are a few screenshots.

When a DLL file required by the designated Mediabase.dll is missing

When the designated DLL file, Mediabase.dll, itself can't be found.

When all DLL file dependency are resolved

Wow.. quite helpful, isn’t it?

About BOOL, BOOLEAN and bool on Windows

Well, this was what I wondered when I used MFC/Win32 a lot when I was a sophormore. Why are there so many boolean type on Windows? And why did people at MS made such many boolean type? Well, actually they are not new. They are just alias of int and char, or BYTE.

In C, there was no native BOOL type. C++ added boolean for this. During the days of C, people tened to define an alias for boolean type using typedef and mapped it to int or char.

However, for MFC and Win32, why are there BOOL and BOOLEAN? I found explanation for them long time ago. However, now I forgot it. So, I searched it again.
Here is a good explanation from MS’s blog.


Well.. for C#, they made another one, bool. ( glad that it is same to C++ bool. )

Ah.. Microsoft….

MFC problems

There are a few subjects I would like to write about MFC and would like to compare Cocoa and MFC. I know that it is not fair to compare Cocoa and MFC, because MFC was designed at the time of ToolBox of System x. However, Cocoa was also designed at almost similar time at NeXT.
However, ToolBox and MFC was based on programming model of the past, while the NeXT API was designed with newer ideas at that time. Currently Cocoa is more comparable to .NET framework. As I compared ( unexpectedly ) at my previous blog “What Apple Inc. didn’t tell you”, there are similarities between Cocoa and .NET.
I also suggest .NET framework to Windows programmers who want to taste Cocoa to figure out how it will be like.

Anyway, in this post, I would like to talk about a problem with MFC among many problems.

Let’s take a look at LVCOLUMN structure, which is used for representing columns for CListCtrl.

typedef struct _LVCOLUMN { 
    UINT mask; 
    int fmt; 
    int cx; 
    LPTSTR pszText; 
    int cchTextMax; 
    int iSubItem; 
#if (_WIN32_IE >= 0x0300)
    int iImage;
    int iOrder;
#if (_WIN32_WINNT >= 0x0600)
    int cxMin;
    int cxDefault;
    int cxIdeal;

As you can see, the first member variable is “mask”. Then let’s take a look at the second one, fmt.

Alignment of the column header and the subitem text in the column. The alignment of the leftmost column is always left-justified; it cannot be changed. This member can be one of the following values:

Text is left-aligned.
Text is right-aligned.
Text is centered.
A bitmask used to select those bits of fmt that control field justification. To check the format of a column, use a logical “and” to combine LCFMT_JUSTIFYMASK with fmt. You can then use a switch statement to determine whether the LVCFMT_LEFT, LVCFMT_RIGHT, or LVCFMT_CENTER bits are set.

What is LVCFMT_JUSTIFYFYMASK? It is ANDed with LVCFMT_LEFT/RIGHT/CENTER to set those alignment setting.
Hmmm… Why is there another mask bit set here? Isn’t the 1st member variable is for masks?
Like this, here and there in MFC, there are some confusing part or illogically designed parts.

Also, although this is another aspect of MFC, it doesn’t provide easy way to work with controls. For example, instead of calling CListCtrl’s method to add, delete items and columns, it utilizes messages. You need to send messages to controls to manipulate them. Some controls don’t work like this. What I want to say is that the architecture of MFC is somewhat awkward and not designed for ease of use, which is very different from Cocoa and .NET.

When I was a university student, I found out that may other CSE student had difficulty in using MFC framework. I think it is not coincidence.
Probably MS architects at MS knew about this problem and they decided to make a new framework by hiring Borland people to adopt their Form-based and property programming paradigm.

%d bloggers like this: