From: bubnikv on
Hi guys.

I am writing an open source application for HAM radio operators. It is
a chat program over short waves. It uses speaker/mic to connect to the
outside world. http://pocketdigi.sourceforge.net

The call SHCreateMenu fails on only one device of about 200. It is IPAQ
3635 with windows 3.0, which I do not have access to. Other programs
run on his device flawlessly. I am testing the application it on
emulator and on IPAQ 3630, everything works.

I read huge lists of discussion on SHCreateMenu. It is mostly the
resource issue. It shall not be the case because it runs on number of
devices correctly.

I tried to call the SHCreateMenu with/without the SHCMBF_HMENU, none
works. Even the call with the flag SHCMBF_EMPTYBAR fails on his device.
On the other side, the deprecated APIs CommandBar_Create and
CommandBar_InsertMenubar work. I am clueless. Any help? I use the
eMbedded studio 3.0.

See the code. On the damned device the first two blocks fail.

Thanks, Vojtech

memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.hInstRes = g_hInst;
mbi.nToolBarId = IDR_MENUBAR2; // IDM_MAIN_MENU;
if (!SHCreateMenuBar(&mbi)) {
MessageBox(hWnd, L"SHCreateMenuBar Failed - type 1", L"Error",
MB_OK);
} else {
s_hWndCommandBar = mbi.hwndMB;
s_hMenuFFT = SHGetSubMenu(s_hWndCommandBar, IDM_MAIN_MENUITEM1);
hMenuTools = SHGetSubMenu(s_hWndCommandBar, IDM_MAIN_MENUITEM2);
s_hMenuChannels = SHGetSubMenu(s_hWndCommandBar,
IDM_MAIN_MENUITEM3);
s_hMenuMacros = SHGetSubMenu(s_hWndCommandBar,
IDM_MAIN_MENUITEM4);
if (s_hMenuFFT == 0)
MessageBox(hWnd, L"Menu FFT handler not acquired - type1", L"Error",
MB_OK);
if (hMenuTools == 0)
MessageBox(hWnd, L"Menu Tools handler not acquired - type1",
L"Error", MB_OK);
if (s_hMenuChannels == 0)
MessageBox(hWnd, L"Menu Channels handler not acquired - type1",
L"Error", MB_OK);
if (s_hMenuMacros == 0)
MessageBox(hWnd, L"Menu Macros handler not acquired - type1",
L"Error", MB_OK);
}

if (s_hWndCommandBar == 0 || s_hMenuFFT == 0 || hMenuTools == 0 ||
s_hMenuChannels == 0 || s_hMenuMacros == 0) {
// try another run
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.hInstRes = g_hInst;
mbi.nToolBarId = IDR_MENUBAR2; // IDM_MAIN_MENU;
mbi.dwFlags = SHCMBF_HMENU;
if (!SHCreateMenuBar(&mbi)) {
MessageBox(hWnd, L"SHCreateMenuBar Failed - type 2", L"Error",
MB_OK);
} else {
s_hWndCommandBar = mbi.hwndMB;
HMENU hMenu = SHGetMenu(s_hWndCommandBar);
s_hMenuFFT = GetSubMenu(hMenu, 0);
hMenuTools = GetSubMenu(hMenu, 1);
s_hMenuChannels = GetSubMenu(hMenu, 2);
s_hMenuMacros = GetSubMenu(hMenu, 3);
if (s_hMenuFFT == 0)
MessageBox(hWnd, L"Menu FFT handler not acquired - type2",
L"Error", MB_OK);
if (hMenuTools == 0)
MessageBox(hWnd, L"Menu Tools handler not acquired - type2",
L"Error", MB_OK);
if (s_hMenuChannels == 0)
MessageBox(hWnd, L"Menu Channels handler not acquired - type2",
L"Error", MB_OK);
if (s_hMenuMacros == 0)
MessageBox(hWnd, L"Menu Macros handler not acquired - type2",
L"Error", MB_OK);
}
}

if (s_hWndCommandBar == 0 || s_hMenuFFT == 0 || hMenuTools == 0 ||
s_hMenuChannels == 0 || s_hMenuMacros == 0) {
HMENU hMenu = 0;
s_hWndCommandBar = CommandBar_Create(g_hInst, hWnd, 101010);
if (s_hWndCommandBar == 0) {
MessageBox(hWnd, L"CommandBar_Create Failed - type 3", L"Error",
MB_OK);
} else {
memset(&mbi, 0, sizeof(SHMENUBARINFO));
mbi.cbSize = sizeof(SHMENUBARINFO);
mbi.hwndParent = hWnd;
mbi.hInstRes = g_hInst;
mbi.dwFlags = SHCMBF_EMPTYBAR;
if (! SHCreateMenuBar(&mbi))
MessageBox(hWnd, L"SHCMBF_EMPTYBAR Failed - type 3", L"Error",
MB_OK);
CommandBar_InsertMenubar(s_hWndCommandBar, g_hInst, IDR_MENUBAR2 /*
IDM_MAIN_MENU */, 0);
hMenu = CommandBar_GetMenu(s_hWndCommandBar, 0);
s_hMenuFFT = GetSubMenu(hMenu, 0);
hMenuTools = GetSubMenu(hMenu, 1);
s_hMenuChannels = GetSubMenu(hMenu, 2);
s_hMenuMacros = GetSubMenu(hMenu, 3);
if (s_hMenuFFT == 0)
MessageBox(hWnd, L"Menu FFT handler not acquired - type3",
L"Error", MB_OK);
if (hMenuTools == 0)
MessageBox(hWnd, L"Menu Tools handler not acquired - type3",
L"Error", MB_OK);
if (s_hMenuChannels == 0)
MessageBox(hWnd, L"Menu Channels handler not acquired - type3",
L"Error", MB_OK);
if (s_hMenuMacros == 0)
MessageBox(hWnd, L"Menu Macros handler not acquired - type3",
L"Error", MB_OK);
}
}

if (s_hWndCommandBar == 0 || s_hMenuFFT == 0 || hMenuTools == 0 ||
s_hMenuChannels == 0 || s_hMenuMacros == 0) {
MessageBox(hWnd, L"Menu creation failed", L"Error", MB_OK);
} else {
MessageBox(hWnd, L"Menu creation OK", L"We have won!", MB_OK);
}

From: r_z_aret on
I can't help much, but do have a few comments.


On 29 Jun 2006 00:49:54 -0700, "bubnikv" <bubnikv(a)seznam.cz> wrote:

>Hi guys.
>
>I am writing an open source application for HAM radio operators. It is
>a chat program over short waves. It uses speaker/mic to connect to the
>outside world. http://pocketdigi.sourceforge.net
>
>The call SHCreateMenu fails on only one device of about 200. It is IPAQ
>3635 with windows 3.0, which I do not have access to. Other programs
>run on his device flawlessly. I am testing the application it on
>emulator and on IPAQ 3630, everything works.

The 3635 is one of the original Pocket PCs, based on version 3.0 of
the Windows CE operating system. SHCreateMenuBar definitely works on
my 3600, and sure should work on your 3630 (I assume you mean
SHCreateMenuBar, rather than SHCreateMenu).


>
>I read huge lists of discussion on SHCreateMenu. It is mostly the
>resource issue. It shall not be the case because it runs on number of
>devices correctly.
>
>I tried to call the SHCreateMenu with/without the SHCMBF_HMENU, none
>works. Even the call with the flag SHCMBF_EMPTYBAR fails on his device.

I sure haven't been able to use SHCreateMenuBar without a SHMENUBAR
resource in my resource script (.rc file). Possibly relevant: 20-24
Feb 04 called "SHCreateMenuBar() without a resource file" in
microsoft.public.pocketpc.developer. In particular, see 20 Feb 04
contribution from Almond Stowger for ideas. Also, a 19 Feb 04
contribution from Eddy Escardo says:
SHCreateMenuBar does not currently support programatically
generated HMENUs, as the SHCMBF_HMENU flag just means that
nToolBarId will represent the ID of a menu in a compiled
resource module, not an actual HMENU that you can pass to
the SHCreateMenuBar call (as you've probably figured out by now).

I think I've had serious problems with SHCMBF_EMPTYBAR. Comments in my
code reference a 13 Nov 04 contribution from Almon B. Strowger to
thread called "SHCreateMenuBar" in microsoft.public.pocketpc.developer


>On the other side, the deprecated APIs CommandBar_Create and
>CommandBar_InsertMenubar work. I am clueless. Any help? I use the
>eMbedded studio 3.0.

CommandBar_Create forces an application to run in "emulation mode",
with Task Bar on the screen bottom and application menu on the screen
top. It seems to work on all Pocket PCs except Pocket PC 2003. But I
no longer trust it for Pocket PCs


>
>See the code. On the damned device the first two blocks fail.
>
>Thanks, Vojtech
>
> memset(&mbi, 0, sizeof(SHMENUBARINFO));
> mbi.cbSize = sizeof(SHMENUBARINFO);
> mbi.hwndParent = hWnd;
Is this hWnd for the main window?

> mbi.hInstRes = g_hInst;
> mbi.nToolBarId = IDR_MENUBAR2; // IDM_MAIN_MENU;
Is this defined in a resource script (.rc file)?

> if (!SHCreateMenuBar(&mbi)) {
> MessageBox(hWnd, L"SHCreateMenuBar Failed - type 1", L"Error",
>MB_OK);
> } else {
> s_hWndCommandBar = mbi.hwndMB;
> s_hMenuFFT = SHGetSubMenu(s_hWndCommandBar, IDM_MAIN_MENUITEM1);

I use the following to get the HMENU for the main menu:
m_hMenu = reinterpret_cast<HMENU>(::SendMessage(
s_hWndCommandBar, SHCMBM_GETMENU, 0, 0 ));

and then use the following (edited a bit) to get other HMENUs:
#ifdef FOR_PocketPC
// 5 Jun 06 (8.0.0.13)
//
--------------------------------------------------------------------
// hmenuForWM5
// See 1 Feb 06 contribution by Alexey Gravanov to thread called
// "WM2005 Menu issue" in microsoft.public.pocketpc.developer. But
// TBIF_BYINDEX isn't defined for any SDK that works with eVC 3 or
eVC 4.
static HMENU hmenuForWM5( HWND hWnd, int nPos )
{
#ifndef TBIF_BYINDEX
// From copy of aygshell.h in WM 5 for Pocket PC SDK
// Allows menus on softkeys (which have no ID) to be accessed
through TB_GETBUTTONINFO/TB_SETBUTTONINFO
// by using an index (0 or 1) and setting TBIF_BYINDEX.
DWORD TBIF_BYINDEX = 0x80000000;
#endif
UINT uPos = static_cast<UINT>(nPos); // silence
lint
TBBUTTONINFO bi;
adgINITSTRUCT_Size( bi ); // initializes structure
bi.dwMask = TBIF_LPARAM | TBIF_BYINDEX;
::SendMessage( hWnd, TB_GETBUTTONINFO, uPos,
reinterpret_cast<LPARAM>(&bi) );
return reinterpret_cast<HMENU>(bi.lParam);
} // hmenuForWM5
#endif

HMENU ClsPFCommandBar::GetSubMenu( int nPosMenu, BOOL bCheck ) const
{

#if 0 && defined FOR_PocketPC
// 17 Apr 03 (4.0.0.1) Idea from Boling, but BZ found it
unnecessary
int nId = GetSubMenuID( nPosMenu );
HMENU hMenu = reinterpret_cast<HMENU>(::SendMessage( m_hWnd,
SHCMBM_GETSUBMENU, 0, nId ));
#else
// 12 Jun 03 (4.0.0.11)
HMENU hMenu = nPosMenu < 0 ? m_hMenu : ::GetSubMenu( m_hMenu,
nPosMenu );
#endif
#ifdef FOR_PocketPC
// 6 Jun 06 (8.0.0.13)
if (!PFMIsMenu( hMenu ))
{
hMenu = hmenuForWM5( GetHwnd(), nPosMenu );
}
#endif

#ifdef UNDER_CE
// 19 May 05 (7.7.0.31)
if (!PFMIsMenu( hMenu ))
{
for (int i = 0; i < m_clsButtons.GetCount(); i++)
{
// Buttons get special treatment; I store each HMENU in an
array, and retrieve the appropriate value here
if (m_clsButtons[i].nPos == nPosMenu)
{
hMenu = m_clsButtons[i].hMenu;
break;
}
}
}
#endif

return hMenu;

} // GetSubMenu

> hMenuTools = SHGetSubMenu(s_hWndCommandBar, IDM_MAIN_MENUITEM2);
> s_hMenuChannels = SHGetSubMenu(s_hWndCommandBar,
>IDM_MAIN_MENUITEM3);
> s_hMenuMacros = SHGetSubMenu(s_hWndCommandBar,
>IDM_MAIN_MENUITEM4);
> if (s_hMenuFFT == 0)
> MessageBox(hWnd, L"Menu FFT handler not acquired - type1", L"Error",
>MB_OK);
> if (hMenuTools == 0)
> MessageBox(hWnd, L"Menu Tools handler not acquired - type1",
>L"Error", MB_OK);
> if (s_hMenuChannels == 0)
> MessageBox(hWnd, L"Menu Channels handler not acquired - type1",
>L"Error", MB_OK);
> if (s_hMenuMacros == 0)
> MessageBox(hWnd, L"Menu Macros handler not acquired - type1",
>L"Error", MB_OK);
> }
>
> if (s_hWndCommandBar == 0 || s_hMenuFFT == 0 || hMenuTools == 0 ||
>s_hMenuChannels == 0 || s_hMenuMacros == 0) {
> // try another run
> memset(&mbi, 0, sizeof(SHMENUBARINFO));
> mbi.cbSize = sizeof(SHMENUBARINFO);
> mbi.hwndParent = hWnd;
> mbi.hInstRes = g_hInst;
> mbi.nToolBarId = IDR_MENUBAR2; // IDM_MAIN_MENU;
> mbi.dwF