2

I have a old MFC application that I can't to enable 'Microsoft.Windows.Common-Controls' to all controls in this application because new behavior of some controls. But I need it for CEdit that support to EM_SETCUEBANNER.

I try to do that in OnInitDialog:

m_edt = (CEdit *)GetDlgItem(edit_id);
int i= SetWindowTheme(m_edt->m_hWnd, L"Explorer", NULL);

SetWindowTheme returns 0 but I still cannot use the EM_SETCUEBANNER message.

How can I enable Microsoft.Windows.Common-Controls only for CEdit?

Jabberwocky
  • 48,281
  • 17
  • 65
  • 115
herzl shemuelian
  • 3,346
  • 8
  • 34
  • 49
  • I'd rather go for enabling 'Microsoft.Windows.Common-Controls' for all controls in your application and change some of the code. The only change in behaviour I could spot when I did this several years ago on a big project was in the ListBox: the old listbox would not report a `LBN_SELCHANGE` when you clicked outside of an item whereas the new ListBox would report it. – Jabberwocky Aug 22 '18 at 15:13
  • If you could mention which changes of behaviour you have noted I'd be grateful. – Jabberwocky Aug 22 '18 at 15:14
  • You can call InitCommonControlsEx and specify ICC_STANDARD_CLASSES, but it will apply on button, edit, static, listbox, combobox, and scroll bar – jaudo Aug 22 '18 at 15:15
  • @jaudo I'm pretty sure that `InitCommonControlsEx` is unrelated to this issue. – Jabberwocky Aug 22 '18 at 15:18
  • @Jabberwocky: You are correct, InitCommonControls is orthogonal to whether Microsoft.Windows.Common-Controls is used. The latter chooses between common controls 5 (the old behavior) and common controls 6 (new behaviors) while the former registers the selected version of the common control window classes. – SoronelHaetir Aug 22 '18 at 15:29
  • 4
    you need activate activation context where version='6.0.0.0' before create this control and deactivate after. all controls created inside version='6.0.0.0' active context will be this version – RbMm Aug 22 '18 at 17:05

1 Answers1

4

You need to create an Activatation Context that uses a ComCtrl32 v6 manifest. Then you can activate the context before creating the CEdit, and deactivate the context afterwards.

See How can you use both versions 5 and 6 of the common controls within the same module? on Raymond Chen's blog on MSDN.

For example, I did a quick test:

// setup main UI as needed, then...

// I borrowed code from https://stackoverflow.com/a/10444161/65863
// for testing purposes, but you can set lpSource to your own manifest
// file, if needed...
ACTCTX ctx = {};
ctx.cbSize = sizeof(actCtx);
ctx.dwFlags = ACTCTX_FLAG_RESOURCE_NAME_VALID
            | ACTCTX_FLAG_SET_PROCESS_DEFAULT
            | ACTCTX_FLAG_ASSEMBLY_DIRECTORY_VALID;
ctx.lpSource = TEXT("shell32.dll");
ctx.lpAssemblyDirectory = TEXT("C:\\Windows\\System32\\"); // <-- don't hard-code this in production code!
ctx.lpResourceName = MAKEINTRESOURCE(124);

HANDLE hActCtx = CreateActCtx(&ctx);
if (hActCtx == INVALID_HANDLE_VALUE) {
    // handle error ...
    return;
}

ULONG_PTR ulCookie = 0;
if (!ActivateActCtx(hActCtx, &ulCookie)) {
    // handle error ...
    ReleaseActCtx(hActCtx);
    return;
}

// make single Edit control as needed ...

DeactivateActCtx(0, ulCookie);
ReleaseActCtx(hActCtx);

And this was the result:

image

The app was compiled without any manifest at all, so ComCtrl32 v5 would be the default. The top Edit control was created using the process's default Activation Context, and the bottom Edit control was created with an explicit Activation Context using a ComCtrl32 v6 manifest, and then EM_SETCUEBANNER applied to it (if you don't want to create your own manifest, you can use resource #124 from shell32.dll, per this answer to How to enable visual styles without a manifest).

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770