January 2007 - Posts

Gordon Hogenson on C++/CLI

I read a lot of books but with my day job and various other projects and writing commitments I don’t have a lot of spare time. As a result I am very picky about what books I read and especially technical books since there are so many mediocre technical books out there.

Well recently Gordon Hogenson sent me a copy of his new C++/CLI book and considering that he is responsible for Visual C++ documentation at Microsoft I decided to read it. It is called “C++/CLI: The Visual C++ Language for .NET”.

This is the first book that I have come across that is dedicated to C++/CLI and it is rock solid. If you are a C++ developer wanting to take advantage of managed code then this is the book for you. If you are a C# developer wanting a bit more flexibility and power at the systems level then this is the book for you. Not only does it cover C++/CLI in detail, Gordon as it turns out is a very good writer and he made it a very enjoyable book to read.

To be clear, this is not a book about Visual C++. Rather, it is focused on C++/CLI, the language that the Visual C++ compiler offers for supporting the .NET Framework and targeting the Common Language Runtime in particular.

The book also includes a great "Quick Reference" appendix that is vital as you start using C++/CLI for the first time.

Get your copy now from Amazon or a bookstore near you.


© 2007 Kenny Kerr 

Posted by KennyKerr with 1 comment(s)

Recovering a Window’s Alpha Channel

Ian Griffiths who convinced me to add the window transparency features to Window Clippings writes about calculating the alpha channel for a window. Ian does a good job of explaining the theory behind the calculations.


© 2007 Kenny Kerr 

Posted by KennyKerr with no comments

Why doesn’t Kenny Kerr work for Microsoft?

Chris Sells posted a comment to my Controls and the Desktop Window Manager article that read:

I give up -- why don't you work at Microsoft? Want to?

Before I could respond, my wife chimed in with quite a revealing comment. Read that first.

I had always dreamt of ideally working on one of three teams: Visual C++, COM (now Distributed Systems Group), or Windows. I would have been happy with almost any group, as Microsoft is known for smart people, great products and challenging technology.

It started when the Visual C++ team approached me about a position as a program manager. I did the phone screen and flew to Redmond for a long day hanging out with the Visual C++ team. It was one of the most enjoyable (and exhausting) experiences I have ever had. It also included two overnight flights across the continent in the span of two days. Shortly after that, I heard that they wanted to offer me the job but were waiting on the lawyers. I then stopped hearing from the recruiter and when I finally inquired, he told me that I do not qualify for a US work permit since I am not university educated.

Quite a few teams at Microsoft have since approached me but after mentioning the work permit issue, they went nowhere.

Most recently, the Windows Client Performance team (where I would absolutely love to work) approached me after coming across all my in-depth Windows Vista articles. A few really nice and persistent people (hi Paul and Richard!) from the Windows team persuaded me to consider again the possibility of joining Microsoft. Unfortunately, after explaining the work permit issue, this latest attempt again ground to a halt.

So, why don’t I work for Microsoft? I would love to but it seems those powerful Microsoft immigration lawyers that I have heard so much about are not all-powerful after all.

Kenny Kerr
British Columbia, Canada


© 2007 Kenny Kerr 

Posted by KennyKerr with 15 comment(s)

Window Clippings 1.5

Update: Version 2.0 is now available! Download it now from http://www.windowclippings.com/.

 

Window Clippings 1.5 is now available for download. There are a number of new features that I’m sure you’ll appreciate. Read on to learn more!

This is the last release that you will have to manually download to replace previous versions. Version 1.5 introduces, among many other new features, the ability to update itself when new versions become available. More on that in a minute.

WindowClippings.exe – for x86 editions of Windows XP, Windows Server 2003 and Windows Vista

WindowClippings.exe – for x64 editions of Windows XP, Windows Server 2003 and Windows Vista

Latest build: 1.5.15

This latest version turned out to be quite a bit larger in scope than I anticipated. It first started with an email from Chris Sells inquiring about the ability to capture shadows on Windows Vista as well as the ability include the selected window’s parent. Here is an example of this:

Notice that I’ve captured the actual shadow produced by the desktop window manager instead of faking a shadow as some other tools do.

After adding support for optionally including shadows and parent windows I continued testing and preparing for the release. Chris meanwhile started using a beta build of Window Clippings for his upcoming book and shared the beta with his co-author Ian Griffiths. At this point I received an email from Ian asking whether I could capture the transparency of windows in the alpha channel of the resulting image file. I was reluctant at first but Ian was very persuasive and I eventually added support for this. Consider the following window that illustrates how the desktop background image appears through the window:

Now here is an example of the image generated by Window Clippings having captured the transparency of the window. I have placed the image over some squiggles in a OneNote page to illustrate the transparency:

As you can see, the image has retained the transparency of the window on the desktop but has lost the blurring provided by the desktop window manager since this is not something that image formats can currency represent. Big thanks go to Ian for pushing me to add this feature and proving that it was possible.

Finally, I hadn’t planned on supporting OneNote 2007 in this release but I noticed that it conflicts with the OneNote 2003 API so in the interests of the user I decided to push ahead and add OneNote 2007 to the feature list. Anyway, let me show you how to use the new features.

Image Effects

I generalized the “Clear window background” feature to support not only Windows Vista but any window with any level of transparency. This may be a window with “glass” such as you find on Windows Vista and later versions or it may be a “layered window” with a transparency key or a full-blown alpha channel on any supported version of Windows. In previous versions, “Clear window background” did just that by removing any background “clutter” that may have produced what I called “dirty glass”. In this latest version however, the resulting image actually adopts the transparency of the window so if you save a PNG file it will include an alpha channel mirroring that of the selected window(s).

The second image effect instructs Window Clippings to capture any shadow that may be present on Windows Vista. To be clear, I capture the shadow present around a window and preserve the alpha blending. I do not draw my own shadow as I wanted it to look exactly as it does in reality. This also means that Window Clippings won’t create images with shadows for windows that never had shadows to begin with. Personally I find this more authentic.

Keep in mind that capturing these image effects pushes the boundaries of video hardware performance as well as the robustness of desktop composition. You may find some windows that cannot be captured. It may be because they’re relying on DirectX or simply have pretty slow GDI drawing performance. In these cases your best bet is to simply disable both image effects and the window clipping should be created as before. Future builds of Window Clippings will provide better compatibility.

Include Parent Window

This is the only new feature in Window Clippings that doesn’t have any obvious user interface. To include the parent window in a selection, simply hold the Shift key while selecting the window.

Sending to OneNote 2003 and 2007

Window Clippings can now send window clippings to either OneNote 2003 or OneNote 2007. If you have both installed you get to choose where your window clippings are sent. The OneNote API is a bit troublesome so there are some “release notes” related to using Window Clippings with OneNote that I should point out.

If you installed OneNote 2007 after OneNote 2003 it will have overwritten the OneNote 2003 API so that it no longer works as expected. To fix this you simply need to rerun the OneNote 2003 setup and select the “Repair” option. At that point you can once again use either OneNote 2003 or 2007 as the target for your window clippings.

Window Clippings makes use of the new XmlLite library that is included with recent editions of Windows. It is used for OneNote 2007 support so if you have OneNote 2007 installed but Window Clippings indicates that it is not available then it means that you don’t have XmlLite on your computer. XmlLite is included with Windows Server SP2, Windows XP x64 SP2, and yes with Windows Vista so you may only need to install it if you are still running Windows XP. You can download it here.

To be clear, Window Clippings does not require XmlLite and will function just fine without it. It is only needed to send window clippings to OneNote 2007.

Check for Updates

Finally, you can check for updates at any time by selecting “Check for Updates” from the notification icon’s context menu. Window Clippings will also check for updates on startup. If a new version is available and you choose to upgrade, Window Clippings will perform the upgrade in-place and you will be able to continue working momentarily with little disruption. I have tried to make it as unobtrusive as possible.

What’s Next

Well that’s it for this release. I hope you enjoy it and please provide feedback. This release was very much driven by user feedback. So what’s next? You tell me. I have a lot of ideas but I’d love to hear from you!

By the way, all the images in this post were taking with Window Clippings 1.5 making use of the various settings to achieve the desired effects.

Update: I wrote an article introducing Window Clippings to new users. It walks you through the basic operations and introduces all the available settings: Using Window Clippings.

Update: Build 1.5.9 fixes a bug related to using Window Clippings with multiple monitors on Windows XP.

Update: Build 1.5.10 adds support for DPI scaling for users using large scale or custom DPI configurations.

Update: Build 1.5.15 fixes a number of bugs that I have discovered. The only reported bug that I have fixed in this build is the one mentioned by Leo Davidson regarding residue from the context menu being included in the image due to the menu fading out. Window Clippings now correctly disables all animations while the window clipping is being created including newer Vista-specific animations.


© 2007 Kenny Kerr 

 

Posted by KennyKerr with 57 comment(s)
Filed under:

Controls and the Desktop Window Manager

Of all the Windows Vista for Developers series articles that I have written, the one about the Desktop Window Manager (DWM) is by far the most popular considering the blog traffic statistics and the amount of email I receive with questions about glass.

By far the most common question I hear is about how to get controls to render correctly on glass. If you recall, I wrote the DWM article before the release of Windows Vista to manufacturing. Those early builds included a hack that allowed you to easily draw controls on glass by tweaking the transparency key. I demonstrated this technique in the article. Unfortunately, when Microsoft finally released Windows Vista this “hack” no longer worked leaving developers to wonder how it could be done.

Having said my piece about DWM and what with being extremely busy with my day job and various other commitments I never quite found the time to present alternative solutions. For the sake of my email inbox, I am going to present a simple solution to address the most common request:

How can I display an edit control on glass?!

There are a number of ways of solving this sort of problem. Specifically, there are a number of ways to override the default drawing behavior of the standard and common controls.

You can handle WM_PAINT and draw it yourself. This tends to be more work than it’s worth so most developers avoid it, however it does allow you all the freedom necessary to paint with the necessary alpha channel information to render correctly on glass. My DWM sample demonstrates this technique, albeit not with a control.

Another solution is to owner draw controls. This is a lot of work but a lot less than the WM_PAINT approach as the system does a lot of the work for you. Owner draw is nice and works for most but not all controls. Notably it does not work with edit controls.

An even simpler approach is custom draw but this works with an even smaller set of controls.

Finally, for a small number of controls you can handle WM_CTLCOLORxxx to set the text and background color of the control.

Considering the options listed thus far, only the last one actually supports edit controls and does not involve a gargantuan amount of work. Unfortunately, it does not play nicely with glass since the technique involves GDI primitives that do not support alpha blending.

I repeat: How can I display an edit control on glass?!

It is at times like these that I wonder why I don’t work for Microsoft and am not compensated for the articles I post on my blog…  :)

Having received yet another email yesterday asking about edit controls on glass I decided to poke around the Windows SDK to see if it has anything new to offer. By the way, if you do not regularly read the Windows SDK I highly encourage that you do so. On a hunch, I started my search in the Themes and Visual Styles section of the SDK. After all, this is the subsystem responsible for providing the look and feel for controls.

The first thing I noticed was a set of functions added to UxTheme.dll in Windows Vista to support buffered painting. At first this might not seem all that interesting since the DWM already provides a degree of double buffering, but having the ability to buffer painting operations means that you can capture, alter, and then paint the updated bitmap. Of course, this is nothing new and could be achieved manually but the new functions provided by Visual Styles just simplify the task and solves our immediate problem quite nicely.

The Buffered Paint API

The buffered paint API provides a set of functions to provide efficient off-screen painting to a device context (DC). Since painting is done to a DC, it means that your investment in GDI is not lost. That’s right folks, you don’t have to port your entire application to Windows Presentation Foundation just yet.

To start, you should call the BufferedPaintInit function at least once per thread to initialize the API for use. Each call to BufferedPaintInit must eventually be matched with a call to BufferedPaintUnInit on the same thread.

To begin a buffered paint operation, simply call the BeginBufferedPaint function. It accepts a target DC and target rectangle identifying the eventual location that the buffer will be copied to. A few additional paramteters allow you to control the buffer characteristics. One of these is the format of the buffer and thankfully, it supports device-independent bitmaps (DIBs) necessary for most alpha blending operations. BeginBufferedPaint then returns a handle that can be passed to various other buffered paint API functions as well as a DC that you can use to paint to the buffer.

One such function that you can pass the buffered paint handle to is BufferedPaintSetAlpha. It allows you to easily update the alpha channel for the entire buffer and set it to a single value to control the level of transparency/opacity. Note that it updates the alpha value for each pixel in the buffer to a single value.

Finally you can copy the buffer to the target DC and free the associated resources allocated by BeginBufferedPaint with a single call to the EndBufferedPaint function.

By now, you can probably imagine where I am going with this. You simply need to use the buffered paint API to create a buffer to paint the edit control into and then set the alpha channel on the buffer before updating the window DC. Let us bring it home with a sample.

The BufferedPaint class

The following class wraps the buffered paint API to simplify its use from C++.

class BufferedPaint
{
public:
 
    BufferedPaint() :
        m_handle(0)
    {
        COM_VERIFY(::BufferedPaintInit());
    }
 
    ~BufferedPaint()
    {
        COM_VERIFY(::BufferedPaintUnInit());
    }
 
    HRESULT Begin(HDC targetDC,
                  const RECT& targetRect,
                  BP_BUFFERFORMAT format,
                  __in_opt BP_PAINTPARAMS* options,
                  __out CDCHandle& bufferedDC)
    {
        ASSERT(0 == m_handle);
 
        m_handle = ::BeginBufferedPaint(targetDC,
                                        &targetRect,
                                        format,
                                        options,
                                        &bufferedDC.m_hDC);
 
        HRESULT result = S_OK;
 
        if (0 == m_handle)
        {
            result = HRESULT_FROM_WIN32(::GetLastError());
        }
 
        return result;
    }
 
    HRESULT End(bool updateTargetDC)
    {
        ASSERT(0 != m_handle);
 
        HRESULT result = ::EndBufferedPaint(m_handle,
                                            updateTargetDC);
 
        m_handle = 0;
        return result;
    }
 
    HRESULT SetAlpha(__in_opt const RECT* rect,
                     BYTE alpha)
    {
        ASSERT(0 != m_handle);
 
        return ::BufferedPaintSetAlpha(m_handle,
                                       rect,
                                       alpha);
    }
 
private:
 
    HPAINTBUFFER m_handle;
 
};

The OpaqueEdit class

The following C++ class is used to subclass the system’s edit control so that we can more easily take over its painting duties.

class OpaqueEdit :
    public CWindowImpl<OpaqueEdit, CEdit>
{
public:
 
    BEGIN_MSG_MAP_EX(OpaqueEdit)
        MESSAGE_HANDLER(WM_PAINT, OnPaint)
        REFLECTED_COMMAND_CODE_HANDLER_EX(EN_CHANGE, OnChange)
        DEFAULT_REFLECTION_HANDLER()
    END_MSG_MAP()
 
private:
 
    LRESULT OnPaint(UINT /*message*/,
                    WPARAM /*wParam*/,
                    LPARAM /*lParam*/,
                    BOOL& /*handled*/)
    {
        CPaintDC targetDC(m_hWnd);
        CDCHandle bufferedDC;
 
        if (SUCCEEDED(m_bufferedPaint.Begin(targetDC,
                                            targetDC.m_ps.rcPaint,
                                            BPBF_TOPDOWNDIB,
                                            0, // options
                                            bufferedDC)))
        {
            SendMessage(WM_PRINTCLIENT,
                        reinterpret_cast<WPARAM>(bufferedDC.m_hDC),
                        PRF_CLIENT);
 
            COM_VERIFY(m_bufferedPaint.SetAlpha(0, // entire buffer
                                                255)); // 255 = opaque
 
            // Copy buffered DC to target DC
            COM_VERIFY(m_bufferedPaint.End(true));
        }
 
        return 0;
    }
 
    void OnChange(UINT /*notifyCode*/,
                  int /*control*/,
                  HWND /*window*/)
    {
        VERIFY(InvalidateRect(0, // entire window
                              FALSE)); // don't erase background
    }
 
    BufferedPaint m_bufferedPaint;
 
};

As you can see in my WM_PAINT handler, I send the edit control the WM_PRINTCLIENT message, instructing it to paint into the buffered DC. I then set the buffer’s alpha channel to 255 (completely opaque) and update the target DC. What might come as a surprise is the need for the EN_CHANGE handler. Since the edit control paints outside of the WM_PAINT message, I need to paint “over” the extra painting that occurs when the control’s text changes. In this example, I simply invalidate the control, which forces it to receive a new WM_PAINT message. I could probably optimize this further but it is sufficient for this example. Keep in mind that since the DWM provides double buffering automatically you should not notice any flicker due to the repeated painting.

The SampleDialog class

The following class simply ensures that the window is represented as a “sheet” of glass and uses the OpaqueEdit class to subclass the edit control.

class SampleDialog :
    public CDialogImpl<SampleDialog>
{
public:
 
    enum { IDD = IDD_SAMPLE };
 
    BEGIN_MSG_MAP(MainWindow)
        MSG_WM_INITDIALOG(OnInitDialog)
        MSG_WM_ERASEBKGND(OnEraseBackground)
        COMMAND_ID_HANDLER(IDCANCEL, OnCancel)
        REFLECT_NOTIFICATIONS()
    END_MSG_MAP()
 
private:
 
    bool OnInitDialog(HWND /*control*/,
                      LPARAM /*lParam*/)
    {
        const MARGINS margins = { -1 };
 
        COM_VERIFY(::DwmExtendFrameIntoClientArea(m_hWnd,
                                                  &margins));
 
        VERIFY(m_edit.SubclassWindow(GetDlgItem(IDC_CONTROL)));
 
        return true; // Yes, go ahead and set the keyboard focus.
    }
 
    bool OnEraseBackground(CDCHandle dc)
    {
        CRect rect;
        VERIFY(GetClientRect(&rect));
 
        dc.FillSolidRect(&rect,
                         RGB(0,0,0));
 
        return true; // Yes, I erased the background.
    }
 
    LRESULT OnCancel(WORD /*notifyCode*/,
                     WORD identifier,
                     HWND /*window*/,
                     BOOL& /*handled*/)
    {
        VERIFY(EndDialog(identifier));
        return 0;
    }
 
    OpaqueEdit m_edit;
};

That is all there is to it. I hope the techniques described in this article will help in your path to adopting Windows Vista as a developer.


© 2007 Kenny Kerr 

 

Posted by KennyKerr with 11 comment(s)

Window Clippings and Toronto

I’m taking Window Clippings on the road this week! Only kidding… Sorry about the delay folks. I know a lot of you have been waiting for version 1.3 to be released. One of my monitors recently died. I ordered a replacement from Dell but I’m still waiting for it to arrive. The courier company seems to be struggling with the weather we’re having here in the North West. Window Clippings supports multiple monitors and it’s important that I test those scenarios before every release because of all the calculations that are done with screen coordinates.

Anyway, I’m flying to Toronto this evening and will be back on Wednesday at which point the new monitor should have arrived.


© 2007 Kenny Kerr

Posted by KennyKerr with no comments
Filed under:

Window Clippings Question

I have received some great feedback from a few users and am preparing to release a new version with a few great new little features. It should be available in the next week or so. I will talk a lot more about that soon. However, here is a question for you:

Would you care if I removed the OneNote support? Please let me know either way.

If you use the OneNote feature, would you like to see support for OneNote 2007 added?

I just need to figure out what to do with this feature – do I add OneNote 2007 support or do I just scrap it. I honestly do not use this feature and do not know anyone who does but if you are out there and really care about this feature then please let me know! I probably will not remove it in the short term but I am planning the 2.0 release and need to decide what to do with it.

Comments please!

Update:

Thanks for all the responses. As a result, I will continue to support OneNote 2003 and add support for OneNote 2007 shortly. Windows Clippings 1.3 will be released in the next few days so I will not have time to add OneNote 2007 support in that release but a subsequent release will include it so stay tuned!


© 2007 Kenny Kerr

Posted by KennyKerr with 10 comment(s)
Filed under:

Those Five Things Bla Bla

I find it interesting that the self-assumed chancellor of blogland has a problem with the "Five Things" meme. How dare we waste RSS on such silliness as if it were a precious natural resource we are squandering? Sigh. But then he also proclaimed private blogs unconstitutional so you have to wonder.

:)

Anyway, since James Kovacs tagged me I am obligated to share my dirty little secrets:

  1. I was born in Israel and spent the first seven or eight years of my life living as an Israeli kid. I couldn't speak a word of English when we left. I am not Jewish but can't wait to go back one day as it still feels like home at some level…
  2. I own an Xbox 360 but have only ever played PGR on it. We mostly use it as a Windows Vista Media Center Extender. Is it just me or is the Xbox incredibly noisy?
  3. I play the sax, clarinet and flute and played in a jazz/blues band as a kid. I miss jamming with the gang.
  4. I don't drink or smoke.
  5. I think that the perfect programming language is not commercially viable.

OK so number five is just a random thought but that's all I can think of to share. If my mundane existence isn't interesting enough, go over to gapingvoid for some characteristically MacLeod humor.

I'm apparently also obligated to tag five more people. Here goes:

  1. Ashley Visagie
  2. Nishant Sivakumar
  3. Shawn Farkas
  4. Brandon Bray
  5. Paul Watson

Happy New Year!


© 2007 Kenny Kerr

Posted by KennyKerr with 5 comment(s)

Looking Back At 2006

I can't believe I can already say that 2006 is behind us. 2006 involved a lot more writing and some new tools. Let's take a quick look.

Blogging

Here are some of the more popular and/or meaningful articles I posted on my blog in 2006:

Increment differences in C++ and C#

The Linq between C# and C++

Attributes That Do Nothing

I also started publishing a popular series of articles on my blog titled Windows Vista for Developers:

Part 1: Aero Wizards

Part 2: Task Dialogs in Depth

Part 3: The Desktop Window Manager

Part 4: User Account Control

Part 5: Getting Started With Server Core

Part 6: The New File Dialogs 

I hope to continue with this series in 2007.

And of course there was that "politically incorrect" post:

The Christ in Christmas

Tools

I also published a few more tools/updates:

Window Clippings 1.2 (full Vista support)

Known Folders Browser 1.0 (for Vista and beyond)

Articles

A few more of my articles were published in 2006:

Credential Management with the .NET Framework 2.0

Understanding Member Functions in Visual C++ 2005

Visual C++ 2005 under the Hood

Best Practices for Writing Efficient and Reliable Code with C++/CLI

Beyond WinFX: Transactions, Aero Wizards, and Task Dialogs In Windows Vista

2007

It looks like 2007 will bring a lot of change for my family and I, but I'll talk more about that when the time comes.

Here's to a great year to you all – thanks for reading.


© 2007 Kenny Kerr

Posted by KennyKerr with 1 comment(s)
More Posts