MFC Quirks: Part 1

I have been working with MFC to move the shader analysis code so it can be ran with DirectX running in C++. To do this I reimplemented most of what I did in C# in MFC (which I have worked with in the past). 

Since it has been a while since I last worked with MFC I had forgotten a lot of the little quirks and since it seems it is used much less these days than it was 5 years ago trying to scour the internet for the answer to some of the more niggling problems has also became more difficult and some of the sites are simply out of date. Not to mention a few new problems Microsoft has introduced in Visual Studio 2013.

So here is a small overview of little problems and how to avoid them.

DRAW ORDER

The draw order in MFC is by default the order of the creation of the items of the dialog. This can become a pain once you have added many items to the dialog and want to have an older item drawn last.

Unfortunately there isnt an easy solution to this so here is the awkward way. 

Right-click on the dialogs ressource (.rc) file and select "View Code" this will show you the code for the creation of the dialog. That will looks something like this:

IDD_DXMFC_DIALOG DIALOGEX 0, 0, 1031, 475
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "DXMFC"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
SCROLLBAR IDC_SCROLLBAR1,342,0,8,318,SBS_VERT
GROUPBOX"",IDC_STATIC,350,339,108,120
CONTROL "Error Level 0",IDC_ERRORLEVEL0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,458,57,10
CONTROL "Error Level 2",IDC_ERRORLEVEL2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,458,57,10
CONTROL "Error Level 1",IDC_ERRORLEVEL1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,77,458,57,10
CONTROL "Error Level 3",IDC_ERRORLEVEL3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,211,458,57,10
END

So if we want this to draw the "Error Level 3" CONTROL before the GROUPBOX we can simply place the CONTROL before it in the list like this:

IDD_DXMFC_DIALOG DIALOGEX 0, 0, 1031, 475
STYLE DS_SETFONT | DS_MODALFRAME | DS_FIXEDSYS | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
EXSTYLE WS_EX_APPWINDOW
CAPTION "DXMFC"
FONT 8, "MS Shell Dlg", 0, 0, 0x1
BEGIN
SCROLLBAR IDC_SCROLLBAR1,342,0,8,318,SBS_VERT
CONTROL "Error Level 3",IDC_ERRORLEVEL3,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,211,458,57,10
GROUPBOX"",IDC_STATIC,350,339,108,120
CONTROL "Error Level 0",IDC_ERRORLEVEL0,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,9,458,57,10
CONTROL "Error Level 2",IDC_ERRORLEVEL2,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,143,458,57,10
CONTROL "Error Level 1",IDC_ERRORLEVEL1,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,77,458,57,10
END

So now if you save and close that file then run a build you will see that they will now be drawing in the new order.

DIRECTX DIALOG ITEM DRAW ORDER

Now if you are creating a DirectX view in your code you may want it to draw at a different time than when you are creating the CView* derived object. This trick is very similar to the one above. First you create a custom draw MFC object and place it in the dialog where you want your DirectX view to be and set its place in the resource file so that will be called on to draw at the correct time. Now when you come to create your DirectX view give it the HWND of the new custom draw MFC object. All of your drawing will now be done within that box. I find this to be a lot more convenient than creating the object in code as it allows you to scale and position your DirectX view in the design, which is for me a lot more convenient than using code and counting pixels.

NON-UNICODE MFC SUPORT IN VISUAL STUDIO 2013

When developing any project I like to keep everything in either unicode or multibyte because I find mixing just leads to excess code that is prone to mistakes. This is especially true when working with Direct3D's D3DCompile funciton which takes a void* as input for the shader text but will fail without a proper error message if you pass in a unicode string. To avoid this I switched the project into multibyte everywhere. The only problem is that when I transferred over to Visual Studio 2013 this is no longer supported in the MFC libraries. To fix this you have to go to this MSDN page to get an update to enable the standard multibyte functions of MFC. 

NEW LINES IN MFC DIALOGS

A lot of MFC dialogs use the windows new line format of "\r\n" rather only "\n". You will also have to enable the 'Multiline' property on the text box you are using.