HBMMENU_CALLBACK in vista

The following code always failed in Windows Vista (Beta 2 Build 5384). It is deemed a completely legimite code and works fine in Windows 2000, XP. Is this a known bug or HBMMENU_CALLBACK is not supported anymore?

Debugger shows that USER32!ValidateMENUITEMINFO sets the last error code as:

LastErrorValue: (Win32) 0x57 (87) - The parameter is incorrect.

MENUITEMINFO menuItemInfo = {0};

menuItemInfo.cbSize = sizeof(MENUITEMINFO);

menuItemInfo.fMask = MIIM_BITMAP;

menuItemInfo.hbmpItem = HBMMENU_CALLBACK;

ATLVERIFY( SetMenuItemInfo(hMenu, ID_FILE_NEW, FALSE, &menuItemInfo) );

Any leads or information would be appreciated. Thanks

[671 byte] By [patria] at [2007-12-21]
# 1

Works fine for me.

HMENU hMenu = CreatePopupMenu();
AppendMenu(hMenu, MF_STRING, 1, TEXT("Menu text")); // returns TRUE
MENUITEMINFO menuItemInfo = {0};
menuItemInfo.cbSize = sizeof(MENUITEMINFO);
menuItemInfo.fMask = MIIM_BITMAP;
menuItemInfo.hbmpItem = HBMMENU_CALLBACK;
SetMenuItemInfo(hMenu, 1, FALSE, &menuItemInfo); // returns TRUE

I went through the function history and I can't find any time when it rejected HBMMENU_CALLBACK.

RaymondChen-MSFT at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 2
This did not work for me. SetMenuItemInfo() returned false on Vista (Beta 2, Build 5384). The same code works fine on XP.
Chrix at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 3
The following code works on xp but fails on vista:

// Test1.cpp : Defines the entry point for the application.

//

#include "stdafx.h"

#include "Test1.h"

#define MAX_LOADSTRING 100

// Global Variables:

HINSTANCE hInst;// current instance

TCHAR szTitle[MAX_LOADSTRING];// The title bar text

TCHAR szWindowClass[MAX_LOADSTRING];// the main window class name

// Forward declarations of functions included in this code module:

ATOMMyRegisterClass(HINSTANCE hInstance);

BOOLInitInstance(HINSTANCE, int);

LRESULT CALLBACKWndProc(HWND, UINT, WPARAM, LPARAM);

INT_PTR CALLBACKAbout(HWND, UINT, WPARAM, LPARAM);

int APIENTRY _tWinMain(HINSTANCE hInstance,

HINSTANCE hPrevInstance,

LPTSTR lpCmdLine,

int nCmdShow)

{

UNREFERENCED_PARAMETER(hPrevInstance);

UNREFERENCED_PARAMETER(lpCmdLine);

// TODO: Place code here.

MSG msg;

HACCEL hAccelTable;

// Initialize global strings

LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);

LoadString(hInstance, IDC_TEST1, szWindowClass, MAX_LOADSTRING);

MyRegisterClass(hInstance);

// Perform application initialization:

if (!InitInstance (hInstance, nCmdShow))

{

return FALSE;

}

hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_TEST1));

// Main message loop:

while (GetMessage(&msg, NULL, 0, 0))

{

if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))

{

TranslateMessage(&msg);

DispatchMessage(&msg);

}

}

return (int) msg.wParam;

}

//

// FUNCTION: MyRegisterClass()

//

// PURPOSE: Registers the window class.

//

// COMMENTS:

//

// This function and its usage are only necessary if you want this code

// to be compatible with Win32 systems prior to the 'RegisterClassEx'

// function that was added to Windows 95. It is important to call this

function

// so that the application will get 'well formed' small icons associated

// with it.

//

ATOM MyRegisterClass(HINSTANCE hInstance)

{

WNDCLASSEX wcex;

wcex.cbSize = sizeof(WNDCLASSEX);

wcex.style= CS_HREDRAW | CS_VREDRAW;

wcex.lpfnWndProc= WndProc;

wcex.cbClsExtra= 0;

wcex.cbWndExtra= 0;

wcex.hInstance= hInstance;

wcex.hIcon= LoadIcon(hInstance, MAKEINTRESOURCE(IDI_TEST1));

wcex.hCursor= LoadCursor(NULL, IDC_ARROW);

wcex.hbrBackground= (HBRUSH)(COLOR_WINDOW+1);

//wcex.lpszMenuName= MAKEINTRESOURCE(IDC_TEST1);

wcex.lpszMenuName= NULL;

wcex.lpszClassName= szWindowClass;

wcex.hIconSm= LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));

return RegisterClassEx(&wcex);

}

//

// FUNCTION: InitInstance(HINSTANCE, int)

//

// PURPOSE: Saves instance handle and creates main window

//

// COMMENTS:

//

// In this function, we save the instance handle in a global variable

and

// create and display the main program window.

//

BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)

{

HWND hWnd;

hInst = hInstance; // Store instance handle in our global variable

hWnd = CreateWindow(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,

CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, NULL, NULL, hInstance, NULL);

if (!hWnd)

{

return FALSE;

}

ShowWindow(hWnd, nCmdShow);

UpdateWindow(hWnd);

return TRUE;

}

//

// FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM)

//

// PURPOSE: Processes messages for the main window.

//

// WM_COMMAND- process the application menu

// WM_PAINT- Paint the main window

// WM_DESTROY- post a quit message and return

//

//

LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM

lParam)

{

int wmId, wmEvent;

PAINTSTRUCT ps;

HDC hdc;

switch (message)

{

case WM_CONTEXTMENU:

{

int flags, sucess;

int pos, nX, nY;

HMENU hMenu;

MENUITEMINFO info = {0};

static const WORD bBits[] = {0x00, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x7e, 0x0};

HBITMAP hbmImage;

hMenu = CreatePopupMenu();

AppendMenu(hMenu, MF_STRING, 1, TEXT("Felipe"));

hbmImage = CreateBitmap (8, 8, 1, 1, bBits);

info.cbSize = sizeof(MENUITEMINFO);

info.fMask = MIIM_BITMAP;

//info.hbmpItem = hbmImage;

info.hbmpItem = HBMMENU_CALLBACK;

if (!SetMenuItemInfo(hMenu, 1, false, &info)) {

MessageBox (hWnd, TEXT("FAIL"), TEXT("FAIL"), 0);

}

//info.hbmpItem = image.handle;

flags = TPM_LEFTBUTTON;

if (GetKeyState (VK_LBUTTON) >= 0) flags |= TPM_RIGHTBUTTON;

pos = GetMessagePos ();

nX = LOWORD(pos);

nY = HIWORD(pos);

TrackPopupMenu (hMenu, flags, nX, nY, 0, hWnd, 0);

DestroyMenu(hMenu);

DeleteObject(hbmImage);

break;

}

//case WM_COMMAND:

//wmId = LOWORD(wParam);

//wmEvent = HIWORD(wParam);

//// Parse the menu selections:

//switch (wmId)

//{

//case IDM_ABOUT:

//DialogBox(hInst, MAKEINTRESOURCE(IDD_ABOUTBOX), hWnd, About);

//break;

//case IDM_EXIT:

//DestroyWindow(hWnd);

//break;

//default:

//return DefWindowProc(hWnd, message, wParam, lParam);

//}

//break;

case WM_PAINT:

hdc = BeginPaint(hWnd, &ps);

// TODO: Add any drawing code here...

EndPaint(hWnd, &ps);

break;

case WM_DESTROY:

PostQuitMessage(0);

break;

default:

return DefWindowProc(hWnd, message, wParam, lParam);

}

return 0;

}

// Message handler for about box.

INT_PTR CALLBACK About(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)

{

UNREFERENCED_PARAMETER(lParam);

switch (message)

{

case WM_INITDIALOG:

return (INT_PTR)TRUE;

case WM_COMMAND:

if (LOWORD(wParam) == IDOK || LOWORD(wParam) == IDCANCEL)

{

EndDialog(hDlg, LOWORD(wParam));

return (INT_PTR)TRUE;

}

break;

}

return (INT_PTR)FALSE;

}

Am I doing something wrong ?

I'm working on Vista beta 2 (build 5384)

Chrix at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 4
I copied your "wm_contextmenu" handler and I got no error. I get a pop-up menu that says "Felipe". If you can take your compiled program and put it somewhere I'll download it and see what the difference is between yours and mine.
RaymondChen-MSFT at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 5

https://bugs.eclipse.org/bugs/show_bug.cgi?id=151148

In this bug report you will find the source and the binary for you to run.

source: https://bugs.eclipse.org/bugs/attachment.cgi?id=47860
binary: https://bugs.eclipse.org/bugs/attachment.cgi?id=47861

Regards

Chrix at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 6
I just downloaded and ran your binary on Vista build 5493 and I get a pop-up menu that says "Felipe"; no error messagebox.
RaymondChen-MSFT at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 7

Right now I'm running:
Windows Vista Beta 2 (x86) (Build 5384) - DVD (Checked Build) (English)
I can download:
Windows Vista July 2006 CTP (x86) (Build 5472.5) - DVD (Checked Build) (English)
Is that worth a try ?
I can't find Vista build 5493 anywhere, am I missing anything ?

Thanks

Chrix at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 8
Build 5493 is the internal build that I have. I don't have an extra computer to install build 5384 onto sorry.
RaymondChen-MSFT at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 9
In Vista July CTP Build 5472, it still fails.
Seems like it has been already fixed as you say in the FUTURE version which we cannot see.

I have added a workaround to check the OS version and not to add use HBMMENU_CALLBACK in Vista, which makes the software ugly. But at least it works then (without graphics).

At least, Raymond, if you can confirm that this is a bug (or we are doing something wrond) in the latest public build, it would be appreciated.

Or we just have to wait until the next public build...

patria at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...
# 10
Sorry I don't have a spare machine to install the Vista July CTP onto (I don't even know where to get it). Looking at the code I see no changes in the HBMMENU_CALLBACK parameter validation since 1999.
RaymondChen-MSFT at 2007-8-30 > top of Msdn Tech,Software Development for Windows Vista,UI Development for Windows Vista...

Software Development for Windows Vista

Site Classified