0

How can I reproduce Explorer's buttons from Windows 10 using the Win32 API?

image


UPDATE: I tried to create a Command Link using this code, but it shows me a checkbox instead:

HWND hwndCommandLink = CreateWindow(
    L"BUTTON", // Predefined class; Unicode assumed
    L"", // Text will be defined later
    WS_TABSTOP | WS_VISIBLE | WS_CHILD | BS_COMMANDLINK, // Styles
    200, // x position
    10, // y position
    100, // Button width
    100, // Button height
    m_hwnd, // Parent window
    NULL, // No menu
    (HINSTANCE)GetWindowLongPtr(m_hwnd, GWLP_HINSTANCE),
    NULL); // Pointer not needed

image

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
Noobes GT
  • 3
  • 4
  • Task Dialog api is the closest to what you can do with Windows API: https://learn.microsoft.com/en-us/windows/win32/controls/task-dialogs-overview note the final style depends on version of Windows. ex: https://stackoverflow.com/questions/46838210/taskdialog-not-working-on-or-replacement-for-windows-10 (recent look) https://www.codeproject.com/Articles/16806/Vista-Goodies-in-C-Using-TaskDialogIndirect-to-Bui (older look) – Simon Mourier Oct 22 '20 at 13:36
  • @SimonMourier [Command Links](https://learn.microsoft.com/en-us/windows/win32/uxguide/ctrl-command-links) are the *closest* you can get with the API, since that is what those buttons actually are. `TaskDialogIndirect()` simply has an option to *use* Command Links if specified. – Remy Lebeau Oct 22 '20 at 14:38

2 Answers2

1

Those buttons are formally known as Command Links. Per the Push Buttons documentation:

Windows Vista and Version 6.00 also introduced another kind of push button, the command link. Visually, a command link is very different from a normal push button, but it has the same functionality. A command link typically displays an arrow icon, a line of text, and additional text in a smaller font.

So, first thing, you need an application manifest that enables ComCtl32.dll v6. See Enabling Visual Styles for details about that. If you do not enable ComCtl32.dll v6, you will end up with a (misbehaving) CheckBox instaad of a proper Command Link. You can use DllGetVersion() to verify at runtime whether ComCtl32.dll v6 is actually being used or not. See Using DllGetVersion to Determine the Version Number.

With ComCtrl32.dll v6 enabled, per How to Create a Command Link you can simply create a standard BUTTON control with the BS_COMMANDLINK (or BS_DEFCOMMANDLINK) window style enabled, and then you can send it WM_SETTEXT and BCM_SETNOTE messages to set its 2 text fields, and a BM_SETIMAGE message to set its icon. When a Command Link is clicked, its parent window will receive a standard BN_CLICKED notification.

If you use the Task Dialog API (also introduced in Vista), the TaskDialogIndirect() function has TDF_USE_COMMAND_LINKS and TDF_USE_COMMAND_LINKS_NO_ICON flags available to display specified buttons as Command Links. The TaskDialog() function does not have that option.

Remy Lebeau
  • 555,201
  • 31
  • 458
  • 770
  • @NoobesGT you are going to have to be more specific. Please edit your question to provide details about what you actually tried that is not working for you. – Remy Lebeau Oct 22 '20 at 17:36
  • I asked you to **edit your question** to provide those details. I have made the edit for you now. Next time, please do it yourself. In any case, you didn't provide enough info to diagnose the problem. Please **edit your question** to provide a [mcve]. And did you enable ComCtrl32 v6, like I stated in my answer? That is a *requirement* for using Command Links. – Remy Lebeau Oct 22 '20 at 17:49
  • may i ask what is this called and how can i reproduce it? https://i.imgur.com/5JsPQ88.png – Noobes GT Oct 22 '20 at 18:11
  • @NoobesGT I tested the code presented and it works perfectly fine for me exactly as shown, so you must be doing something wrong that we can't see, like not enabling ComCtrl32 v6 correctly. Without ComCtrl32 v6, I see the checkbox. With ComCtrl32 v6, I see the Command Link. I have updated my answer to reflect this. – Remy Lebeau Oct 22 '20 at 18:36
  • @NoobesGT Windows Explorer uses TreeViews and ListViews to display items. That image looks like an item in a [ListView group](https://learn.microsoft.com/en-us/windows/win32/controls/list-view-controls-overview#arranging-list-items-by-group), see [How to Use Groups in a List-View`](https://learn.microsoft.com/en-us/windows/win32/controls/use-groups-in-a-list-view)/ Now please, stop asking new questions in comments. EDIT YOUR QUESTION or POST A NEW QUESTION. I suggest you read the [tour] and [help] on how to use this site properly. – Remy Lebeau Oct 22 '20 at 18:36
0

You need Enable Visual Styles to modify the button style:

If you are using Microsoft Visual C++ 2005 or later, you can add the following compiler directive to your source code instead of manually creating a manifest. For readability, the directive is broken into several lines here.

So, you can select YES (/MANIFEST) in Properties->Linker->Manifest->Generate Manifest and add the following compiler directive at the beginning of the code:

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

Also, you can add a manifest file in Properties->Manifest Tool->Input and Out->Additional Manifest Files

enter image description here

The content of the manifest file is as follows:

<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
  <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1"> 
    <application>
      <!--The ID below indicates app support for Windows 10 -->
      <supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}"/>
    </application>
  </compatibility>
  <dependency>
    <dependentAssembly>
        <assemblyIdentity
            type="win32"
            name="Microsoft.Windows.Common-Controls"
            version="6.0.0.0"
            processorArchitecture="*"
            publicKeyToken="6595b64144ccf1df"
            language="*"
        />
    </dependentAssembly>
  </dependency>
</assembly>

Both methods works for me:

enter image description here

Zeus
  • 3,703
  • 3
  • 7
  • 20