News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests

Main Menu

Toolbar menu

Started by TimoVJL, November 07, 2023, 04:08:59 AM

Previous topic - Next topic

TimoVJL

Simple toolbar menu project for Pelles C

May the source be with you

Vortex

Hi Timo,

Thanks for the example project, nice contribution :thumbsup:

jj2007

Quote from: TimoVJL on November 07, 2023, 04:08:59 AMSimple toolbar menu project for Pelles C

Perfect, thanks a lot, Timo :thup:

TimoVJL

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;
}
May the source be with you

Vortex

Hi Timo,

I build the project with Pelles C V12. Nice job :thumbsup:

jj2007

GitHub:
QuoteCustom owner menubar drawing for win32 even with aero themes using undocumented Windows messages and structures, previously unknown.