My solution after considering the options available. The approach is the one used by the Notepad++ code for the Function List panel, but slightly different where some data structures are not visible by the plugin code.
First of all, create an empty dialog in the resource file. Then use the following code in the .CPP file:
INT_PTR CALLBACK ProjectDlg::run_dlgProc(UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
// the dialog is being initialized
case WM_INITDIALOG:
{
// create the toolbar with the specified style
int style = WS_CHILD | WS_VISIBLE | CCS_ADJUSTABLE | TBSTYLE_AUTOSIZE | TBSTYLE_FLAT |
TBSTYLE_LIST | TBSTYLE_TRANSPARENT | BTNS_AUTOSIZE | BTNS_SEP | TBSTYLE_TOOLTIPS;
_hToolBar = ::CreateWindowEx(0, TOOLBARCLASSNAME, NULL, style,
0, 0, 0, 0, _hSelf, nullptr, _hInst, NULL);
// set the bitmap size
::SendMessage(_hToolBar, TB_SETBITMAPSIZE, 0, MAKELPARAM(24, 24));
// get the icons from the resources
TBADDBITMAP addbmp = { 0, 0 };
const int nbIcons = 8;
int iconIDs[nbIcons] = { IDB_NEWPRJ, IDB_OPENPRJ, IDB_SAVEPRJ, IDB_ADDLIB,
IDB_RMVLIB, IDB_ADDFILE, IDB_COMFILE, IDB_COMALL };
int iconDarkModeIDs[nbIcons] = { IDB_NEWPRJ_DM, IDB_OPENPRJ_DM, IDB_SAVEPRJ_DM,
IDB_ADDLIB_DM, IDB_RMVLIB_DM , IDB_ADDFILE_DM,
IDB_COMFILE_DM , IDB_COMALL_DM };
for (size_t i = 0; i < nbIcons; ++i)
{
int icoID = ::SendMessage(nppData._nppHandle, NPPM_ISDARKMODEENABLED, (WPARAM)0, (LPARAM(0))) ? iconDarkModeIDs[i] : iconIDs[i];
HBITMAP hBmp = static_cast<HBITMAP>(::LoadImage(_hInst, MAKEINTRESOURCE(icoID), IMAGE_BITMAP, 24, 24, LR_LOADMAP3DCOLORS | LR_LOADTRANSPARENT));
addbmp.nID = reinterpret_cast<UINT_PTR>(hBmp);
::SendMessage(_hToolBar, TB_ADDBITMAP, 1, reinterpret_cast<LPARAM>(&addbmp));
}
// set up the buttons
TBBUTTON tbButtons[nbIcons];
tbButtons[0].idCommand = IDC_NEWPRJ;
tbButtons[0].iBitmap = 0;
tbButtons[0].fsState = TBSTATE_ENABLED;
tbButtons[0].fsStyle = BTNS_BUTTON | BTNS_AUTOSIZE;
tbButtons[0].iString = reinterpret_cast<intptr_t>(TEXT("New project..."));
// set up all the other buttons
// set up the tool bar and show it
::SendMessage(_hToolBar, TB_SETMAXTEXTROWS, 0, 0);
::SendMessage(_hToolBar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
::SendMessage(_hToolBar, TB_SETBUTTONSIZE, 0, MAKELONG(24, 24));
::SendMessage(_hToolBar, TB_ADDBUTTONS, sizeof(tbButtons) / sizeof(TBBUTTON),
reinterpret_cast<LPARAM>(&tbButtons));
::SendMessage(_hToolBar, TB_AUTOSIZE, 0, 0);
::ShowWindow(_hToolBar, SW_SHOW);
// create the other controls
// the dialog was resized
case WM_SIZE:
{
// get the new width and height of the panel
int width = LOWORD(lParam);
int height = HIWORD(lParam);
// get the size of the toolbar
RECT toolbarMenuRect;
::GetClientRect(_hToolBar, &toolbarMenuRect);
// move the toolbar to the top with a margin
int margin = 1;
::MoveWindow(_hToolBar, margin, margin, width,
toolbarMenuRect.bottom, TRUE);
// set the size of all the other controls
}
// manage the other messages
}
return DockingDlgInterface::run_dlgProc(message, wParam, lParam);
}
Hope this will help someone eventually.