MFC Support for Direct2D – Part 7: Saving to files

Once have enabled Direct2D support in an MFC application, there is no sweat to load an image from a file, by using one of CD2DBitmap constructors.
Unfortunately, we cannot find a CD2DBitmap method to save it into a image file (something similar to CImage::Save or Gdiplus::Image::Save).
No problem, we can try to do it ourselves. Here is an example:

Create and use a WIC bitmap render target

Looks good although it can be refactorized and/or can be improved for saving multiple frames, metadata and so on. However, it’s a problem: if the Direct2D bitmap (pBitmap) has been created in the window’s render target, EndDraw returns D2DERR_WRONG_RESOURCE_DOMAIN error (the resource was realized on the wrong render target). That is because CWnd::EnableD2DSupport creates a render target of type D2D1_RENDER_TARGET_TYPE_DEFAULT and as stated in the documentation, it cannot share its resources with another render targets. So, let’s replace EnableD2DSupport call with a call to another one (let’s say it EnableD2DSoftwareSupport).

Replace CWnd::EnableD2DSupport

More details can be found in the demo application attached below. Just to note that forcing software rendering for window’s render target leads in performance penalty but generally, we can live with that until finding a better solution. :)

Demo application

The demo application is a simple image viewer using MFC support for Direct2D and WIC to load/save images from/into into files.
DownloadSave Direct2D bitmap in a file - Demo.zip (12)

Resources and related articles

Enumerate WIC Components

In an older article, I presented a function that enumerates Windows Imaging Component codecs. Recently I had the idea to make a set of WIC Interfaces wrapper classes for easily enumerate and get info about all types of WIC components: bitmap decoders and encoders, metadata readers and writers, format converters, and supported pixel formats. Here are just few samples of code.

CComponentEnumT – a template class for enumerating WIC components

CComponentInfoBaseT – base class for all other component info classes

CPixelFormatInfoT – just one of classes getting WIC component info

Just note that, for further easier using, I’ve defined here CPixelFormatInfo, an alias for CPixelFormatInfoT<IWICPixelFormatInfo2>.

CComponentEnumT specializations and aliases

Finally, let’s see how to use these classes!

Enumerating WIC pixel formats

Quite easy, isn’t it?

Get the pixel format info

You can find the complete source code in the attached demo solution.

Demo solution

Download: Enumerate WIC Components - Demo Solution.zip (39)

Enumerate WIC Components - Demo

Enumerate WIC Components – Demo

The demo solution contains an MFC and a console project that use the classes described above in order to enumerate WIC components and get info about each one. The MFC one allows choosing the component type(s) as well as enum options (include the disabled components or enum only Windows built-in components). The console application is simpler and I wrote it just to demonstrate that my little library of wrapper classes can be used both in MFC and non-MFC applications.

Notes

  • I hope, this article can be useful.
  • If you have any observation or remarks, please do not hesitate to post a reply!

Resources and related articles

Three Ways to Find Files

Let’ say we have to implement a function that search a folder to recursively find files having an extension from a given list of extensions. This article shows three possible implementations: one using FindFirstFile and FindNextFile WinAPI functions, one using CFileFind MFC class and one using Filesystem Library.

Find files using FindFirstFile and FindNextFile WinAPI functions

Althugh this implementation uses some ATL stuff to make things easier, it appears still quite complicated.

Find files using CFileFind MFC class

Using CFileFind MFC class can make code a little bit shorter and the programmer’s life easier.

Note: IsStringInListNoCase searches a list for a string, not case sensitive. You can find its implementation in the attached demo solution.

Find files using Filesystem Library

Here it is:

Hurray, we did it in just few lines of code! :)
Of course, it can be used in MFC, ATL, Win32 and Console applications, as well.

Demo solution

The demo solution contains three projects, each having one of the above implementations.
Download: Find Files Samples (Visual Studio 2015).zip (50)

Resources and related articles

MFC Support for Direct2D – Part 6: Composite Effects

We can combine two or more images and/or effects by using the composite effect. Here is an example.

Drawing shadows using Direct2D composite effects

Demo project

Download: Composite Effect Demo.zip (166)
You can set the amount of blur and the color as well as the distance of the shadow.

Composite Effect Demo

Composite Effect Demo

Resources and related articles

MFC Support for DirectWrite – Part 11: About Trimming Again

In a previous article, I showed how to trim a text which overflows the layout box. In the example presented there, the ellipsis is added at the end of truncated text. But if, let’s say, we have to show a long path and file name, it is not meaningful if the file name is not displayed. No problem, this can be easily resolved if have a look at DWRITE_TRIMMING structure which passed to IDWriteTextFormat::SetTrimming. The second parameter is a character code used as delimiter and the third one is the delimiter count. The text is preserved from the end until is found the delimiter which coresponds to delimiter count. For example, if the delimiter is backslash and the delimiter count is 2, a text like “e:\Articles\MFC Support for DirectWrite\DirectWrite Trimming Demo\D2DStaticCtrl.cpp” may be displayed as follows “e:\Articles…\DirectWrite Trimming Demo\D2DStaticCtrl.cpp”.

An example of trimming by using a delimiter

Demo project

Download: DirectWrite Trimming Demo.zip (188)
The demo project is a simple MFC application which demonstrate how to trim text rendered with DirectWrite. You can choose the granularity, the delimiter and the delimiter count and see what is displayed.

DirectWrite Trimming Demo

DirectWrite Trimming Demo

Resources and related articles

Easy Screen Capture with MFC

In an older article published at Codeguru, I showed how easy is to make screen capture using CImage ATL/MFC class. Here is the sample code from that article:

Like a walking in the park. :)  However, it can be made even easier, with fewer lines of code.

Now, let’s add two more methods, one for capturing a given display monitor and one for capture a window.

Demo aplication

Download: Screen Capture Demo.zip (220)
The demo application makes per-monitor capture.

Monitor capture demo

Monitor capture demo

 

Resources and related articles

Double-click in MDI Client

It’s hard to believe that handling mouse double-clicks in MDI Client windows can be super useful, but I found this problem in a discussion forum. I presumed that it was not only for fun, so I tried to resolve it. First, I subclassed the MDI Client window in a CWnd-derived class. That is possible for a standard MFC project in this way:

But no success: WM_LBUTTONDBLCLK message handler is not called in CMDIClientWnd class. Then I tried to catch it in overridden PreTranslateMessage or even in a WH_MOUSE hook with the same result. Finally, I had a look using Spy++ tool. Bingo! The MDI Client (of predefined window class named “MdiClient“) has no CS_DBLCLKS style so it does not deal with mouse double-clicks.

MDIClient

MDIClient

All wat he have to do is to create the The MDI Client window with our own registered window class. This is possible by overriding CMDIFrameWnd::CreateClient.

Create a MDI client window which belongs to a window class having CS_DBLCLKS style

Handle MDI Client double-clicks in standard MFC applications

Once we have created the MDI Client window and subclassed it as shown above, can simply handle (for example) WM_LBUTTONDBLCLK in our CWnd-derived class.

Handle MDI Client double-clicks in Visual Studio or Office-style MFC applications

CMDIFrameWndEx uses its own CWnd-derived class for the MDI Client window, so we cannot use another one in  main frame class. However, this is not so big problem because we can now catch WM_LBUTTONDBLCLK in overridden PreTranslateMessage method.

Or, you can catch it in a WH_MOUSE hook, if think that can be more exciting. :)

Note that creating the MDI Client window in overridden CMDIFrameWnd::CreateClient cand be done in all cases in the same way.

Demo solution

Download: MDI client double-click samples.zip (286)
The sample Visual Studio solution contains two projects: one is a standard MDI application, and the other one is Office-style. Just enjoy of MDI Client double-clicks! :)

Resources and related articles