Simple toolbar menu project for Pelles C
(https://i.postimg.cc/GB5h7mXZ/SMenu1.png) (https://postimg.cc/GB5h7mXZ)
Hi Timo,
Thanks for the example project, nice contribution :thumbsup:
Quote from: TimoVJL on November 07, 2023, 04:08:59 AMSimple toolbar menu project for Pelles C
Perfect, thanks a lot, Timo :thup:
A silly funny example in C
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <commctrl.h>
//#pragma lib "comctl32.lib"
#define IDM_MENU 6001
#define IDM_EXIT 6002
#define IDM_NEW 6003
#define IDM_OPEN 6004
#define IDC_STATUS 4000
#define IDC_TOOLBAR 4001
#ifndef NELEMS
#define NELEMS(a) (sizeof(a) / sizeof(a[0]))
#endif
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
static BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct);
static void OnDestroy(HWND hwnd);
static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify);
//static UINT OnNCHitTest(HWND hwnd, int x, int y);
static UINT OnNCHitTest(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam);
static void OnSize(HWND hwnd, UINT state, int cx, int cy);
static void ContextMenu(HWND hwnd);
TCHAR szAppName[] = TEXT("WSDIFrame");
TCHAR szFrameClass[] = TEXT("cWSDIFrame");
HWND g_hFrame, g_hStatus, g_hToolbar;
HANDLE g_hInst;
HMENU g_hMenu;
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
WNDCLASSEX wcx;
MSG msg;
wcx.cbSize = sizeof(WNDCLASSEX);
GetClassInfoEx(hInstance, MAKEINTRESOURCE(32770), &wcx);
wcx.style = CS_BYTEALIGNCLIENT | CS_BYTEALIGNWINDOW;
wcx.lpfnWndProc = (WNDPROC)WndProc;
wcx.hInstance = hInstance;
wcx.hbrBackground = (HBRUSH)COLOR_3DSHADOW;
wcx.lpszClassName = szFrameClass;
if (!RegisterClassEx(&wcx))
return 0;
g_hInst = hInstance;
g_hFrame = CreateWindowEx(WS_EX_OVERLAPPEDWINDOW, szFrameClass, 0, //szAppName,
WS_POPUP | WS_VISIBLE | WS_THICKFRAME,
//WS_THICKFRAME, //WS_OVERLAPPEDWINDOW,
//CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, 200, 200,
NULL, NULL, hInstance, NULL);
if (!g_hFrame)
return 0;
ShowWindow(g_hFrame, nCmdShow);
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return msg.wParam;
}
HWND MakeToolbar(HWND hWnd, UINT wID)
{
TBBUTTON tbb[] = {
{-1, IDM_MENU, TBSTATE_ENABLED, BTNS_SHOWTEXT, {0}, 0L, (int)TEXT("Menu")},
{0, 0, TBSTATE_ENABLED, TBSTYLE_SEP, {0}, 0L, 0},
{STD_FILENEW, IDM_NEW, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, (int)TEXT("New")},
{STD_FILEOPEN, IDM_OPEN, TBSTATE_ENABLED, TBSTYLE_BUTTON, {0}, 0L, (int)TEXT("Open")},
};
TBADDBITMAP tbBitmap;
HWND hToolbar = CreateWindowEx(0, TEXT("ToolbarWindow32"), NULL,
WS_CHILD | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT | TBSTYLE_LIST
, 0, 0, 0, 0, hWnd,
(HMENU)IDC_TOOLBAR, GetModuleHandle(NULL), NULL);
SendMessage(hToolbar, TB_BUTTONSTRUCTSIZE, sizeof(TBBUTTON), 0);
tbBitmap.hInst = HINST_COMMCTRL;
tbBitmap.nID = IDB_STD_SMALL_COLOR;
SendMessage(hToolbar, TB_ADDBITMAP, 0, (WPARAM)&tbBitmap);
SendMessage(hToolbar, TB_ADDBUTTONS, NELEMS(tbb), (LPARAM)&tbb);
SendMessage(hToolbar, TB_SETEXTENDEDSTYLE, 0, TBSTYLE_EX_MIXEDBUTTONS);
ShowWindow(hToolbar, SW_SHOW);
return hToolbar;
}
static HWND MakeStatusbar(HWND hWnd, UINT wID)
{
HWND hStatus = CreateStatusWindow(WS_CHILD | WS_VISIBLE | SBARS_SIZEGRIP,
NULL, hWnd, wID);
return hStatus;
}
static HMENU MakeMenubar(HWND hWnd)
{
HMENU hMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_ENABLED | MF_STRING, IDM_NEW, TEXT("&New"));
AppendMenu(hMenu, MF_ENABLED | MF_STRING, IDM_OPEN, TEXT("&Open"));
AppendMenu(hMenu, MF_ENABLED | MF_SEPARATOR, 0, 0);
AppendMenu(hMenu, MF_ENABLED | MF_STRING, IDM_EXIT, TEXT("&Exit"));
return hMenu;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
switch (wMsg)
{
case WM_COMMAND:
return OnCommand((hwnd), (int)(LOWORD(wParam)), (HWND) (lParam), (UINT)HIWORD(wParam)), 0;
case WM_NCHITTEST:
//return (LRESULT)(DWORD)(UINT)OnNCHitTest(hwnd,(int)(short)LOWORD(lParam),(int)(short)HIWORD(lParam));
return OnNCHitTest(hwnd, wMsg, wParam, lParam);
case WM_SIZE:
return OnSize((hwnd), (UINT) (wParam), (int)(short)LOWORD(lParam), (int)(short)HIWORD(lParam)), 0;
case WM_CREATE:
return OnCreate((hwnd), (LPCREATESTRUCT) (lParam)), 0;
case WM_DESTROY:
return OnDestroy(hwnd), 0;
default:
return DefWindowProc(hwnd, wMsg, wParam, lParam);
}
}
static BOOL OnCreate(HWND hwnd, LPCREATESTRUCT lpCreateStruct)
{
InitCommonControls();
g_hToolbar = MakeToolbar(hwnd, IDC_TOOLBAR);
//g_hStatus = MakeStatusbar(hwnd, IDC_STATUS);
g_hMenu = MakeMenubar(hwnd);
return 0;
}
static void OnDestroy(HWND hwnd)
{
PostQuitMessage(0);
}
static void OnCommand(HWND hwnd, int id, HWND hwndCtl, UINT codeNotify)
{
switch (id)
{
case IDM_MENU:
ContextMenu(hwnd);
return;
case IDM_EXIT:
PostMessage(hwnd, WM_CLOSE, 0, 0L);
return;
}
}
//static UINT OnNCHitTest(HWND hwnd, int x, int y)
static UINT OnNCHitTest(HWND hwnd, UINT wMsg, WPARAM wParam, LPARAM lParam)
{
RECT rcTB;
GetWindowRect(g_hToolbar, &rcTB);
LRESULT rc = DefWindowProc(hwnd, wMsg, wParam, lParam);
if (HIWORD(lParam) < rcTB.bottom) return HTCAPTION;
else return rc;
}
static void OnSize(HWND hwnd, UINT state, int cx, int cy)
{
if (state == SIZE_MINIMIZED)
return;
//SendMessage(g_hToolbar, WM_SIZE, state, cx);
SendMessage(g_hStatus, WM_SIZE, state, cx);
}
static void ContextMenu(HWND hwnd)
{
RECT rcTB;
GetWindowRect(g_hToolbar, &rcTB);
TrackPopupMenu(g_hMenu, TPM_LEFTALIGN, rcTB.left, rcTB.bottom, 0, g_hFrame, NULL);
return;
}
Hi Timo,
I build the project with Pelles C V12. Nice job :thumbsup:
GitHub (https://github.com/adzm/win32-custom-menubar-aero-theme):
QuoteCustom owner menubar drawing for win32 even with aero themes using undocumented Windows messages and structures, previously unknown.